123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602 |
- /******************************************************************************
- Filename: ZDSecMgr.c
- Revised: $Date: 2012-02-16 13:22:48 -0800 (Thu, 16 Feb 2012) $
- Revision: $Revision: 29339 $
- Description: The ZigBee Device Security Manager.
- Copyright 2005-2012 Texas Instruments Incorporated. All rights reserved.
- IMPORTANT: Your use of this Software is limited to those specific rights
- granted under the terms of a software license agreement between the user
- who downloaded the software, his/her employer (which must be your employer)
- and Texas Instruments Incorporated (the "License"). You may not use this
- Software unless you agree to abide by the terms of the License. The License
- limits your use, and you acknowledge, that the Software may not be modified,
- copied or distributed unless embedded on a Texas Instruments microcontroller
- or used solely and exclusively in conjunction with a Texas Instruments radio
- frequency transceiver, which is integrated into your product. Other than for
- the foregoing purpose, you may not use, reproduce, copy, prepare derivative
- works of, modify, distribute, perform, display or sell this Software and/or
- its documentation for any purpose.
- YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
- PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
- INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
- NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
- TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
- NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
- LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
- INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
- OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
- OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
- (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
- Should you have any questions regarding your right to use this Software,
- contact Texas Instruments Incorporated at www.TI.com.
- ******************************************************************************/
- #ifdef __cplusplus
- extern "C"
- {
- #endif
- /******************************************************************************
- * INCLUDES
- */
- #include "ZComdef.h"
- #include "OSAL.h"
- #include "OSAL_NV.h"
- #include "ZGlobals.h"
- #include "ssp.h"
- #include "nwk_globals.h"
- #include "nwk.h"
- #include "NLMEDE.h"
- #include "AddrMgr.h"
- #include "AssocList.h"
- #include "APSMEDE.h"
- #include "ZDConfig.h"
- #include "ZDSecMgr.h"
- /******************************************************************************
- * CONSTANTS
- */
- // maximum number of devices managed by this Security Manager
- #if !defined ( ZDSECMGR_DEVICE_MAX )
- #define ZDSECMGR_DEVICE_MAX 3
- #endif
- // total number of preconfigured devices (EXT address, MASTER key)
- //devtag.pro.security
- //#define ZDSECMGR_PRECONFIG_MAX ZDSECMGR_DEVICE_MAX
- #define ZDSECMGR_PRECONFIG_MAX 0
- // maximum number of MASTER keys this device may hold
- #define ZDSECMGR_MASTERKEY_MAX ZDSECMGR_DEVICE_MAX
- // maximum number of LINK keys this device may store
- #define ZDSECMGR_ENTRY_MAX ZDSECMGR_DEVICE_MAX
- // total number of devices under control - authentication, SKKE, etc.
- #define ZDSECMGR_CTRL_MAX ZDSECMGR_DEVICE_MAX
- // total number of stored devices
- #if !defined ( ZDSECMGR_STORED_DEVICES )
- #define ZDSECMGR_STORED_DEVICES 3
- #endif
- // Total number of preconfigured trust center link key
- #if !defined ( ZDSECMGR_TC_DEVICE_MAX )
- #define ZDSECMGR_TC_DEVICE_MAX 1
- #endif
- #if ( ZDSECMGR_TC_DEVICE_MAX < 1 ) || ( ZDSECMGR_TC_DEVICE_MAX > 255 )
- #error "ZDSECMGR_TC_DEVICE_MAX shall be between 1 and 255 !"
- #endif
- #define ZDSECMGR_CTRL_NONE 0
- #define ZDSECMGR_CTRL_INIT 1
- #define ZDSECMGR_CTRL_TK_MASTER 2
- #define ZDSECMGR_CTRL_SKKE_INIT 3
- #define ZDSECMGR_CTRL_SKKE_WAIT 4
- #define ZDSECMGR_CTRL_SKKE_DONE 5
- #define ZDSECMGR_CTRL_SKKE_FAIL 6
- #define ZDSECMGR_CTRL_TK_NWK 7
- #define ZDSECMGR_CTRL_BASE_CNTR 1
- #define ZDSECMGR_CTRL_SKKE_INIT_CNTR 1
- #define ZDSECMGR_CTRL_TK_NWK_CNTR 1
- // set SKA slot maximum
- #define ZDSECMGR_SKA_SLOT_MAX 1
- // APSME Stub Implementations
- #define ZDSecMgrMasterKeyGet APSME_MasterKeyGet
- #define ZDSecMgrLinkKeySet APSME_LinkKeySet
- #define ZDSecMgrLinkKeyNVIdGet APSME_LinkKeyNVIdGet
- #define ZDSecMgrKeyFwdToChild APSME_KeyFwdToChild
- #define ZDSecMgrIsLinkKeyValid APSME_IsLinkKeyValid
- /******************************************************************************
- * TYPEDEFS
- */
- typedef struct
- {
- uint8 extAddr[Z_EXTADDR_LEN];
- uint8 key[SEC_KEY_LEN];
- } ZDSecMgrPreConfigData_t;
- typedef struct
- {
- uint16 ami;
- uint8 key[SEC_KEY_LEN];
- } ZDSecMgrMasterKeyData_t;
- typedef struct
- {
- uint16 ami;
- uint16 keyNvId; // index to the Link Key table in NV
- ZDSecMgr_Authentication_Option authenticateOption;
- } ZDSecMgrEntry_t;
- typedef struct
- {
- ZDSecMgrEntry_t* entry;
- uint16 parentAddr;
- uint8 secure;
- uint8 state;
- uint8 cntr;
- } ZDSecMgrCtrl_t;
- typedef struct
- {
- uint16 nwkAddr;
- uint8* extAddr;
- uint16 parentAddr;
- uint8 secure;
- uint8 devStatus;
- ZDSecMgrCtrl_t* ctrl;
- } ZDSecMgrDevice_t;
- /******************************************************************************
- * LOCAL VARIABLES
- */
- #if 0 // Taken out because the following functionality is only used for test
- // purpose. A more efficient (above) way is used. It can be put
- // back in if customers request for a white/black list feature.
- uint8 ZDSecMgrStoredDeviceList[ZDSECMGR_STORED_DEVICES][Z_EXTADDR_LEN] =
- {
- { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- };
- #endif
- uint8 ZDSecMgrTCExtAddr[Z_EXTADDR_LEN]=
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- // Key data is put in CONST area for security reasons
- CONST uint8 ZDSecMgrTCMasterKey[SEC_KEY_LEN] =
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x89,0x67,0x45,0x23,0x01,0xEF,0xCD,0xAB};
- uint8 ZDSecMgrTCAuthenticated = FALSE;
- //devtag.pro.security - remove this
- #if ( ZDSECMGR_PRECONFIG_MAX != 0 )
- const ZDSecMgrPreConfigData_t ZDSecMgrPreConfigData[ZDSECMGR_PRECONFIG_MAX] =
- {
- //---------------------------------------------------------------------------
- // DEVICE A
- //---------------------------------------------------------------------------
- {
- // extAddr
- {0x7C,0x01,0x12,0x13,0x14,0x15,0x16,0x17},
- // key
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
- },
- //---------------------------------------------------------------------------
- // DEVICE B
- //---------------------------------------------------------------------------
- {
- // extAddr
- {0x84,0x03,0x00,0x00,0x00,0x4B,0x12,0x00},
- // key
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
- },
- //---------------------------------------------------------------------------
- // DEVICE C
- //---------------------------------------------------------------------------
- {
- // extAddr
- {0x3E,0x01,0x12,0x13,0x14,0x15,0x16,0x17},
- // key
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
- },
- };
- #endif // ( ZDSECMGR_PRECONFIG_MAX != 0 )
- ZDSecMgrEntry_t* ZDSecMgrEntries = NULL;
- ZDSecMgrCtrl_t* ZDSecMgrCtrlData = NULL;
- void ZDSecMgrAddrMgrUpdate( uint16 ami, uint16 nwkAddr );
- void ZDSecMgrAddrMgrCB( uint8 update, AddrMgrEntry_t* newEntry, AddrMgrEntry_t* oldEntry );
- uint8 ZDSecMgrPermitJoiningEnabled;
- uint8 ZDSecMgrPermitJoiningTimed;
- APSME_TCLinkKey_t TrustCenterLinkKey;
- APSME_ApsLinkKeyFrmCntr_t ApsLinkKeyFrmCntr[ZDSECMGR_ENTRY_MAX];
- APSME_TCLinkKeyFrmCntr_t TCLinkKeyFrmCntr[ZDSECMGR_TC_DEVICE_MAX];
- /******************************************************************************
- * PRIVATE FUNCTIONS
- *
- * ZDSecMgrMasterKeyInit
- * ZDSecMgrAddrStore
- * ZDSecMgrExtAddrStore
- * ZDSecMgrExtAddrLookup
- * ZDSecMgrMasterKeyLookup
- * ZDSecMgrMasterKeyStore
- * ZDSecMgrEntryInit
- * ZDSecMgrEntryLookup
- * ZDSecMgrEntryLookupAMI
- * ZDSecMgrEntryLookupExt
- * ZDSecMgrEntryLookupExtGetIndex
- * ZDSecMgrEntryFree
- * ZDSecMgrEntryNew
- * ZDSecMgrCtrlInit
- * ZDSecMgrCtrlRelease
- * ZDSecMgrCtrlLookup
- * ZDSecMgrCtrlSet
- * ZDSecMgrCtrlAdd
- * ZDSecMgrCtrlTerm
- * ZDSecMgrCtrlReset
- * ZDSecMgrMasterKeyLoad
- * ZDSecMgrAppKeyGet
- * ZDSecMgrAppKeyReq
- * ZDSecMgrEstablishKey
- * ZDSecMgrSendMasterKey
- * ZDSecMgrSendNwkKey
- * ZDSecMgrDeviceEntryRemove
- * ZDSecMgrDeviceEntryAdd
- * ZDSecMgrDeviceCtrlHandler
- * ZDSecMgrDeviceCtrlSetup
- * ZDSecMgrDeviceCtrlUpdate
- * ZDSecMgrDeviceRemove
- * ZDSecMgrDeviceValidateSKKE
- * ZDSecMgrDeviceValidateRM
- * ZDSecMgrDeviceValidateCM
- * ZDSecMgrDeviceValidate
- * ZDSecMgrDeviceJoin
- * ZDSecMgrDeviceJoinDirect
- * ZDSecMgrDeviceJoinFwd
- * ZDSecMgrDeviceNew
- * ZDSecMgrAssocDeviceAuth
- * ZDSecMgrAuthInitiate
- * ZDSecMgrAuthNwkKey
- * APSME_TCLinkKeyInit
- * APSME_IsDefaultTCLK
- */
- //-----------------------------------------------------------------------------
- // master key data
- //-----------------------------------------------------------------------------
- void ZDSecMgrMasterKeyInit( void );
- //-----------------------------------------------------------------------------
- // address management
- //-----------------------------------------------------------------------------
- ZStatus_t ZDSecMgrAddrStore( uint16 nwkAddr, uint8* extAddr, uint16* ami );
- ZStatus_t ZDSecMgrExtAddrStore( uint16 nwkAddr, uint8* extAddr, uint16* ami );
- ZStatus_t ZDSecMgrExtAddrLookup( uint8* extAddr, uint16* ami );
- //-----------------------------------------------------------------------------
- // Trust Center management
- //-----------------------------------------------------------------------------
- uint8 ZDSecMgrTCExtAddrCheck( uint8* extAddr );
- void ZDSecMgrTCDataLoad( uint8* extAddr );
- //-----------------------------------------------------------------------------
- // MASTER key data
- //-----------------------------------------------------------------------------
- ZStatus_t ZDSecMgrMasterKeyLookup( uint16 ami, uint16* pKeyNvId );
- ZStatus_t ZDSecMgrMasterKeyStore( uint16 ami, uint8* key );
- //-----------------------------------------------------------------------------
- // entry data
- //-----------------------------------------------------------------------------
- void ZDSecMgrEntryInit(uint8 state);
- ZStatus_t ZDSecMgrEntryLookup( uint16 nwkAddr, ZDSecMgrEntry_t** entry );
- ZStatus_t ZDSecMgrEntryLookupAMI( uint16 ami, ZDSecMgrEntry_t** entry );
- ZStatus_t ZDSecMgrEntryLookupExt( uint8* extAddr, ZDSecMgrEntry_t** entry );
- ZStatus_t ZDSecMgrEntryLookupExtGetIndex( uint8* extAddr, ZDSecMgrEntry_t** entry, uint16* entryIndex );
- ZStatus_t ZDSecMgrEntryLookupAMIGetIndex( uint16 ami, uint16* entryIndex );
- void ZDSecMgrEntryFree( ZDSecMgrEntry_t* entry );
- ZStatus_t ZDSecMgrEntryNew( ZDSecMgrEntry_t** entry );
- ZStatus_t ZDSecMgrAuthenticationSet( uint8* extAddr, ZDSecMgr_Authentication_Option option );
- void ZDSecMgrApsLinkKeyInit(void);
- #if defined ( NV_RESTORE )
- static void ZDSecMgrWriteNV(void);
- static void ZDSecMgrRestoreFromNV(void);
- static void ZDSecMgrUpdateNV( uint16 index );
- #endif
- //-----------------------------------------------------------------------------
- // control data
- //-----------------------------------------------------------------------------
- void ZDSecMgrCtrlInit( void );
- void ZDSecMgrCtrlRelease( ZDSecMgrCtrl_t* ctrl );
- void ZDSecMgrCtrlLookup( ZDSecMgrEntry_t* entry, ZDSecMgrCtrl_t** ctrl );
- void ZDSecMgrCtrlSet( ZDSecMgrDevice_t* device,
- ZDSecMgrEntry_t* entry,
- ZDSecMgrCtrl_t* ctrl );
- ZStatus_t ZDSecMgrCtrlAdd( ZDSecMgrDevice_t* device, ZDSecMgrEntry_t* entry );
- void ZDSecMgrCtrlTerm( ZDSecMgrEntry_t* entry );
- ZStatus_t ZDSecMgrCtrlReset( ZDSecMgrDevice_t* device,
- ZDSecMgrEntry_t* entry );
- //-----------------------------------------------------------------------------
- // key support
- //-----------------------------------------------------------------------------
- ZStatus_t ZDSecMgrMasterKeyLoad( uint8* extAddr, uint8* key );
- ZStatus_t ZDSecMgrAppKeyGet( uint16 initNwkAddr,
- uint8* initExtAddr,
- uint16 partNwkAddr,
- uint8* partExtAddr,
- uint8** key,
- uint8* keyType );
- void ZDSecMgrAppKeyReq( ZDO_RequestKeyInd_t* ind );
- ZStatus_t ZDSecMgrEstablishKey( ZDSecMgrDevice_t* device );
- ZStatus_t ZDSecMgrSendMasterKey( ZDSecMgrDevice_t* device );
- ZStatus_t ZDSecMgrSendNwkKey( ZDSecMgrDevice_t* device );
- void ZDSecMgrNwkKeyInit(uint8 setDefault);
- //-----------------------------------------------------------------------------
- // device entry
- //-----------------------------------------------------------------------------
- void ZDSecMgrDeviceEntryRemove( ZDSecMgrEntry_t* entry );
- ZStatus_t ZDSecMgrDeviceEntryAdd( ZDSecMgrDevice_t* device, uint16 ami );
- //-----------------------------------------------------------------------------
- // device control
- //-----------------------------------------------------------------------------
- void ZDSecMgrDeviceCtrlHandler( ZDSecMgrDevice_t* device );
- void ZDSecMgrDeviceCtrlSetup( ZDSecMgrDevice_t* device );
- void ZDSecMgrDeviceCtrlUpdate( uint8* extAddr, uint8 state );
- //-----------------------------------------------------------------------------
- // device management
- //-----------------------------------------------------------------------------
- void ZDSecMgrDeviceRemove( ZDSecMgrDevice_t* device );
- ZStatus_t ZDSecMgrDeviceValidateSKKE( ZDSecMgrDevice_t* device );
- ZStatus_t ZDSecMgrDeviceValidateRM( ZDSecMgrDevice_t* device );
- ZStatus_t ZDSecMgrDeviceValidateCM( ZDSecMgrDevice_t* device );
- ZStatus_t ZDSecMgrDeviceValidate( ZDSecMgrDevice_t* device );
- ZStatus_t ZDSecMgrDeviceJoin( ZDSecMgrDevice_t* device );
- ZStatus_t ZDSecMgrDeviceJoinDirect( ZDSecMgrDevice_t* device );
- ZStatus_t ZDSecMgrDeviceJoinFwd( ZDSecMgrDevice_t* device );
- ZStatus_t ZDSecMgrDeviceNew( ZDSecMgrDevice_t* device );
- //-----------------------------------------------------------------------------
- // association management
- //-----------------------------------------------------------------------------
- void ZDSecMgrAssocDeviceAuth( associated_devices_t* assoc );
- //-----------------------------------------------------------------------------
- // authentication management
- //-----------------------------------------------------------------------------
- void ZDSecMgrAuthInitiate( uint8* responder );
- void ZDSecMgrAuthNwkKey( void );
- //-----------------------------------------------------------------------------
- // APSME function
- //-----------------------------------------------------------------------------
- void APSME_TCLinkKeyInit( uint8 setDefault );
- uint8 APSME_IsDefaultTCLK( uint8 *extAddr );
- /******************************************************************************
- * @fn ZDSecMgrMasterKeyInit ]
- *
- * @brief Initialize master key data in NV
- *
- * @param none
- *
- * @return none
- */
- void ZDSecMgrMasterKeyInit( void )
- {
- uint16 index;
- ZDSecMgrMasterKeyData_t masterKeyData;
- masterKeyData.ami = INVALID_NODE_ADDR;
- osal_memset( &masterKeyData.key, 0x00, SEC_KEY_LEN );
- for ( index = 0; index < ZDSECMGR_MASTERKEY_MAX; index++ )
- {
- if ( osal_nv_item_init( (ZCD_NV_MASTER_KEY_DATA_START + index),
- sizeof(ZDSecMgrMasterKeyData_t), &masterKeyData) == SUCCESS)
- {
- // the item already exists in NV just needs to be set to default values
- osal_nv_write( (ZCD_NV_MASTER_KEY_DATA_START + index), 0,
- sizeof(ZDSecMgrMasterKeyData_t), &masterKeyData );
- }
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrAddrStore
- *
- * @brief Store device addresses.
- *
- * @param nwkAddr - [in] NWK address
- * @param extAddr - [in] EXT address
- * @param ami - [out] Address Manager index
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrAddrStore( uint16 nwkAddr, uint8* extAddr, uint16* ami )
- {
- ZStatus_t status;
- AddrMgrEntry_t entry;
- // add entry
- entry.user = ADDRMGR_USER_SECURITY;
- entry.nwkAddr = nwkAddr;
- AddrMgrExtAddrSet( entry.extAddr, extAddr );
- if ( AddrMgrEntryUpdate( &entry ) == TRUE )
- {
- // return successful results
- *ami = entry.index;
- status = ZSuccess;
- }
- else
- {
- // return failed results
- *ami = entry.index;
- status = ZNwkUnknownDevice;
- }
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrExtAddrStore
- *
- * @brief Store EXT address.
- *
- * @param extAddr - [in] EXT address
- * @param ami - [out] Address Manager index
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrExtAddrStore( uint16 nwkAddr, uint8* extAddr, uint16* ami )
- {
- ZStatus_t status;
- AddrMgrEntry_t entry;
- // add entry
- entry.user = ADDRMGR_USER_SECURITY;
- entry.nwkAddr = nwkAddr;
- AddrMgrExtAddrSet( entry.extAddr, extAddr );
- if ( AddrMgrEntryUpdate( &entry ) == TRUE )
- {
- // return successful results
- *ami = entry.index;
- status = ZSuccess;
- }
- else
- {
- // return failed results
- *ami = entry.index;
- status = ZNwkUnknownDevice;
- }
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrExtAddrLookup
- *
- * @brief Lookup index for specified EXT address.
- *
- * @param extAddr - [in] EXT address
- * @param ami - [out] Address Manager index
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrExtAddrLookup( uint8* extAddr, uint16* ami )
- {
- ZStatus_t status;
- AddrMgrEntry_t entry;
- // lookup entry
- entry.user = ADDRMGR_USER_SECURITY;
- AddrMgrExtAddrSet( entry.extAddr, extAddr );
- if ( AddrMgrEntryLookupExt( &entry ) == TRUE )
- {
- // return successful results
- *ami = entry.index;
- status = ZSuccess;
- }
- else
- {
- // return failed results
- *ami = entry.index;
- status = ZNwkUnknownDevice;
- }
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrAddrClear
- *
- * @brief Clear security bit from Address Manager for specific device.
- *
- * @param extAddr - [in] EXT address
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrAddrClear( uint8* extAddr )
- {
- ZStatus_t status;
- uint16 entryAmi;
- // get Address Manager Index
- status = ZDSecMgrExtAddrLookup( extAddr, &entryAmi );
- if ( status == ZSuccess )
- {
- AddrMgrEntry_t addrEntry;
- // Clear SECURITY User bit from the address manager
- addrEntry.user = ADDRMGR_USER_SECURITY;
- addrEntry.index = entryAmi;
- if ( AddrMgrEntryRelease( &addrEntry ) != TRUE )
- {
- // return failure results
- status = ZFailure;
- }
- }
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrMasterKeyLookup
- *
- * @brief Lookup MASTER key for specified address index.
- *
- * @param ami - [in] Address Manager index
- * @param pKeyNvId - [out] MASTER key NV ID
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrMasterKeyLookup( uint16 ami, uint16* pKeyNvId )
- {
- uint16 index;
- ZDSecMgrMasterKeyData_t masterKeyData;
- for ( index = 0; index < ZDSECMGR_MASTERKEY_MAX ; index++ )
- {
- // Read entry index of the Master key table from NV
- osal_nv_read( (ZCD_NV_MASTER_KEY_DATA_START + index), 0,
- sizeof(ZDSecMgrMasterKeyData_t), &masterKeyData );
- if ( masterKeyData.ami == ami )
- {
- // return successful results
- *pKeyNvId = ZCD_NV_MASTER_KEY_DATA_START + index;
- // clear copy of key in RAM
- osal_memset(&masterKeyData, 0x00, sizeof(ZDSecMgrMasterKeyData_t));
- return ZSuccess;
- }
- }
- *pKeyNvId = SEC_NO_KEY_NV_ID;
- // clear copy of key in RAM
- osal_memset(&masterKeyData, 0x00, sizeof(ZDSecMgrMasterKeyData_t));
- return ZNwkUnknownDevice;
- }
- /******************************************************************************
- * @fn ZDSecMgrMasterKeyStore
- *
- * @brief Store MASTER key for specified address index.
- *
- * @param ami - [in] Address Manager index
- * @param key - [in] valid key to store
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrMasterKeyStore( uint16 ami, uint8* key )
- {
- uint16 index;
- ZDSecMgrMasterKeyData_t masterKeyData;
- for ( index = 0; index < ZDSECMGR_MASTERKEY_MAX ; index++ )
- {
- // Read entry index of the Master key table from NV
- osal_nv_read( (ZCD_NV_MASTER_KEY_DATA_START + index), 0,
- sizeof(ZDSecMgrMasterKeyData_t), &masterKeyData );
- if ( masterKeyData.ami == INVALID_NODE_ADDR )
- {
- // store EXT address index
- masterKeyData.ami = ami;
- if ( key != NULL )
- {
- osal_memcpy( masterKeyData.key, key, SEC_KEY_LEN );
- }
- else
- {
- osal_memset( masterKeyData.key, 0, SEC_KEY_LEN );
- }
- // set new values in NV
- osal_nv_write( (ZCD_NV_MASTER_KEY_DATA_START + index), 0,
- sizeof(ZDSecMgrMasterKeyData_t), &masterKeyData );
- // clear copy of key in RAM
- osal_memset( &masterKeyData, 0x00, sizeof(ZDSecMgrMasterKeyData_t) );
- // return successful results
- return ZSuccess;
- }
- }
- // clear copy of key in RAM
- osal_memset( &masterKeyData, 0x00, sizeof(ZDSecMgrMasterKeyData_t) );
- return ZNwkUnknownDevice;
- }
- /******************************************************************************
- * @fn ZDSecMgrEntryInit
- *
- * @brief Initialize entry sub module
- *
- * @param state - device initialization state
- *
- * @return none
- */
- void ZDSecMgrEntryInit(uint8 state)
- {
- if (ZDSecMgrEntries == NULL)
- {
- uint16 index;
- if ((ZDSecMgrEntries = osal_mem_alloc(sizeof(ZDSecMgrEntry_t) * ZDSECMGR_ENTRY_MAX)) == NULL)
- {
- return;
- }
- for (index = 0; index < ZDSECMGR_ENTRY_MAX; index++)
- {
- ZDSecMgrEntries[index].ami = INVALID_NODE_ADDR;
- ZDSecMgrEntries[index].keyNvId = SEC_NO_KEY_NV_ID;
- }
- }
- #if defined NV_RESTORE
- if (state == ZDO_INITDEV_RESTORED_NETWORK_STATE)
- {
- ZDSecMgrRestoreFromNV();
- }
- #else
- (void)state;
- #endif
- }
- /******************************************************************************
- * @fn ZDSecMgrEntryLookup
- *
- * @brief Lookup entry index using specified NWK address.
- *
- * @param nwkAddr - [in] NWK address
- * @param entry - [out] valid entry
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrEntryLookup( uint16 nwkAddr, ZDSecMgrEntry_t** entry )
- {
- uint16 index;
- AddrMgrEntry_t addrMgrEntry;
- // initialize results
- *entry = NULL;
- // verify data is available
- if ( ZDSecMgrEntries != NULL )
- {
- addrMgrEntry.user = ADDRMGR_USER_SECURITY;
- addrMgrEntry.nwkAddr = nwkAddr;
- if ( AddrMgrEntryLookupNwk( &addrMgrEntry ) == TRUE )
- {
- for ( index = 0; index < ZDSECMGR_ENTRY_MAX ; index++ )
- {
- if ( addrMgrEntry.index == ZDSecMgrEntries[index].ami )
- {
- // return successful results
- *entry = &ZDSecMgrEntries[index];
- // break from loop
- return ZSuccess;
- }
- }
- }
- }
- return ZNwkUnknownDevice;
- }
- /******************************************************************************
- * @fn ZDSecMgrEntryLookupAMI
- *
- * @brief Lookup entry using specified address index
- *
- * @param ami - [in] Address Manager index
- * @param entry - [out] valid entry
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrEntryLookupAMI( uint16 ami, ZDSecMgrEntry_t** entry )
- {
- uint16 index;
- // initialize results
- *entry = NULL;
- // verify data is available
- if ( ZDSecMgrEntries != NULL )
- {
- for ( index = 0; index < ZDSECMGR_ENTRY_MAX ; index++ )
- {
- if ( ZDSecMgrEntries[index].ami == ami )
- {
- // return successful results
- *entry = &ZDSecMgrEntries[index];
- // break from loop
- return ZSuccess;
- }
- }
- }
- return ZNwkUnknownDevice;
- }
- /******************************************************************************
- * @fn ZDSecMgrEntryLookupExt
- *
- * @brief Lookup entry index using specified EXT address.
- *
- * @param extAddr - [in] EXT address
- * @param entry - [out] valid entry
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrEntryLookupExt( uint8* extAddr, ZDSecMgrEntry_t** entry )
- {
- ZStatus_t status;
- uint16 ami;
- // initialize results
- *entry = NULL;
- status = ZNwkUnknownDevice;
- // lookup address index
- if ( ZDSecMgrExtAddrLookup( extAddr, &ami ) == ZSuccess )
- {
- status = ZDSecMgrEntryLookupAMI( ami, entry );
- }
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrEntryLookupExtGetIndex
- *
- * @brief Lookup entry index using specified EXT address.
- *
- * @param extAddr - [in] EXT address
- * @param entryIndex - [out] valid index to the entry table
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrEntryLookupExtGetIndex( uint8* extAddr, ZDSecMgrEntry_t** entry, uint16* entryIndex )
- {
- uint16 ami;
- uint16 index;
- // lookup address index
- if ( ZDSecMgrExtAddrLookup( extAddr, &ami ) == ZSuccess )
- {
- // verify data is available
- if ( ZDSecMgrEntries != NULL )
- {
- for ( index = 0; index < ZDSECMGR_ENTRY_MAX ; index++ )
- {
- if ( ZDSecMgrEntries[index].ami == ami )
- {
- // return successful results
- *entry = &ZDSecMgrEntries[index];
- *entryIndex = index;
- // break from loop
- return ZSuccess;
- }
- }
- }
- }
- return ZNwkUnknownDevice;
- }
- /******************************************************************************
- * @fn ZDSecMgrEntryLookupAMIGetIndex
- *
- * @brief Lookup entry using specified address index
- *
- * @param ami - [in] Address Manager index
- * @param entryIndex - [out] valid index to the entry table
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrEntryLookupAMIGetIndex( uint16 ami, uint16* entryIndex )
- {
- uint16 index;
- // verify data is available
- if ( ZDSecMgrEntries != NULL )
- {
- for ( index = 0; index < ZDSECMGR_ENTRY_MAX ; index++ )
- {
- if ( ZDSecMgrEntries[index].ami == ami )
- {
- // return successful results
- *entryIndex = index;
- // break from loop
- return ZSuccess;
- }
- }
- }
- return ZNwkUnknownDevice;
- }
- /******************************************************************************
- * @fn ZDSecMgrEntryFree
- *
- * @brief Free entry.
- *
- * @param entry - [in] valid entry
- *
- * @return ZStatus_t
- */
- void ZDSecMgrEntryFree( ZDSecMgrEntry_t* entry )
- {
- APSME_LinkKeyData_t *pApsLinkKey = NULL;
- #if defined ( NV_RESTORE )
- ZStatus_t status;
- uint16 entryIndex;
- status = ZDSecMgrEntryLookupAMIGetIndex( entry->ami, &entryIndex );
- #endif
- pApsLinkKey = (APSME_LinkKeyData_t *)osal_mem_alloc(sizeof(APSME_LinkKeyData_t));
- if (pApsLinkKey != NULL)
- {
- osal_memset( pApsLinkKey, 0x00, sizeof(APSME_LinkKeyData_t) );
- // Clear the APS Link key in NV
- osal_nv_write( entry->keyNvId, 0,
- sizeof(APSME_LinkKeyData_t), pApsLinkKey);
- // set entry to invalid Key
- entry->keyNvId = SEC_NO_KEY_NV_ID;
- osal_mem_free(pApsLinkKey);
- }
- // marking the entry as INVALID_NODE_ADDR
- entry->ami = INVALID_NODE_ADDR;
- // set to default value
- entry->authenticateOption = ZDSecMgr_Not_Authenticated;
- #if defined ( NV_RESTORE )
- if ( status == ZSuccess )
- {
- ZDSecMgrUpdateNV(entryIndex);
- }
- #endif
- }
- /******************************************************************************
- * @fn ZDSecMgrEntryNew
- *
- * @brief Get a new entry.
- *
- * @param entry - [out] valid entry
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrEntryNew( ZDSecMgrEntry_t** entry )
- {
- uint16 index;
- // initialize results
- *entry = NULL;
- // verify data is available
- if ( ZDSecMgrEntries != NULL )
- {
- // find available entry
- for ( index = 0; index < ZDSECMGR_ENTRY_MAX ; index++ )
- {
- if ( ZDSecMgrEntries[index].ami == INVALID_NODE_ADDR )
- {
- // return successful result
- *entry = &ZDSecMgrEntries[index];
- // Set the authentication option to default
- ZDSecMgrEntries[index].authenticateOption = ZDSecMgr_Not_Authenticated;
- // break from loop
- return ZSuccess;
- }
- }
- }
- return ZNwkUnknownDevice;
- }
- /******************************************************************************
- * @fn ZDSecMgrCtrlInit
- *
- * @brief Initialize control sub module
- *
- * @param none
- *
- * @return none
- */
- void ZDSecMgrCtrlInit( void )
- {
- uint16 size;
- uint16 index;
- // allocate entry data
- size = (short)( sizeof(ZDSecMgrCtrl_t) * ZDSECMGR_CTRL_MAX );
- ZDSecMgrCtrlData = osal_mem_alloc( size );
- // initialize data
- if ( ZDSecMgrCtrlData != NULL )
- {
- for( index = 0; index < ZDSECMGR_CTRL_MAX; index++ )
- {
- ZDSecMgrCtrlData[index].state = ZDSECMGR_CTRL_NONE;
- }
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrCtrlRelease
- *
- * @brief Release control data.
- *
- * @param ctrl - [in] valid control data
- *
- * @return none
- */
- void ZDSecMgrCtrlRelease( ZDSecMgrCtrl_t* ctrl )
- {
- // should always be enough entry control data
- ctrl->state = ZDSECMGR_CTRL_NONE;
- }
- /******************************************************************************
- * @fn ZDSecMgrCtrlLookup
- *
- * @brief Lookup control data.
- *
- * @param entry - [in] valid entry data
- * @param ctrl - [out] control data - NULL if not found
- *
- * @return none
- */
- void ZDSecMgrCtrlLookup( ZDSecMgrEntry_t* entry, ZDSecMgrCtrl_t** ctrl )
- {
- uint16 index;
- // initialize search results
- *ctrl = NULL;
- // verify data is available
- if ( ZDSecMgrCtrlData != NULL )
- {
- for ( index = 0; index < ZDSECMGR_CTRL_MAX; index++ )
- {
- // make sure control data is in use
- if ( ZDSecMgrCtrlData[index].state != ZDSECMGR_CTRL_NONE )
- {
- // check for entry match
- if ( ZDSecMgrCtrlData[index].entry == entry )
- {
- // return this control data
- *ctrl = &ZDSecMgrCtrlData[index];
- // break from loop
- return;
- }
- }
- }
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrCtrlSet
- *
- * @brief Set control data.
- *
- * @param device - [in] valid device data
- * @param entry - [in] valid entry data
- * @param ctrl - [in] valid control data
- *
- * @return none
- */
- void ZDSecMgrCtrlSet( ZDSecMgrDevice_t* device,
- ZDSecMgrEntry_t* entry,
- ZDSecMgrCtrl_t* ctrl )
- {
- // set control date
- ctrl->parentAddr = device->parentAddr;
- ctrl->secure = device->secure;
- ctrl->entry = entry;
- ctrl->state = ZDSECMGR_CTRL_INIT;
- ctrl->cntr = 0;
- // set device pointer
- device->ctrl = ctrl;
- }
- /******************************************************************************
- * @fn ZDSecMgrCtrlAdd
- *
- * @brief Add control data.
- *
- * @param device - [in] valid device data
- * @param entry - [in] valid entry data
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrCtrlAdd( ZDSecMgrDevice_t* device, ZDSecMgrEntry_t* entry )
- {
- uint16 index;
- // verify data is available
- if ( ZDSecMgrCtrlData != NULL )
- {
- // look for an empty slot
- for ( index = 0; index < ZDSECMGR_CTRL_MAX; index++ )
- {
- if ( ZDSecMgrCtrlData[index].state == ZDSECMGR_CTRL_NONE )
- {
- // return successful results
- ZDSecMgrCtrlSet( device, entry, &ZDSecMgrCtrlData[index] );
- // break from loop
- return ZSuccess;
- }
- }
- }
- return ZNwkUnknownDevice;
- }
- /******************************************************************************
- * @fn ZDSecMgrCtrlTerm
- *
- * @brief Terminate device control.
- *
- * @param entry - [in] valid entry data
- *
- * @return none
- */
- void ZDSecMgrCtrlTerm( ZDSecMgrEntry_t* entry )
- {
- ZDSecMgrCtrl_t* ctrl;
- // remove device from control data
- ZDSecMgrCtrlLookup ( entry, &ctrl );
- if ( ctrl != NULL )
- {
- ZDSecMgrCtrlRelease ( ctrl );
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrCtrlReset
- *
- * @brief Reset control data.
- *
- * @param device - [in] valid device data
- * @param entry - [in] valid entry data
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrCtrlReset( ZDSecMgrDevice_t* device, ZDSecMgrEntry_t* entry )
- {
- ZStatus_t status;
- ZDSecMgrCtrl_t* ctrl;
- // initialize results
- status = ZNwkUnknownDevice;
- // look for a match for the entry
- ZDSecMgrCtrlLookup( entry, &ctrl );
- if ( ctrl != NULL )
- {
- ZDSecMgrCtrlSet( device, entry, ctrl );
- status = ZSuccess;
- }
- else
- {
- status = ZDSecMgrCtrlAdd( device, entry );
- }
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrMasterKeyLoad
- *
- * @brief Load the MASTER key for device with specified EXT
- * address.
- *
- * @param extAddr - [in] EXT address of device
- * @param key - [in] MASTER key shared with device
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrMasterKeyLoad( uint8* extAddr, uint8* key )
- {
- ZStatus_t status;
- uint16 ami;
- uint16 keyNvId;
- // set status based on policy
- status = ZDSecMgrExtAddrLookup( extAddr, &ami );
- if ( status == ZSuccess )
- {
- // get the address NV ID
- if ( ZDSecMgrMasterKeyLookup( ami, &keyNvId ) == ZSuccess )
- {
- // overwrite old key in NV
- osal_nv_write( keyNvId, osal_offsetof(ZDSecMgrMasterKeyData_t, key),
- SEC_KEY_LEN, key );
- }
- else
- {
- // store new key -- NULL will zero key
- status = ZDSecMgrMasterKeyStore( ami, key );
- }
- }
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrAppKeyGet
- *
- * @brief get an APP key - option APP(MASTER or LINK) key
- *
- * @param initNwkAddr - [in] NWK address of initiator device
- * @param initExtAddr - [in] EXT address of initiator device
- * @param partNwkAddr - [in] NWK address of partner device
- * @param partExtAddr - [in] EXT address of partner device
- * @param key - [out] APP(MASTER or LINK) key
- * @param keyType - [out] APP(MASTER or LINK) key type
- *
- * @return ZStatus_t
- */
- uint8 ZDSecMgrAppKeyType = KEY_TYPE_APP_LINK; // Set the default key type
- // to KEY_TYPE_APP_LINK since
- // only specific requirement
- // right now comes from SE profile
- ZStatus_t ZDSecMgrAppKeyGet( uint16 initNwkAddr,
- uint8* initExtAddr,
- uint16 partNwkAddr,
- uint8* partExtAddr,
- uint8** key,
- uint8* keyType )
- {
- // Intentionally unreferenced parameters
- (void)initNwkAddr;
- (void)initExtAddr;
- (void)partNwkAddr;
- (void)partExtAddr;
- //---------------------------------------------------------------------------
- // note:
- // should use a robust mechanism to generate keys, for example
- // combine EXT addresses and call a hash function
- //---------------------------------------------------------------------------
- SSP_GetTrueRand( SEC_KEY_LEN, *key );
- *keyType = ZDSecMgrAppKeyType;
- return ZSuccess;
- }
- /******************************************************************************
- * @fn ZDSecMgrAppKeyReq
- *
- * @brief Process request for APP key between two devices.
- *
- * @param device - [in] ZDO_RequestKeyInd_t, request info
- *
- * @return none
- */
- void ZDSecMgrAppKeyReq( ZDO_RequestKeyInd_t* ind )
- {
- APSME_TransportKeyReq_t req;
- uint8 initExtAddr[Z_EXTADDR_LEN];
- uint16 partNwkAddr;
- uint8 key[SEC_KEY_LEN];
- // validate initiator and partner
- if ( ( APSME_LookupNwkAddr( ind->partExtAddr, &partNwkAddr ) == TRUE ) &&
- ( APSME_LookupExtAddr( ind->srcAddr, initExtAddr ) == TRUE ) )
- {
- // point the key to some memory
- req.key = key;
- // get an APP key - option APP (MASTER or LINK) key
- if ( ZDSecMgrAppKeyGet( ind->srcAddr,
- initExtAddr,
- partNwkAddr,
- ind->partExtAddr,
- &req.key,
- &req.keyType ) == ZSuccess )
- {
- // always secure
- req.nwkSecure = TRUE;
- req.apsSecure = TRUE;
- req.tunnel = NULL;
- // send key to initiator device
- req.dstAddr = ind->srcAddr;
- req.extAddr = ind->partExtAddr;
- req.initiator = TRUE;
- APSME_TransportKeyReq( &req );
- // send key to partner device
- req.dstAddr = partNwkAddr;
- req.extAddr = initExtAddr;
- req.initiator = FALSE;
- APSME_TransportKeyReq( &req );
- // clear copy of key in RAM
- osal_memset( key, 0x00, SEC_KEY_LEN);
- }
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrEstablishKey
- *
- * @brief Start SKKE with device joining network.
- *
- * @param device - [in] ZDSecMgrDevice_t, device info
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrEstablishKey( ZDSecMgrDevice_t* device )
- {
- ZStatus_t status;
- APSME_EstablishKeyReq_t req;
- req.respExtAddr = device->extAddr;
- req.method = APSME_SKKE_METHOD;
- if ( device->parentAddr == NLME_GetShortAddr() )
- {
- req.dstAddr = device->nwkAddr;
- //devtag.0604.todo - remove obsolete
- req.apsSecure = FALSE;
- req.nwkSecure = FALSE;
- }
- else
- {
- req.dstAddr = device->parentAddr;
- //devtag.0604.todo - remove obsolete
- req.apsSecure = TRUE;
- req.nwkSecure = TRUE;
- }
- status = APSME_EstablishKeyReq( &req );
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrSendMasterKey
- *
- * @brief Send MASTER key to device joining network.
- *
- * @param device - [in] ZDSecMgrDevice_t, device info
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrSendMasterKey( ZDSecMgrDevice_t* device )
- {
- ZStatus_t status;
- APSME_TransportKeyReq_t req;
- uint16 keyNvId;
- uint8 masterKey[SEC_KEY_LEN];
- req.keyType = KEY_TYPE_TC_MASTER;
- req.extAddr = device->extAddr;
- req.tunnel = NULL;
- if ( ZDSecMgrMasterKeyLookup( device->ctrl->entry->ami, &keyNvId ) == ZSuccess )
- {
- osal_nv_read( keyNvId, osal_offsetof(ZDSecMgrMasterKeyData_t, key),
- SEC_KEY_LEN, masterKey );
- }
- else
- {
- // in case read from NV fails
- osal_memset( masterKey, 0x00, SEC_KEY_LEN);
- }
- req.key = masterKey;
- //check if using secure hop to to parent
- if ( device->parentAddr != NLME_GetShortAddr() )
- {
- //send to parent with security
- req.dstAddr = device->parentAddr;
- req.nwkSecure = TRUE;
- req.apsSecure = TRUE;
- }
- else
- {
- //direct with no security
- req.dstAddr = device->nwkAddr;
- req.nwkSecure = FALSE;
- req.apsSecure = FALSE;
- }
- status = APSME_TransportKeyReq( &req );
- // clear copy of key in RAM
- osal_memset( masterKey, 0x00, SEC_KEY_LEN);
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrSendNwkKey
- *
- * @brief Send NWK key to device joining network.
- *
- * @param device - [in] ZDSecMgrDevice_t, device info
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrSendNwkKey( ZDSecMgrDevice_t* device )
- {
- ZStatus_t status;
- APSME_TransportKeyReq_t req;
- APSDE_FrameTunnel_t tunnel;
- nwkKeyDesc tmpKey;
- req.dstAddr = device->nwkAddr;
- req.extAddr = device->extAddr;
- if ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_PRO_HIGH )
- {
- req.keyType = KEY_TYPE_NWK_HIGH;
- }
- else
- {
- req.keyType = KEY_TYPE_NWK;
- }
- // get the Active Key into a local variable
- if( NLME_ReadNwkKeyInfo( 0, sizeof(tmpKey), &tmpKey,
- ZCD_NV_NWK_ACTIVE_KEY_INFO ) != SUCCESS )
- {
- // set key data to all 0s if NV read fails
- osal_memset(&tmpKey, 0x00, sizeof(tmpKey));
- }
- if ( (ZG_CHECK_SECURITY_MODE == ZG_SECURITY_PRO_HIGH)
- || (ZG_CHECK_SECURITY_MODE == ZG_SECURITY_SE_STANDARD) )
- {
- // set values
- req.keySeqNum = tmpKey.keySeqNum;
- req.key = tmpKey.key;
- //devtag.pro.security.todo - make sure that if there is no link key the NWK
- //key isn't used to secure the frame at the APS layer -- since the receiving
- //device may not have a NWK key yet
- req.apsSecure = TRUE;
- // check if using secure hop to to parent
- if ( device->parentAddr == NLME_GetShortAddr() )
- {
- req.nwkSecure = FALSE;
- req.tunnel = NULL;
- }
- else
- {
- req.nwkSecure = TRUE;
- req.tunnel = &tunnel;
- req.tunnel->tna = device->parentAddr;
- req.tunnel->dea = device->extAddr;
- }
- }
- else
- {
- // default values
- //devtag.0604.verify
- req.nwkSecure = TRUE;
- req.apsSecure = FALSE;
- req.tunnel = NULL;
- if ( device->parentAddr != NLME_GetShortAddr() )
- {
- req.dstAddr = device->parentAddr;
- }
- // special cases
- //devtag.0604.todo - modify to preconfig flag
- if ( device->secure == FALSE )
- {
- req.keySeqNum = tmpKey.keySeqNum;
- req.key = tmpKey.key;
- // check if using secure hop to to parent
- if ( device->parentAddr == NLME_GetShortAddr() )
- {
- req.nwkSecure = FALSE;
- }
- }
- else
- {
- req.key = NULL;
- req.keySeqNum = 0;
- }
- }
- status = APSME_TransportKeyReq( &req );
- // clear copy of key in RAM before return
- osal_memset( &tmpKey, 0x00, sizeof(nwkKeyDesc) );
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrDeviceEntryRemove
- *
- * @brief Remove device entry.
- *
- * @param entry - [in] valid entry
- *
- * @return none
- */
- void ZDSecMgrDeviceEntryRemove( ZDSecMgrEntry_t* entry )
- {
- // terminate device control
- if ( ( ZG_BUILD_COORDINATOR_TYPE ) && ( ZG_DEVICE_COORDINATOR_TYPE ) )
- {
- ZDSecMgrCtrlTerm( entry );
- }
- // remove device from entry data
- ZDSecMgrEntryFree( entry );
- }
- /******************************************************************************
- * @fn ZDSecMgrDeviceRemoveByExtAddr
- *
- * @brief Remove device entry by its ext address.
- *
- * @param pAddr - pointer to the extended address
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrDeviceRemoveByExtAddr( uint8 *pAddr )
- {
- ZDSecMgrEntry_t *pEntry;
- uint8 retValue;
- retValue = (uint8)ZDSecMgrEntryLookupExt( pAddr, &pEntry );
- if( retValue == ZSuccess )
- {
- ZDSecMgrDeviceEntryRemove( pEntry );
- }
- return retValue;
- }
- /******************************************************************************
- * @fn ZDSecMgrDeviceEntryAdd
- *
- * @brief Add entry.
- *
- * @param device - [in] ZDSecMgrDevice_t, device info
- * @param ami - [in] Address Manager index
- *
- * @return ZStatus_t
- */
- void ZDSecMgrAddrMgrUpdate( uint16 ami, uint16 nwkAddr )
- {
- AddrMgrEntry_t entry;
- // get the ami data
- entry.user = ADDRMGR_USER_SECURITY;
- entry.index = ami;
- AddrMgrEntryGet( &entry );
- // check if NWK address is same
- if ( entry.nwkAddr != nwkAddr )
- {
- // update NWK address
- entry.nwkAddr = nwkAddr;
- AddrMgrEntryUpdate( &entry );
- }
- }
- ZStatus_t ZDSecMgrDeviceEntryAdd( ZDSecMgrDevice_t* device, uint16 ami )
- {
- ZStatus_t status;
- ZDSecMgrEntry_t* entry;
- // initialize as unknown until completion
- status = ZNwkUnknownDevice;
- device->ctrl = NULL;
- // make sure not already registered
- if ( ZDSecMgrEntryLookup( device->nwkAddr, &entry ) == ZSuccess )
- {
- // verify that address index is same
- if ( entry->ami != ami )
- {
- // remove conflicting entry
- ZDSecMgrDeviceEntryRemove( entry );
- if ( ZDSecMgrEntryLookupAMI( ami, &entry ) == ZSuccess )
- {
- // update NWK address
- ZDSecMgrAddrMgrUpdate( ami, device->nwkAddr );
- }
- }
- }
- else if ( ZDSecMgrEntryLookupAMI( ami, &entry ) == ZSuccess )
- {
- // update NWK address
- ZDSecMgrAddrMgrUpdate( ami, device->nwkAddr );
- }
- // check if a new entry needs to be created
- if ( entry == NULL )
- {
- // get new entry
- if ( ZDSecMgrEntryNew( &entry ) == ZSuccess )
- {
- // reset entry lkd
- // finish setting up entry
- entry->ami = ami;
- // update NWK address
- ZDSecMgrAddrMgrUpdate( ami, device->nwkAddr );
- // enter new device into device control
- if ( ( ZG_BUILD_COORDINATOR_TYPE ) && ( ZG_DEVICE_COORDINATOR_TYPE ) )
- {
- status = ZDSecMgrCtrlAdd( device, entry );
- }
- else
- {
- status = ZSuccess;
- }
- }
- }
- else
- {
- // reset entry lkd
- // reset entry in entry control
- if ( ( ZG_BUILD_COORDINATOR_TYPE ) && ( ZG_DEVICE_COORDINATOR_TYPE ) )
- {
- status = ZDSecMgrCtrlReset( device, entry );
- }
- else
- {
- status = ZSuccess;
- }
- }
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrDeviceCtrlHandler
- *
- * @brief Device control handler.
- *
- * @param device - [in] ZDSecMgrDevice_t, device info
- *
- * @return none
- */
- void ZDSecMgrDeviceCtrlHandler( ZDSecMgrDevice_t* device )
- {
- uint8 state;
- uint8 cntr;
- state = device->ctrl->state;
- cntr = ZDSECMGR_CTRL_BASE_CNTR;
- switch ( state )
- {
- case ZDSECMGR_CTRL_TK_MASTER:
- if ( ZDSecMgrSendMasterKey( device ) == ZSuccess )
- {
- state = ZDSECMGR_CTRL_SKKE_INIT;
- cntr = ZDSECMGR_CTRL_SKKE_INIT_CNTR;
- }
- break;
- case ZDSECMGR_CTRL_SKKE_INIT:
- if ( ZDSecMgrEstablishKey( device ) == ZSuccess )
- {
- state = ZDSECMGR_CTRL_SKKE_WAIT;
- }
- break;
- case ZDSECMGR_CTRL_SKKE_WAIT:
- // continue to wait for SKA control timeout
- break;
- case ZDSECMGR_CTRL_TK_NWK:
- if ( ZDSecMgrSendNwkKey( device ) == ZSuccess )
- {
- state = ZDSECMGR_CTRL_NONE;
- }
- break;
- default:
- state = ZDSECMGR_CTRL_NONE;
- break;
- }
- if ( state != ZDSECMGR_CTRL_NONE )
- {
- device->ctrl->state = state;
- device->ctrl->cntr = cntr;
- osal_start_timerEx(ZDAppTaskID, ZDO_SECMGR_EVENT, 100 );
- }
- else
- {
- ZDSecMgrCtrlRelease( device->ctrl );
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrDeviceCtrlSetup
- *
- * @brief Setup device control.
- *
- * @param device - [in] ZDSecMgrDevice_t, device info
- *
- * @return ZStatus_t
- */
- void ZDSecMgrDeviceCtrlSetup( ZDSecMgrDevice_t* device )
- {
- if ( device->ctrl != NULL )
- {
- if ( device->secure == FALSE )
- {
- // send the master key data to the joining device
- device->ctrl->state = ZDSECMGR_CTRL_TK_MASTER;
- }
- else
- {
- // start SKKE
- device->ctrl->state = ZDSECMGR_CTRL_SKKE_INIT;
- }
- ZDSecMgrDeviceCtrlHandler( device );
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrDeviceCtrlUpdate
- *
- * @brief Update control data.
- *
- * @param extAddr - [in] EXT address
- * @param state - [in] new control state
- *
- * @return none
- */
- void ZDSecMgrDeviceCtrlUpdate( uint8* extAddr, uint8 state )
- {
- ZDSecMgrEntry_t* entry;
- ZDSecMgrCtrl_t* ctrl;
- // lookup device entry data
- (void)ZDSecMgrEntryLookupExt( extAddr, &entry );
- if ( entry != NULL )
- {
- // lookup device control data
- ZDSecMgrCtrlLookup( entry, &ctrl );
- // make sure control data is valid
- if ( ctrl != NULL )
- {
- // possible state transitions
- if ( ctrl->state == ZDSECMGR_CTRL_SKKE_WAIT )
- {
- if ( state == ZDSECMGR_CTRL_SKKE_DONE )
- {
- // send the network key
- ctrl->state = ZDSECMGR_CTRL_TK_NWK;
- ctrl->cntr = ZDSECMGR_CTRL_TK_NWK_CNTR;
- }
- else if ( state == ZDSECMGR_CTRL_SKKE_FAIL )
- {
- // force default timeout in order to cleanup control logic
- ctrl->state = ZDSECMGR_CTRL_SKKE_FAIL;
- ctrl->cntr = ZDSECMGR_CTRL_BASE_CNTR;
- }
- }
- // timer should be active
- }
- }
- }
- void APSME_SKA_TimerExpired( uint8 initiator, uint8* partExtAddr );
- void APSME_SKA_TimerExpired( uint8 initiator, uint8* partExtAddr )
- {
- if ( ( ZG_BUILD_COORDINATOR_TYPE ) && ( ZG_DEVICE_COORDINATOR_TYPE ) )
- {
- if ( initiator == TRUE )
- {
- ZDSecMgrDeviceCtrlUpdate( partExtAddr, ZDSECMGR_CTRL_SKKE_FAIL );
- }
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrDeviceRemove
- *
- * @brief Remove device from network.
- *
- * @param device - [in] ZDSecMgrDevice_t, device info
- *
- * @return none
- */
- void ZDSecMgrDeviceRemove( ZDSecMgrDevice_t* device )
- {
- APSME_RemoveDeviceReq_t remDevReq;
- NLME_LeaveReq_t leaveReq;
- associated_devices_t* assoc;
- // check if parent, remove the device
- if ( device->parentAddr == NLME_GetShortAddr() )
- {
- // this is the parent of the device
- leaveReq.extAddr = device->extAddr;
- leaveReq.removeChildren = FALSE;
- leaveReq.rejoin = FALSE;
- // find child association
- assoc = AssocGetWithExt( device->extAddr );
- if ( ( assoc != NULL ) &&
- ( assoc->nodeRelation >= CHILD_RFD ) &&
- ( assoc->nodeRelation <= CHILD_FFD_RX_IDLE ) )
- {
- // check if associated device is authenticated
- if ( assoc->devStatus & DEV_SEC_AUTH_STATUS )
- {
- leaveReq.silent = FALSE;
- }
- else
- {
- leaveReq.silent = TRUE;
- }
- NLME_LeaveReq( &leaveReq );
- }
- }
- else
- {
- // this is not the parent of the device
- remDevReq.parentAddr = device->parentAddr;
- remDevReq.childExtAddr = device->extAddr;
- APSME_RemoveDeviceReq( &remDevReq );
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrDeviceValidateSKKE
- *
- * @brief Decide whether device is allowed for SKKE.
- *
- * @param device - [in] ZDSecMgrDevice_t, device info
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrDeviceValidateSKKE( ZDSecMgrDevice_t* device )
- {
- ZStatus_t status;
- uint16 ami;
- uint16 keyNvId;
- // get EXT address
- status = ZDSecMgrExtAddrLookup( device->extAddr, &ami );
- if ( status == ZSuccess )
- {
- // get MASTER key
- status = ZDSecMgrMasterKeyLookup( ami, &keyNvId );
- if ( status == ZSuccess )
- {
- status = ZDSecMgrDeviceEntryAdd( device, ami );
- }
- }
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrDeviceValidateRM (RESIDENTIAL MODE)
- *
- * @brief Decide whether device is allowed.
- *
- * @param device - [in] ZDSecMgrDevice_t, device info
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrDeviceValidateRM( ZDSecMgrDevice_t* device )
- {
- ZStatus_t status;
- status = ZSuccess;
- (void)device; // Intentionally unreferenced parameter
- // For test purpose, turning off the zgSecurePermitJoin flag will force
- // the trust center to reject any newly joining devices by sending
- // Remove-device to the parents.
- if ( zgSecurePermitJoin == FALSE )
- {
- status = ZNwkUnknownDevice;
- }
- #if 0 // Taken out because the following functionality is only used for test
- // purpose. A more efficient (above) way is used. It can be put
- // back in if customers request for a white/black list feature.
- // ZDSecMgrStoredDeviceList[] is defined in ZDSecMgr.c
- // The following code processes the device black list (stored device list)
- // If the joining device is not part of the forbidden device list
- // Return ZSuccess. Otherwise, return ZNwkUnknownDevice. The trust center
- // will send Remove-device and ban the device from joining.
- uint8 index;
- uint8* restricted;
- // Look through the stored device list - used for restricted devices
- for ( index = 0; index < ZDSECMGR_STORED_DEVICES; index++ )
- {
- restricted = ZDSecMgrStoredDeviceList[index];
- if ( AddrMgrExtAddrEqual( restricted, device->extAddr ) == TRUE )
- {
- // return as unknown device in regards to validation
- status = ZNwkUnknownDevice;
- // break from loop
- index = ZDSECMGR_STORED_DEVICES;
- }
- }
- #endif
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrDeviceValidateCM (COMMERCIAL MODE)
- *
- * @brief Decide whether device is allowed.
- *
- * @param device - [in] ZDSecMgrDevice_t, device info
- *
- * @return ZStatus_t
- */
- //devtag.pro.security
- ZStatus_t ZDSecMgrDeviceValidateCM( ZDSecMgrDevice_t* device )
- {
- ZStatus_t status;
- uint16 ami;
- uint8 key[SEC_KEY_LEN];
- // implement EXT address and MASTER key policy here -- the total number of
- // Security Manager entries should never exceed the number of EXT addresses
- // and MASTER keys available
- // set status based on policy
- //status = ZNwkUnknownDevice;
- // set status based on policy
- status = ZSuccess; // ZNwkUnknownDevice;
- // get key based on policy
- osal_memcpy( key, ZDSecMgrTCMasterKey, SEC_KEY_LEN);
- // if policy, store new EXT address
- status = ZDSecMgrAddrStore( device->nwkAddr, device->extAddr, &ami );
- // set the key
- ZDSecMgrMasterKeyLoad( device->extAddr, key );
- // if EXT address and MASTER key available -- add device
- if ( status == ZSuccess )
- {
- // add device to internal data - with control
- status = ZDSecMgrDeviceEntryAdd( device, ami );
- }
- // remove copy of key in RAM
- osal_memset( key, 0x00, SEC_KEY_LEN );
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrDeviceValidate
- *
- * @brief Decide whether device is allowed.
- *
- * @param device - [in] ZDSecMgrDevice_t, device info
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrDeviceValidate( ZDSecMgrDevice_t* device )
- {
- ZStatus_t status;
- if ( ZDSecMgrPermitJoiningEnabled == TRUE )
- {
- // device may be joining with a secure flag but it is ultimately the Trust
- // Center that decides -- check if expected pre configured device --
- // override settings
- if ( zgPreConfigKeys == TRUE )
- {
- device->secure = TRUE;
- }
- else
- {
- device->secure = FALSE;
- }
- if ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_PRO_HIGH )
- {
- status = ZDSecMgrDeviceValidateCM( device );
- }
- else // ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_RESIDENTIAL )
- {
- status = ZDSecMgrDeviceValidateRM( device );
- }
- }
- else
- {
- status = ZNwkUnknownDevice;
- }
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrDeviceJoin
- *
- * @brief Try to join this device.
- *
- * @param device - [in] ZDSecMgrDevice_t, device info
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrDeviceJoin( ZDSecMgrDevice_t* device )
- {
- ZStatus_t status;
- uint16 ami;
- // attempt to validate device
- status = ZDSecMgrDeviceValidate( device );
- if ( status == ZSuccess )
- {
- if ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_PRO_HIGH )
- {
- ZDSecMgrDeviceCtrlSetup( device );
- }
- else // ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_RESIDENTIAL )
- {
- // Add the device to the address manager
- ZDSecMgrAddrStore( device->nwkAddr, device->extAddr, &ami );
- //send the nwk key data to the joining device
- status = ZDSecMgrSendNwkKey( device );
- }
- }
- else
- {
- // not allowed, remove the device
- ZDSecMgrDeviceRemove( device );
- }
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrDeviceJoinDirect
- *
- * @brief Try to join this device as a direct child.
- *
- * @param device - [in] ZDSecMgrDevice_t, device info
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrDeviceJoinDirect( ZDSecMgrDevice_t* device )
- {
- ZStatus_t status;
- status = ZDSecMgrDeviceJoin( device );
- if ( status == ZSuccess )
- {
- // set association status to authenticated
- ZDSecMgrAssocDeviceAuth( AssocGetWithShort( device->nwkAddr ) );
- }
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrDeviceJoinFwd
- *
- * @brief Forward join to Trust Center.
- *
- * @param device - [in] ZDSecMgrDevice_t, device info
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrDeviceJoinFwd( ZDSecMgrDevice_t* device )
- {
- ZStatus_t status;
- APSME_UpdateDeviceReq_t req;
- // forward any joining device to the Trust Center -- the Trust Center will
- // decide if the device is allowed to join
- status = ZSuccess;
- // forward authorization to the Trust Center
- req.dstAddr = APSME_TRUSTCENTER_NWKADDR;
- req.devAddr = device->nwkAddr;
- req.devExtAddr = device->extAddr;
- // set security status, option for router to reject if policy set
- if ( (device->devStatus & DEV_HIGH_SEC_STATUS) )
- {
- if ( device->devStatus & DEV_REJOIN_STATUS )
- {
- if ( device->secure == TRUE )
- {
- req.status = APSME_UD_HIGH_SECURED_REJOIN;
- }
- else
- {
- req.status = APSME_UD_HIGH_UNSECURED_REJOIN;
- }
- }
- else
- {
- req.status = APSME_UD_HIGH_UNSECURED_JOIN;
- }
- }
- else
- {
- if ( device->devStatus & DEV_REJOIN_STATUS )
- {
- if ( device->secure == TRUE )
- {
- req.status = APSME_UD_STANDARD_SECURED_REJOIN;
- }
- else
- {
- req.status = APSME_UD_STANDARD_UNSECURED_REJOIN;
- }
- }
- else
- {
- req.status = APSME_UD_STANDARD_UNSECURED_JOIN;
- }
- }
- if ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_PRO_HIGH )
- {
- req.apsSecure = TRUE;
- }
- else
- {
- req.apsSecure = FALSE;
- }
- // send and APSME_UPDATE_DEVICE request to the trust center
- status = APSME_UpdateDeviceReq( &req );
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrDeviceNew
- *
- * @brief Process a new device.
- *
- * @param device - [in] ZDSecMgrDevice_t, device info
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrDeviceNew( ZDSecMgrDevice_t* joiner )
- {
- ZStatus_t status;
- if ( ( ZG_BUILD_COORDINATOR_TYPE ) && ( ZG_DEVICE_COORDINATOR_TYPE ) )
- {
- // try to join this device
- status = ZDSecMgrDeviceJoinDirect( joiner );
- }
- else
- {
- status = ZDSecMgrDeviceJoinFwd( joiner );
- }
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrAssocDeviceAuth
- *
- * @brief Set associated device status to authenticated
- *
- * @param assoc - [in, out] associated_devices_t
- *
- * @return none
- */
- void ZDSecMgrAssocDeviceAuth( associated_devices_t* assoc )
- {
- if ( assoc != NULL )
- {
- assoc->devStatus |= DEV_SEC_AUTH_STATUS;
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrAuthInitiate
- *
- * @brief Initiate entity authentication
- *
- * @param responder - [in] responder EXT address
- *
- * @return none
- */
- void ZDSecMgrAuthInitiate( uint8* responder )
- {
- APSME_AuthenticateReq_t req;
- // make sure NWK address is available
- if ( APSME_LookupNwkAddr( responder, &req.nwkAddr ) )
- {
- // set request fields
- req.extAddr = responder;
- req.action = APSME_EA_INITIATE;
- req.challenge = NULL;
- // start EA processing
- APSME_AuthenticateReq( &req );
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrAuthNwkKey
- *
- * @brief Handle next step in authentication process
- *
- * @param none
- *
- * @return none
- */
- void ZDSecMgrAuthNwkKey()
- {
- if ( devState == DEV_END_DEVICE_UNAUTH )
- {
- if ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_PRO_HIGH )
- {
- uint8 parent[Z_EXTADDR_LEN];
- // get parent's EXT address
- NLME_GetCoordExtAddr( parent );
- // begin entity authentication with parent
- ZDSecMgrAuthInitiate( parent );
- }
- else
- {
- // inform ZDO that device has been authenticated
- osal_set_event ( ZDAppTaskID, ZDO_DEVICE_AUTH );
- }
- }
- }
- /******************************************************************************
- * PUBLIC FUNCTIONS
- */
- /******************************************************************************
- * @fn ZDSecMgrInit
- *
- * @brief Initialize ZigBee Device Security Manager.
- *
- * @param state - device initialization state
- *
- * @return none
- */
- #if ( ADDRMGR_CALLBACK_ENABLED == 1 )
- void ZDSecMgrAddrMgrCB( uint8 update, AddrMgrEntry_t* newEntry, AddrMgrEntry_t* oldEntry );
- void ZDSecMgrAddrMgrCB( uint8 update,
- AddrMgrEntry_t* newEntry,
- AddrMgrEntry_t* oldEntry )
- {
- (void)update;
- (void)newEntry;
- (void)oldEntry;
- }
- #endif // ( ADDRMGR_CALLBACK_ENABLED == 1 )
- void ZDSecMgrInit(uint8 state)
- {
- if ( (ZG_CHECK_SECURITY_MODE == ZG_SECURITY_PRO_HIGH)
- || (ZG_CHECK_SECURITY_MODE == ZG_SECURITY_SE_STANDARD) )
- {
- // initialize sub modules
- ZDSecMgrEntryInit(state);
- if ( ( ZG_BUILD_COORDINATOR_TYPE ) && ( ZG_DEVICE_COORDINATOR_TYPE ) )
- {
- ZDSecMgrCtrlInit();
- }
- // register with Address Manager
- #if ( ADDRMGR_CALLBACK_ENABLED == 1 )
- AddrMgrRegister( ADDRMGR_REG_SECURITY, ZDSecMgrAddrMgrCB );
- #endif
- }
- if ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_PRO_HIGH )
- {
- // configure SKA slot data
- APSME_SKA_SlotInit( ZDSECMGR_SKA_SLOT_MAX );
- }
- if ( ZG_SECURE_ENABLED )
- {
- if ( ( ZG_BUILD_COORDINATOR_TYPE ) && ( ZG_DEVICE_COORDINATOR_TYPE ) )
- {
- // setup joining permissions
- ZDSecMgrPermitJoiningEnabled = TRUE;
- ZDSecMgrPermitJoiningTimed = FALSE;
- }
- }
- // configure security based on security mode and type of device
- ZDSecMgrConfig();
- }
- /******************************************************************************
- * @fn ZDSecMgrConfig
- *
- * @brief Configure ZigBee Device Security Manager.
- *
- * @param none
- *
- * @return none
- */
- void ZDSecMgrConfig( void )
- {
- if ( ZG_SECURE_ENABLED )
- {
- SSP_Init();
- if ( (ZG_CHECK_SECURITY_MODE == ZG_SECURITY_PRO_HIGH)
- || (ZG_CHECK_SECURITY_MODE == ZG_SECURITY_SE_STANDARD) )
- {
- if ( ( ZG_BUILD_COORDINATOR_TYPE ) && ( ZG_DEVICE_COORDINATOR_TYPE ) )
- {
- // COMMERCIAL MODE - COORDINATOR DEVICE
- APSME_SecurityCM_CD();
- }
- else if ( ZSTACK_ROUTER_BUILD )
- {
- // COMMERCIAL MODE - ROUTER DEVICE
- APSME_SecurityCM_RD();
- }
- else
- {
- // COMMERCIAL MODE - END DEVICE
- APSME_SecurityCM_ED();
- }
- }
- else // ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_RESIDENTIAL )
- {
- if ( ( ZG_BUILD_COORDINATOR_TYPE ) && ( ZG_DEVICE_COORDINATOR_TYPE ) )
- {
- // RESIDENTIAL MODE - COORDINATOR DEVICE
- APSME_SecurityRM_CD();
- }
- else if ( ZSTACK_ROUTER_BUILD )
- {
- // RESIDENTIAL MODE - ROUTER DEVICE
- APSME_SecurityRM_RD();
- }
- else
- {
- // RESIDENTIAL MODE - END DEVICE
- APSME_SecurityRM_ED();
- }
- }
- }
- else
- {
- // NO SECURITY
- APSME_SecurityNM();
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrPermitJoining
- *
- * @brief Process request to change joining permissions.
- *
- * @param duration - [in] timed duration for join in seconds
- * - 0x00 not allowed
- * - 0xFF allowed without timeout
- *
- * @return uint8 - success(TRUE:FALSE)
- */
- uint8 ZDSecMgrPermitJoining( uint8 duration )
- {
- uint8 accept;
- ZDSecMgrPermitJoiningTimed = FALSE;
- if ( duration > 0 )
- {
- ZDSecMgrPermitJoiningEnabled = TRUE;
- if ( duration != 0xFF )
- {
- ZDSecMgrPermitJoiningTimed = TRUE;
- }
- }
- else
- {
- ZDSecMgrPermitJoiningEnabled = FALSE;
- }
- accept = TRUE;
- return accept;
- }
- /******************************************************************************
- * @fn ZDSecMgrPermitJoiningTimeout
- *
- * @brief Process permit joining timeout
- *
- * @param none
- *
- * @return none
- */
- void ZDSecMgrPermitJoiningTimeout( void )
- {
- if ( ZDSecMgrPermitJoiningTimed == TRUE )
- {
- ZDSecMgrPermitJoiningEnabled = FALSE;
- ZDSecMgrPermitJoiningTimed = FALSE;
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrNewDeviceEvent
- *
- * @brief Process a the new device event, if found reset new device
- * event/timer.
- *
- * @param none
- *
- * @return uint8 - found(TRUE:FALSE)
- */
- uint8 ZDSecMgrNewDeviceEvent( void )
- {
- uint8 found;
- ZDSecMgrDevice_t device;
- AddrMgrEntry_t addrEntry;
- associated_devices_t* assoc;
- ZStatus_t status;
- // initialize return results
- found = FALSE;
- // look for device in the security init state
- assoc = AssocMatchDeviceStatus( DEV_SEC_INIT_STATUS );
- if ( assoc != NULL )
- {
- // device found
- found = TRUE;
- // check for preconfigured security
- if ( zgPreConfigKeys == TRUE )
- {
- // set association status to authenticated
- ZDSecMgrAssocDeviceAuth( assoc );
- }
- // set up device info
- addrEntry.user = ADDRMGR_USER_DEFAULT;
- addrEntry.index = assoc->addrIdx;
- AddrMgrEntryGet( &addrEntry );
- device.nwkAddr = assoc->shortAddr;
- device.extAddr = addrEntry.extAddr;
- device.parentAddr = NLME_GetShortAddr();
- device.secure = FALSE;
- device.devStatus = assoc->devStatus;
- // process new device
- status = ZDSecMgrDeviceNew( &device );
- if ( status == ZSuccess )
- {
- assoc->devStatus &= ~DEV_SEC_INIT_STATUS;
- }
- else if ( status == ZNwkUnknownDevice )
- {
- AssocRemove( addrEntry.extAddr );
- }
- }
- return found;
- }
- /******************************************************************************
- * @fn ZDSecMgrEvent
- *
- * @brief Handle ZDO Security Manager event/timer(ZDO_SECMGR_EVENT).
- *
- * @param none
- *
- * @return none
- */
- void ZDSecMgrEvent( void )
- {
- uint8 action;
- uint8 restart;
- uint16 index;
- AddrMgrEntry_t entry;
- ZDSecMgrDevice_t device;
- // verify data is available
- if ( ZDSecMgrCtrlData != NULL )
- {
- action = FALSE;
- restart = FALSE;
- // update all the counters
- for ( index = 0; index < ZDSECMGR_ENTRY_MAX; index++ )
- {
- if ( ZDSecMgrCtrlData[index].state != ZDSECMGR_CTRL_NONE )
- {
- if ( ZDSecMgrCtrlData[index].cntr != 0 )
- {
- ZDSecMgrCtrlData[index].cntr--;
- }
- if ( ( action == FALSE ) && ( ZDSecMgrCtrlData[index].cntr == 0 ) )
- {
- action = TRUE;
- // update from control data
- device.parentAddr = ZDSecMgrCtrlData[index].parentAddr;
- device.secure = ZDSecMgrCtrlData[index].secure;
- device.ctrl = &ZDSecMgrCtrlData[index];
- // set the user and address index
- entry.user = ADDRMGR_USER_SECURITY;
- entry.index = ZDSecMgrCtrlData[index].entry->ami;
- // get the address data
- AddrMgrEntryGet( &entry );
- // set device address data
- device.nwkAddr = entry.nwkAddr;
- device.extAddr = entry.extAddr;
- // update from entry data
- ZDSecMgrDeviceCtrlHandler( &device );
- }
- else
- {
- restart = TRUE;
- }
- }
- }
- // check for timer restart
- if ( restart == TRUE )
- {
- osal_start_timerEx(ZDAppTaskID, ZDO_SECMGR_EVENT, 100 );
- }
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrEstablishKeyCfm
- *
- * @brief Process the ZDO_EstablishKeyCfm_t message.
- *
- * @param cfm - [in] ZDO_EstablishKeyCfm_t confirmation
- *
- * @return none
- */
- void ZDSecMgrEstablishKeyCfm( ZDO_EstablishKeyCfm_t* cfm )
- {
- // send the NWK key
- if ( ( ZG_BUILD_COORDINATOR_TYPE ) && ( ZG_DEVICE_COORDINATOR_TYPE ) )
- {
- // update control for specified EXT address
- ZDSecMgrDeviceCtrlUpdate( cfm->partExtAddr, ZDSECMGR_CTRL_SKKE_DONE );
- }
- else
- {
- // this should be done when receiving the NWK key
- // if devState ==
- //if ( devState == DEV_END_DEVICE_UNAUTH )
- //osal_set_event( ZDAppTaskID, ZDO_DEVICE_AUTH );
- // if not in joining state -- this should trigger an event for an
- // end point that requested SKKE
- // if ( devState == DEV_END_DEVICE )
- // devState == DEV_ROUTER;
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrTCExtAddrCheck
- *
- * @brief Verifies if received ext. address matches TC ext. address.
- *
- * @param extAddr - Extended address to be verified.
- *
- * @return TRUE - extended address matches
- * FALSE - otherwise
- */
- uint8 ZDSecMgrTCExtAddrCheck( uint8* extAddr )
- {
- uint8 match;
- uint8 lookup[Z_EXTADDR_LEN];
- match = FALSE;
- if ( AddrMgrExtAddrLookup( APSME_TRUSTCENTER_NWKADDR, lookup ) )
- {
- match = AddrMgrExtAddrEqual( lookup, extAddr );
- }
- return match;
- }
- /******************************************************************************
- * @fn ZDSecMgrTCDataLoad
- *
- * @brief Stores the address of TC into address manager and stores the
- * preconfigured ZDSecMgrTCMasterKey to NV if zgPreConfigKeys
- * is set to TRUE.
- *
- * @param extAddr - Extended address to be verified.
- *
- * @return none
- */
- void ZDSecMgrTCDataLoad( uint8* extAddr )
- {
- uint16 ami;
- uint16 keyNvId;
- uint8 masterKey[SEC_KEY_LEN];
- AddrMgrEntry_t entry;
- // lookup using TC short address
- entry.user = ADDRMGR_USER_DEFAULT;
- entry.nwkAddr = zgTrustCenterAddr;
- // Verify if TC address has been added to Address Manager
- if ( AddrMgrEntryLookupNwk( &entry ) != TRUE )
- {
- if ( ZDSecMgrAddrStore( zgTrustCenterAddr, extAddr, &ami ) == ZSuccess )
- {
- // if preconfigured load key
- if ( zgPreConfigKeys == TRUE )
- {
- if ( ZDSecMgrMasterKeyLookup( ami, &keyNvId ) != ZSuccess )
- {
- // temporary copy
- osal_memcpy( masterKey, ZDSecMgrTCMasterKey, SEC_KEY_LEN);
- ZDSecMgrMasterKeyStore( ami, masterKey );
- // remove copy of key in RAM
- osal_memset( masterKey, 0x00, SEC_KEY_LEN );
- }
- }
- }
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrEstablishKeyInd
- *
- * @brief Process the ZDO_EstablishKeyInd_t message.
- *
- * @param ind - [in] ZDO_EstablishKeyInd_t indication
- *
- * @return none
- */
- void ZDSecMgrEstablishKeyInd( ZDO_EstablishKeyInd_t* ind )
- {
- ZDSecMgrDevice_t device;
- APSME_EstablishKeyRsp_t rsp;
- // load Trust Center data if needed
- ZDSecMgrTCDataLoad( ind->initExtAddr );
- if ( ZDSecMgrTCExtAddrCheck( ind->initExtAddr ) )
- {
- //IF (ind->srcAddr == APSME_TRUSTCENTER_NWKADDR)
- //OR
- //!ZDSecMgrTCAuthenticated
- //devtag.0604.critical
- //how is the parentAddr used here
- // initial SKKE from Trust Center via parent
- device.nwkAddr = APSME_TRUSTCENTER_NWKADDR;
- device.parentAddr = ind->srcAddr;
- }
- else
- {
- // Trust Center direct or E2E SKKE
- device.nwkAddr = ind->srcAddr;
- device.parentAddr = INVALID_NODE_ADDR;
- }
- device.extAddr = ind->initExtAddr;
- //devtag.pro.security.0724.todo - verify usage
- device.secure = ind->nwkSecure;
- // validate device for SKKE
- if ( ZDSecMgrDeviceValidateSKKE( &device ) == ZSuccess )
- {
- rsp.accept = TRUE;
- }
- else
- {
- rsp.accept = FALSE;
- }
- rsp.dstAddr = ind->srcAddr;
- rsp.initExtAddr = &ind->initExtAddr[0];
- //devtag.0604.todo - remove obsolete
- rsp.apsSecure = ind->apsSecure;
- rsp.nwkSecure = ind->nwkSecure;
- APSME_EstablishKeyRsp( &rsp );
- }
- //devtag.pro.security
- #if 0
- void ZDSecMgrEstablishKeyInd( ZDO_EstablishKeyInd_t* ind )
- {
- ZDSecMgrDevice_t device;
- APSME_EstablishKeyRsp_t rsp;
- device.extAddr = ind->initExtAddr;
- device.secure = ind->secure;
- if ( ind->secure == FALSE )
- {
- // SKKE from Trust Center is not secured between child and parent
- device.nwkAddr = APSME_TRUSTCENTER_NWKADDR;
- device.parentAddr = ind->srcAddr;
- }
- else
- {
- // SKKE from initiator should be secured
- device.nwkAddr = ind->srcAddr;
- device.parentAddr = INVALID_NODE_ADDR;
- }
- rsp.dstAddr = ind->srcAddr;
- rsp.initExtAddr = &ind->initExtAddr[0];
- rsp.secure = ind->secure;
- // validate device for SKKE
- if ( ZDSecMgrDeviceValidateSKKE( &device ) == ZSuccess )
- {
- rsp.accept = TRUE;
- }
- else
- {
- rsp.accept = FALSE;
- }
- APSME_EstablishKeyRsp( &rsp );
- }
- #endif
- /******************************************************************************
- * @fn ZDSecMgrTransportKeyInd
- *
- * @brief Process the ZDO_TransportKeyInd_t message.
- *
- * @param ind - [in] ZDO_TransportKeyInd_t indication
- *
- * @return none
- */
- void ZDSecMgrTransportKeyInd( ZDO_TransportKeyInd_t* ind )
- {
- uint8 index;
- uint8 zgPreConfigKey[SEC_KEY_LEN];
- // load Trust Center data if needed
- ZDSecMgrTCDataLoad( ind->srcExtAddr );
- if ( ind->keyType == KEY_TYPE_TC_MASTER )
- {
- if ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_PRO_HIGH )
- //ZDSecMgrTCMasterKey( ind );
- {
- if ( zgPreConfigKeys != TRUE )
- {
- // devtag.pro.security.todo - check if Trust Center address is configured and correct
- ZDSecMgrMasterKeyLoad( ind->srcExtAddr, ind->key );
- }
- else
- {
- // error condition - reject key
- }
- }
- }
- else if ( ( ind->keyType == KEY_TYPE_NWK ) ||
- ( ind->keyType == 6 ) ||
- ( ind->keyType == KEY_TYPE_NWK_HIGH ) )
- {
- // check for dummy NWK key (all zeros)
- for ( index = 0;
- ( (index < SEC_KEY_LEN) && (ind->key[index] == 0) );
- index++ );
- if ( index == SEC_KEY_LEN )
- {
- // load preconfigured key - once!!
- if ( !_NIB.nwkKeyLoaded )
- {
- ZDSecMgrReadKeyFromNv(ZCD_NV_PRECFGKEY, zgPreConfigKey);
- SSP_UpdateNwkKey( zgPreConfigKey, 0 );
- SSP_SwitchNwkKey( 0 );
- // clear local copy of key
- osal_memset(zgPreConfigKey, 0x00, SEC_KEY_LEN);
- }
- }
- else
- {
- SSP_UpdateNwkKey( ind->key, ind->keySeqNum );
- if ( !_NIB.nwkKeyLoaded )
- {
- SSP_SwitchNwkKey( ind->keySeqNum );
- }
- }
- // handle next step in authentication process
- ZDSecMgrAuthNwkKey();
- }
- else if ( ind->keyType == KEY_TYPE_TC_LINK )
- {
- if ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_PRO_HIGH )
- {
- // This should not happen because TCLK should not be Tx
- }
- }
- else if ( ind->keyType == KEY_TYPE_APP_MASTER )
- {
- if ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_PRO_HIGH )
- {
- uint16 ami;
- AddrMgrEntry_t entry;
- ZDSecMgrEntry_t* entryZD;
- ZDSecMgrExtAddrLookup( ind->srcExtAddr, &ami );
- if ( ind->initiator == TRUE )
- {
- // get the ami data
- entry.user = ADDRMGR_USER_SECURITY;
- entry.index = ami;
- AddrMgrEntryGet( &entry );
- if ( entry.nwkAddr != INVALID_NODE_ADDR )
- {
- APSME_EstablishKeyReq_t req;
- ZDSecMgrMasterKeyLoad( ind->srcExtAddr, ind->key );
- ZDSecMgrEntryLookupAMI( ami, &entryZD );
- if ( entryZD == NULL )
- {
- // get new entry
- if ( ZDSecMgrEntryNew( &entryZD ) == ZSuccess )
- {
- // finish setting up entry
- entryZD->ami = ami;
- }
- }
- req.respExtAddr = ind->srcExtAddr;
- req.method = APSME_SKKE_METHOD;
- req.dstAddr = entry.nwkAddr;
- req.apsSecure = FALSE;
- req.nwkSecure = TRUE;
- APSME_EstablishKeyReq( &req );
- }
- }
- else
- {
- if ( ami == INVALID_NODE_ADDR )
- {
- // store new EXT address
- ZDSecMgrAddrStore( INVALID_NODE_ADDR, ind->srcExtAddr, &ami );
- }
- ZDSecMgrMasterKeyLoad( ind->srcExtAddr, ind->key );
- }
- }
- }
- else if ( ind->keyType == KEY_TYPE_APP_LINK )
- {
- if ( ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_PRO_HIGH ) ||
- ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_SE_STANDARD ) )
- {
- uint16 ami;
- ZDSecMgrEntry_t* entry;
- // get the address index
- if ( ZDSecMgrExtAddrLookup( ind->srcExtAddr, &ami ) != ZSuccess )
- {
- // store new EXT address
- ZDSecMgrAddrStore( INVALID_NODE_ADDR, ind->srcExtAddr, &ami );
- ZDP_NwkAddrReq( ind->srcExtAddr, ZDP_ADDR_REQTYPE_SINGLE, 0, 0 );
- }
- ZDSecMgrEntryLookupAMI( ami, &entry );
- if ( entry == NULL )
- {
- // get new entry
- if ( ZDSecMgrEntryNew( &entry ) == ZSuccess )
- {
- // finish setting up entry
- entry->ami = ami;
- }
- }
- ZDSecMgrLinkKeySet( ind->srcExtAddr, ind->key );
- #if defined NV_RESTORE
- ZDSecMgrWriteNV(); // Write the control record for the new established link key to NV.
- #endif
- }
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrUpdateDeviceInd
- *
- * @brief Process the ZDO_UpdateDeviceInd_t message.
- *
- * @param ind - [in] ZDO_UpdateDeviceInd_t indication
- *
- * @return none
- */
- void ZDSecMgrUpdateDeviceInd( ZDO_UpdateDeviceInd_t* ind )
- {
- ZDSecMgrDevice_t device;
- device.nwkAddr = ind->devAddr;
- device.extAddr = ind->devExtAddr;
- device.parentAddr = ind->srcAddr;
- //if ( ( ind->status == APSME_UD_SECURED_JOIN ) ||
- // ( ind->status == APSME_UD_UNSECURED_JOIN ) )
- //{
- // if ( ind->status == APSME_UD_SECURED_JOIN )
- // {
- // device.secure = TRUE;
- // }
- // else
- // {
- // device.secure = FALSE;
- // }
- // try to join this device
- ZDSecMgrDeviceJoin( &device );
- //}
- }
- /******************************************************************************
- * @fn ZDSecMgrRemoveDeviceInd
- *
- * @brief Process the ZDO_RemoveDeviceInd_t message.
- *
- * @param ind - [in] ZDO_RemoveDeviceInd_t indication
- *
- * @return none
- */
- void ZDSecMgrRemoveDeviceInd( ZDO_RemoveDeviceInd_t* ind )
- {
- ZDSecMgrDevice_t device;
- // only accept from Trust Center
- if ( ind->srcAddr == APSME_TRUSTCENTER_NWKADDR )
- {
- // look up NWK address
- if ( APSME_LookupNwkAddr( ind->childExtAddr, &device.nwkAddr ) == TRUE )
- {
- device.parentAddr = NLME_GetShortAddr();
- device.extAddr = ind->childExtAddr;
- // remove device
- ZDSecMgrDeviceRemove( &device );
- }
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrRequestKeyInd
- *
- * @brief Process the ZDO_RequestKeyInd_t message.
- *
- * @param ind - [in] ZDO_RequestKeyInd_t indication
- *
- * @return none
- */
- void ZDSecMgrRequestKeyInd( ZDO_RequestKeyInd_t* ind )
- {
- if ( ind->keyType == KEY_TYPE_NWK )
- {
- }
- else if ( ind->keyType == KEY_TYPE_APP_MASTER )
- {
- ZDSecMgrAppKeyReq( ind );
- }
- else if ( ind->keyType == KEY_TYPE_TC_LINK )
- {
- }
- //else ignore
- }
- /******************************************************************************
- * @fn ZDSecMgrSwitchKeyInd
- *
- * @brief Process the ZDO_SwitchKeyInd_t message.
- *
- * @param ind - [in] ZDO_SwitchKeyInd_t indication
- *
- * @return none
- */
- void ZDSecMgrSwitchKeyInd( ZDO_SwitchKeyInd_t* ind )
- {
- SSP_SwitchNwkKey( ind->keySeqNum );
- // Save if nv
- ZDApp_NVUpdate();
- }
- /******************************************************************************
- * @fn ZDSecMgrAuthenticateInd
- *
- * @brief Process the ZDO_AuthenticateInd_t message.
- *
- * @param ind - [in] ZDO_AuthenticateInd_t indication
- *
- * @return none
- */
- void ZDSecMgrAuthenticateInd( ZDO_AuthenticateInd_t* ind )
- {
- APSME_AuthenticateReq_t req;
- AddrMgrEntry_t entry;
- // update the address manager
- //---------------------------------------------------------------------------
- // note:
- // required for EA processing, but ultimately EA logic could also use the
- // neighbor table to look up addresses -- also(IF using EA) the neighbor
- // table is supposed to have authentication states for neighbors
- //---------------------------------------------------------------------------
- entry.user = ADDRMGR_USER_SECURITY;
- entry.nwkAddr = ind->aps.initNwkAddr;
- AddrMgrExtAddrSet( entry.extAddr, ind->aps.initExtAddr );
- if ( AddrMgrEntryUpdate( &entry ) == TRUE )
- {
- // set request fields
- req.nwkAddr = ind->aps.initNwkAddr;
- req.extAddr = ind->aps.initExtAddr;
- req.action = APSME_EA_ACCEPT;
- req.challenge = ind->aps.challenge;
- // start EA processing
- APSME_AuthenticateReq( &req );
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrAuthenticateCfm
- *
- * @brief Process the ZDO_AuthenticateCfm_t message.
- *
- * @param cfm - [in] ZDO_AuthenticateCfm_t confirmation
- *
- * @return none
- */
- void ZDSecMgrAuthenticateCfm( ZDO_AuthenticateCfm_t* cfm )
- {
- if ( cfm->aps.status == ZSuccess )
- {
- if ( ( cfm->aps.initiator == TRUE ) && ( devState == DEV_END_DEVICE_UNAUTH ) )
- {
- // inform ZDO that device has been authenticated
- osal_set_event ( ZDAppTaskID, ZDO_DEVICE_AUTH );
- }
- }
- }
- #if ( ZG_BUILD_COORDINATOR_TYPE )
- /******************************************************************************
- * @fn ZDSecMgrUpdateNwkKey
- *
- * @brief Load a new NWK key and trigger a network wide update.
- *
- * @param key - [in] new NWK key
- * @param keySeqNum - [in] new NWK key sequence number
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrUpdateNwkKey( uint8* key, uint8 keySeqNum, uint16 dstAddr )
- {
- ZStatus_t status;
- APSME_TransportKeyReq_t req;
- // initialize common elements of local variables
- if ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_PRO_HIGH )
- {
- req.keyType = KEY_TYPE_NWK_HIGH;
- }
- else
- {
- req.keyType = KEY_TYPE_NWK;
- }
- req.dstAddr = dstAddr;
- req.keySeqNum = keySeqNum;
- req.key = key;
- req.extAddr = NULL;
- req.nwkSecure = TRUE;
- req.apsSecure = TRUE;
- req.tunnel = NULL;
- if (( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_PRO_HIGH ) ||
- ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_SE_STANDARD ))
- {
- ZDSecMgrEntry_t* entry;
- uint16 index;
- AddrMgrEntry_t addrEntry;
- addrEntry.user = ADDRMGR_USER_SECURITY;
- status = ZFailure;
- // verify data is available
- if ( ZDSecMgrEntries != NULL )
- {
- // find available entry
- for ( index = 0; index < ZDSECMGR_ENTRY_MAX ; index++ )
- {
- if ( ZDSecMgrEntries[index].ami != INVALID_NODE_ADDR )
- {
- // return successful result
- entry = &ZDSecMgrEntries[index];
- // get NWK address
- addrEntry.index = entry->ami;
- if ( AddrMgrEntryGet( &addrEntry ) == TRUE )
- {
- req.dstAddr = addrEntry.nwkAddr;
- req.extAddr = addrEntry.extAddr;
- status = APSME_TransportKeyReq( &req );
- }
- }
- }
- }
- }
- else // ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_RESIDENTIAL )
- {
- status = APSME_TransportKeyReq( &req );
- }
- SSP_UpdateNwkKey( key, keySeqNum );
- // Save if nv
- ZDApp_NVUpdate();
- return status;
- }
- #endif // ( ZG_BUILD_COORDINATOR_TYPE )
- #if ( ZG_BUILD_COORDINATOR_TYPE )
- /******************************************************************************
- * @fn ZDSecMgrSwitchNwkKey
- *
- * @brief Causes the NWK key to switch via a network wide command.
- *
- * @param keySeqNum - [in] new NWK key sequence number
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrSwitchNwkKey( uint8 keySeqNum, uint16 dstAddr )
- {
- ZStatus_t status;
- APSME_SwitchKeyReq_t req;
- // initialize common elements of local variables
- req.dstAddr = dstAddr;
- req.keySeqNum = keySeqNum;
- if (( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_PRO_HIGH ) ||
- ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_SE_STANDARD ))
- {
- ZDSecMgrEntry_t* entry;
- uint16 index;
- AddrMgrEntry_t addrEntry;
- addrEntry.user = ADDRMGR_USER_SECURITY;
- status = ZFailure;
- // verify data is available
- if ( ZDSecMgrEntries != NULL )
- {
- // find available entry
- for ( index = 0; index < ZDSECMGR_ENTRY_MAX ; index++ )
- {
- if ( ZDSecMgrEntries[index].ami != INVALID_NODE_ADDR )
- {
- // return successful result
- entry = &ZDSecMgrEntries[index];
- // get NWK address
- addrEntry.index = entry->ami;
- if ( AddrMgrEntryGet( &addrEntry ) == TRUE )
- {
- req.dstAddr = addrEntry.nwkAddr;
- status = APSME_SwitchKeyReq( &req );
- }
- }
- }
- }
- }
- else // ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_RESIDENTIAL )
- {
- status = APSME_SwitchKeyReq( &req );
- }
- SSP_SwitchNwkKey( keySeqNum );
- // Save if nv
- ZDApp_NVUpdate();
- return status;
- }
- #endif // ( ZG_BUILD_COORDINATOR_TYPE )
- /******************************************************************************
- * @fn ZDSecMgrRequestAppKey
- *
- * @brief Request an application key with partner.
- *
- * @param partExtAddr - [in] partner extended address
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrRequestAppKey( uint8 *partExtAddr )
- {
- ZStatus_t status;
- APSME_RequestKeyReq_t req;
- req.dstAddr = 0;
- req.keyType = KEY_TYPE_APP_MASTER;
- req.partExtAddr = partExtAddr;
- status = APSME_RequestKeyReq( &req );
- return status;
- }
- #if ( ZG_BUILD_JOINING_TYPE )
- /******************************************************************************
- * @fn ZDSecMgrSetupPartner
- *
- * @brief Setup for application key partner.
- *
- * @param partNwkAddr - [in] partner network address
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrSetupPartner( uint16 partNwkAddr, uint8* partExtAddr )
- {
- AddrMgrEntry_t entry;
- ZStatus_t status;
- status = ZFailure;
- // update the address manager
- entry.user = ADDRMGR_USER_SECURITY;
- entry.nwkAddr = partNwkAddr;
- AddrMgrExtAddrSet( entry.extAddr, partExtAddr );
- if ( AddrMgrEntryUpdate( &entry ) == TRUE )
- {
- status = ZSuccess;
- // check for address discovery
- if ( partNwkAddr == INVALID_NODE_ADDR )
- {
- status = ZDP_NwkAddrReq( partExtAddr, ZDP_ADDR_REQTYPE_SINGLE, 0, 0 );
- }
- else if ( !AddrMgrExtAddrValid( partExtAddr ) )
- {
- status = ZDP_IEEEAddrReq( partNwkAddr, ZDP_ADDR_REQTYPE_SINGLE, 0, 0 );
- }
- }
- return status;
- }
- #endif // ( ZG_BUILD_JOINING_TYPE )
- #if ( ZG_BUILD_COORDINATOR_TYPE )
- /******************************************************************************
- * @fn ZDSecMgrAppKeyTypeSet
- *
- * @brief Set application key type.
- *
- * @param keyType - [in] application key type (KEY_TYPE_APP_MASTER@2 or
- * KEY_TYPE_APP_LINK@3
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrAppKeyTypeSet( uint8 keyType )
- {
- if ( keyType == KEY_TYPE_APP_LINK )
- {
- ZDSecMgrAppKeyType = KEY_TYPE_APP_LINK;
- }
- else
- {
- ZDSecMgrAppKeyType = KEY_TYPE_APP_MASTER;
- }
- return ZSuccess;
- }
- #endif
- /******************************************************************************
- * ZigBee Device Security Manager - Stub Implementations
- */
- /******************************************************************************
- * @fn ZDSecMgrMasterKeyGet (stubs APSME_MasterKeyGet)
- *
- * @brief Get MASTER key for specified EXT address.
- *
- * @param extAddr - [in] EXT address
- * @param pKeyNvId - [out] MASTER key NV ID
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrMasterKeyGet( uint8* extAddr, uint16* pKeyNvId )
- {
- ZStatus_t status;
- uint16 ami;
- // lookup entry for specified EXT address
- status = ZDSecMgrExtAddrLookup( extAddr, &ami );
- if ( status == ZSuccess )
- {
- ZDSecMgrMasterKeyLookup( ami, pKeyNvId );
- }
- else
- {
- *pKeyNvId = SEC_NO_KEY_NV_ID;
- }
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrLinkKeySet (stubs APSME_LinkKeySet)
- *
- * @brief Set <APSME_LinkKeyData_t> for specified NWK address.
- *
- * @param extAddr - [in] EXT address
- * @param data - [in] APSME_LinkKeyData_t
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrLinkKeySet( uint8* extAddr, uint8* key )
- {
- ZStatus_t status;
- ZDSecMgrEntry_t* entry;
- APSME_LinkKeyData_t *pApsLinkKey = NULL;
- uint16 Index;
- // lookup entry index for specified EXT address
- status = ZDSecMgrEntryLookupExtGetIndex( extAddr, &entry, &Index );
- if ( status == ZSuccess )
- {
- // point to NV item
- entry->keyNvId = ZCD_NV_APS_LINK_KEY_DATA_START + Index;
- pApsLinkKey = (APSME_LinkKeyData_t *)osal_mem_alloc(sizeof(APSME_LinkKeyData_t));
- if (pApsLinkKey != NULL)
- {
- // read the key form NV, keyNvId must be ZCD_NV_APS_LINK_KEY_DATA_START based
- osal_nv_read( entry->keyNvId, 0,
- sizeof(APSME_LinkKeyData_t), pApsLinkKey );
- // set new values of the key
- osal_memcpy( pApsLinkKey->key, key, SEC_KEY_LEN );
- pApsLinkKey->rxFrmCntr = 0;
- pApsLinkKey->txFrmCntr = 0;
- osal_nv_write( entry->keyNvId, 0,
- sizeof(APSME_LinkKeyData_t), pApsLinkKey );
- // clear copy of key in RAM
- osal_memset(pApsLinkKey, 0x00, sizeof(APSME_LinkKeyData_t));
- osal_mem_free(pApsLinkKey);
- // set initial values for counters in RAM
- ApsLinkKeyFrmCntr[entry->keyNvId - ZCD_NV_APS_LINK_KEY_DATA_START].txFrmCntr = 0;
- ApsLinkKeyFrmCntr[entry->keyNvId - ZCD_NV_APS_LINK_KEY_DATA_START].rxFrmCntr = 0;
- }
- }
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrAuthenticationSet
- *
- * @brief Mark the specific device as authenticated or not
- *
- * @param extAddr - [in] EXT address
- * @param option - [in] authenticated or not
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrAuthenticationSet( uint8* extAddr, ZDSecMgr_Authentication_Option option )
- {
- ZStatus_t status;
- ZDSecMgrEntry_t* entry;
- // lookup entry index for specified EXT address
- status = ZDSecMgrEntryLookupExt( extAddr, &entry );
- if ( status == ZSuccess )
- {
- entry->authenticateOption = option;
- }
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrAuthenticationCheck
- *
- * @brief Check if the specific device has been authenticated or not
- * For non-trust center device, always return TRUE
- *
- * @param shortAddr - [in] short address
- *
- * @return TRUE @ authenticated with CBKE
- * FALSE @ not authenticated
- */
- uint8 ZDSecMgrAuthenticationCheck( uint16 shortAddr )
- {
- #if defined (TC_LINKKEY_JOIN)
- ZDSecMgrEntry_t* entry;
- uint8 extAddr[Z_EXTADDR_LEN];
- // If the local device is not the trust center, always return TRUE
- if ( NLME_GetShortAddr() != zgTrustCenterAddr )
- {
- return TRUE;
- }
- // Otherwise, check the authentication option
- else if ( AddrMgrExtAddrLookup( shortAddr, extAddr ) )
- {
- // lookup entry index for specified EXT address
- if ( ZDSecMgrEntryLookupExt( extAddr, &entry ) == ZSuccess )
- {
- if ( entry->authenticateOption != ZDSecMgr_Not_Authenticated )
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
- }
- }
- return FALSE;
- #else
- (void)shortAddr; // Intentionally unreferenced parameter
- // For non AMI/SE Profile, perform no check and always return TRUE.
- return TRUE;
- #endif // TC_LINKKEY_JOIN
- }
- /******************************************************************************
- * @fn ZDSecMgrLinkKeyNVIdGet (stubs APSME_LinkKeyNVIdGet)
- *
- * @brief Get Key NV ID for specified NWK address.
- *
- * @param extAddr - [in] EXT address
- * @param keyNvId - [out] NV ID
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrLinkKeyNVIdGet(uint8* extAddr, uint16 *pKeyNvId)
- {
- ZStatus_t status;
- ZDSecMgrEntry_t* entry;
- // lookup entry index for specified NWK address
- status = ZDSecMgrEntryLookupExt( extAddr, &entry );
- if ( status == ZSuccess )
- {
- // return the index to the NV table
- *pKeyNvId = entry->keyNvId;
- }
- else
- {
- *pKeyNvId = SEC_NO_KEY_NV_ID;
- }
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrIsLinkKeyValid (stubs APSME_IsLinkKeyValid)
- *
- * @brief Verifies if Link Key in NV has been set.
- *
- * @param extAddr - [in] EXT address
- *
- * @return TRUE - Link Key has been established
- * FALSE - Link Key in NV has default value.
- */
- uint8 ZDSecMgrIsLinkKeyValid(uint8* extAddr)
- {
- APSME_LinkKeyData_t *pKeyData;
- uint16 apsLinkKeyNvId;
- uint8 nullKey[SEC_KEY_LEN];
- uint8 status = FALSE;
- // initialize default vealue to compare to
- osal_memset(nullKey, 0x00, SEC_KEY_LEN);
- // check for APS link NV ID
- APSME_LinkKeyNVIdGet( extAddr, &apsLinkKeyNvId );
- if (apsLinkKeyNvId != SEC_NO_KEY_NV_ID )
- {
- pKeyData = (APSME_LinkKeyData_t *)osal_mem_alloc(sizeof(APSME_LinkKeyData_t));
- if (pKeyData != NULL)
- {
- // retrieve key from NV
- if ( osal_nv_read( apsLinkKeyNvId, 0,
- sizeof(APSME_LinkKeyData_t), pKeyData) == ZSUCCESS)
- {
- // if stored key is different than default value, then a key has been established
- if (!osal_memcmp(pKeyData, nullKey, SEC_KEY_LEN))
- {
- status = TRUE;
- }
- }
- // clear copy of key in RAM
- osal_memset(pKeyData, 0x00, sizeof(APSME_LinkKeyData_t));
- osal_mem_free(pKeyData);
- }
- }
- return status;
- }
- /******************************************************************************
- * @fn ZDSecMgrKeyFwdToChild (stubs APSME_KeyFwdToChild)
- *
- * @brief Verify and process key transportation to child.
- *
- * @param ind - [in] APSME_TransportKeyInd_t
- *
- * @return uint8 - success(TRUE:FALSE)
- */
- uint8 ZDSecMgrKeyFwdToChild( APSME_TransportKeyInd_t* ind )
- {
- // verify from Trust Center
- if ( ind->srcAddr == APSME_TRUSTCENTER_NWKADDR )
- {
- // check for initial NWK key
- if ( ( ind->keyType == KEY_TYPE_NWK ) ||
- ( ind->keyType == 6 ) ||
- ( ind->keyType == KEY_TYPE_NWK_HIGH ) )
- {
- // set association status to authenticated
- ZDSecMgrAssocDeviceAuth( AssocGetWithExt( ind->dstExtAddr ) );
- }
- return TRUE;
- }
- return FALSE;
- }
- /******************************************************************************
- * @fn ZDSecMgrAddLinkKey
- *
- * @brief Add the application link key to ZDSecMgr. Also mark the device
- * as authenticated in the authenticateOption. Note that this function
- * is hardwared to CBKE right now.
- *
- * @param shortAddr - short address of the partner device
- * @param extAddr - extended address of the partner device
- * @param key - link key
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrAddLinkKey( uint16 shortAddr, uint8 *extAddr, uint8 *key)
- {
- uint16 ami;
- ZDSecMgrEntry_t* entry;
- /* Store the device address in the addr manager */
- if( ZDSecMgrAddrStore( shortAddr, extAddr, &ami ) != ZSuccess )
- {
- /* Adding to Addr Manager fails */
- return ZFailure;
- }
- /* Lookup entry using specified address index */
- ZDSecMgrEntryLookupAMI( ami, &entry );
- // If no existing entry, create one
- if ( entry == NULL )
- {
- if ( ZDSecMgrEntryNew( &entry ) == ZSuccess )
- {
- entry->ami = ami;
- }
- else
- {
- /* Security Manager full */
- return ZBufferFull;
- }
- }
- // Write the link key
- APSME_LinkKeySet( extAddr, key );
- #if defined (TC_LINKKEY_JOIN)
- // Mark the device as authenticated.
- ZDSecMgrAuthenticationSet( extAddr, ZDSecMgr_Authenticated_CBCK );
- #endif
- #if defined NV_RESTORE
- ZDSecMgrWriteNV(); // Write the new established link key to NV.
- #endif
- return ZSuccess;
- }
- #if defined ( NV_RESTORE )
- /******************************************************************************
- * @fn ZDSecMgrInitNV
- *
- * @brief Initialize the SecMgr entry data in NV with all values set to 0
- *
- * @param none
- *
- * @return uint8 - <osal_nv_item_init> return codes
- */
- uint8 ZDSecMgrInitNV(void)
- {
- uint8 rtrn = osal_nv_item_init(ZCD_NV_APS_LINK_KEY_TABLE,
- (sizeof(nvDeviceListHdr_t) + (sizeof(ZDSecMgrEntry_t) * ZDSECMGR_ENTRY_MAX)), NULL);
- // If the item does not already exist, set all values to 0
- if (rtrn != SUCCESS)
- {
- nvDeviceListHdr_t hdr;
- hdr.numRecs = 0;
- osal_nv_write(ZCD_NV_APS_LINK_KEY_TABLE, 0, sizeof(nvDeviceListHdr_t), &hdr);
- }
- return rtrn;
- }
- #endif // NV_RESTORE
- #if defined ( NV_RESTORE )
- /*********************************************************************
- * @fn ZDSecMgrWriteNV()
- *
- * @brief Save off the APS link key list to NV
- *
- * @param none
- *
- * @return none
- */
- static void ZDSecMgrWriteNV( void )
- {
- uint16 i;
- nvDeviceListHdr_t hdr;
- hdr.numRecs = 0;
- if (ZDSecMgrEntries != NULL)
- {
- for ( i = 0; i < ZDSECMGR_ENTRY_MAX; i++ )
- {
- // Save off the record
- osal_nv_write( ZCD_NV_APS_LINK_KEY_TABLE,
- (uint16)((sizeof(nvDeviceListHdr_t)) + (i * sizeof(ZDSecMgrEntry_t))),
- sizeof(ZDSecMgrEntry_t), &ZDSecMgrEntries[i] );
- if ( ZDSecMgrEntries[i].ami != INVALID_NODE_ADDR )
- {
- hdr.numRecs++;
- }
- }
- }
- // Save off the header
- osal_nv_write( ZCD_NV_APS_LINK_KEY_TABLE, 0, sizeof( nvDeviceListHdr_t ), &hdr );
- }
- #endif // NV_RESTORE
- #if defined ( NV_RESTORE )
- /******************************************************************************
- * @fn ZDSecMgrRestoreFromNV
- *
- * @brief Restore the APS Link Key entry data from NV. It does not restore
- * the key data itself as they remain in NV until they are used.
- * Only list data is restored.
- *
- * @param none
- *
- * @return None.
- */
- static void ZDSecMgrRestoreFromNV( void )
- {
- nvDeviceListHdr_t hdr;
- APSME_LinkKeyData_t *pApsLinkKey = NULL;
- if ((osal_nv_read(ZCD_NV_APS_LINK_KEY_TABLE, 0, sizeof(nvDeviceListHdr_t), &hdr) == ZSUCCESS) &&
- ((hdr.numRecs > 0) && (hdr.numRecs <= ZDSECMGR_ENTRY_MAX)))
- {
- uint8 x;
- pApsLinkKey = (APSME_LinkKeyData_t *)osal_mem_alloc(sizeof(APSME_LinkKeyData_t));
- for (x = 0; x < ZDSECMGR_ENTRY_MAX; x++)
- {
- if ( osal_nv_read( ZCD_NV_APS_LINK_KEY_TABLE,
- (uint16)(sizeof(nvDeviceListHdr_t) + (x * sizeof(ZDSecMgrEntry_t))),
- sizeof(ZDSecMgrEntry_t), &ZDSecMgrEntries[x] ) == SUCCESS )
- {
- // update data only for valid entries
- if ( ZDSecMgrEntries[x].ami != INVALID_NODE_ADDR )
- {
- if (pApsLinkKey != NULL)
- {
- // read the key form NV, keyNvId must be ZCD_NV_APS_LINK_KEY_DATA_START based
- osal_nv_read( ZDSecMgrEntries[x].keyNvId, 0,
- sizeof(APSME_LinkKeyData_t), pApsLinkKey );
- // set new values for the counter
- pApsLinkKey->txFrmCntr += ( MAX_APS_FRAMECOUNTER_CHANGES + 1 );
- // restore values for counters in RAM
- ApsLinkKeyFrmCntr[ZDSecMgrEntries[x].keyNvId - ZCD_NV_APS_LINK_KEY_DATA_START].txFrmCntr =
- pApsLinkKey->txFrmCntr;
- ApsLinkKeyFrmCntr[ZDSecMgrEntries[x].keyNvId - ZCD_NV_APS_LINK_KEY_DATA_START].rxFrmCntr =
- pApsLinkKey->rxFrmCntr;
- osal_nv_write( ZDSecMgrEntries[x].keyNvId, 0,
- sizeof(APSME_LinkKeyData_t), pApsLinkKey );
- // clear copy of key in RAM
- osal_memset(pApsLinkKey, 0x00, sizeof(APSME_LinkKeyData_t));
- }
- }
- }
- }
- if (pApsLinkKey != NULL)
- {
- osal_mem_free(pApsLinkKey);
- }
- }
- }
- #endif // NV_RESTORE
- /*********************************************************************
- * @fn ZDSecMgrSetDefaultNV
- *
- * @brief Write the defaults to NV for Entry table and for APS key data table
- *
- * @param none
- *
- * @return none
- */
- void ZDSecMgrSetDefaultNV( void )
- {
- uint16 i;
- nvDeviceListHdr_t hdr;
- ZDSecMgrEntry_t secMgrEntry;
- APSME_LinkKeyData_t *pApsLinkKey = NULL;
- // Initialize the header
- hdr.numRecs = 0;
- // clear the header
- osal_nv_write(ZCD_NV_APS_LINK_KEY_TABLE, 0, sizeof(nvDeviceListHdr_t), &hdr);
- osal_memset( &secMgrEntry, 0x00, sizeof(ZDSecMgrEntry_t) );
- for ( i = 0; i < ZDSECMGR_ENTRY_MAX; i++ )
- {
- // Clear the record
- osal_nv_write( ZCD_NV_APS_LINK_KEY_TABLE,
- (uint16)((sizeof(nvDeviceListHdr_t)) + (i * sizeof(ZDSecMgrEntry_t))),
- sizeof(ZDSecMgrEntry_t), &secMgrEntry );
- }
- pApsLinkKey = (APSME_LinkKeyData_t *)osal_mem_alloc(sizeof(APSME_LinkKeyData_t));
- if (pApsLinkKey != NULL)
- {
- osal_memset( pApsLinkKey, 0x00, sizeof(APSME_LinkKeyData_t) );
- for ( i = 0; i < ZDSECMGR_ENTRY_MAX; i++ )
- {
- // Clear the record
- osal_nv_write( (ZCD_NV_APS_LINK_KEY_DATA_START + i), 0,
- sizeof(APSME_LinkKeyData_t), pApsLinkKey);
- }
- osal_mem_free(pApsLinkKey);
- }
- }
- #if defined ( NV_RESTORE )
- /*********************************************************************
- * @fn ZDSecMgrUpdateNV()
- *
- * @brief Updates one entry of the APS link key table to NV
- *
- * @param index - to the entry in security manager table
- *
- * @return none
- */
- static void ZDSecMgrUpdateNV( uint16 index )
- {
- nvDeviceListHdr_t hdr;
- if (ZDSecMgrEntries != NULL)
- {
- // Save off the record
- osal_nv_write( ZCD_NV_APS_LINK_KEY_TABLE,
- (uint16)((sizeof(nvDeviceListHdr_t)) + (index * sizeof(ZDSecMgrEntry_t))),
- sizeof(ZDSecMgrEntry_t), &ZDSecMgrEntries[index] );
- }
- if (osal_nv_read(ZCD_NV_APS_LINK_KEY_TABLE, 0, sizeof(nvDeviceListHdr_t), &hdr) == ZSUCCESS)
- {
- if ( ZDSecMgrEntries[index].ami == INVALID_NODE_ADDR )
- {
- if (hdr.numRecs > 0)
- {
- hdr.numRecs--;
- }
- }
- else
- {
- hdr.numRecs++;
- }
- // Save off the header
- osal_nv_write( ZCD_NV_APS_LINK_KEY_TABLE, 0, sizeof( nvDeviceListHdr_t ), &hdr );
- }
- }
- #endif // NV_RESTORE
- /******************************************************************************
- * @fn ZDSecMgrAPSRemove
- *
- * @brief Remove device from network.
- *
- * @param nwkAddr - device's NWK address
- * @param extAddr - device's Extended address
- * @param parentAddr - parent's NWK address
- *
- * @return ZStatus_t
- */
- ZStatus_t ZDSecMgrAPSRemove( uint16 nwkAddr, uint8 *extAddr, uint16 parentAddr )
- {
- ZDSecMgrDevice_t device;
- if ( ( nwkAddr == INVALID_NODE_ADDR ) ||
- ( extAddr == NULL ) ||
- ( parentAddr == INVALID_NODE_ADDR ) )
- {
- return ( ZFailure );
- }
- device.nwkAddr = nwkAddr;
- device.extAddr = extAddr;
- device.parentAddr = parentAddr;
- // remove device
- ZDSecMgrDeviceRemove( &device );
- return ( ZSuccess );
- }
- /******************************************************************************
- * @fn APSME_TCLinkKeyInit
- *
- * @brief Initialize the NV table for preconfigured TC link key
- *
- * When zgUseDefaultTCL is set to TRUE, the default preconfig
- * Trust Center Link Key is written to NV. A single tclk is used
- * by all devices joining the network.
- *
- * @param setDefault - TRUE to set default values
- *
- * @return none
- */
- void APSME_TCLinkKeyInit(uint8 setDefault)
- {
- uint8 i;
- APSME_TCLinkKey_t tcLinkKey;
- uint8 rtrn;
- // Initialize all NV items for preconfigured TCLK
- for( i = 0; i < ZDSECMGR_TC_DEVICE_MAX; i++ )
- {
- // Making sure data is cleared for every key all the time
- osal_memset( &tcLinkKey, 0x00, sizeof(APSME_TCLinkKey_t) );
- // Initialize first element of the table with the default TCLK
- if((i == 0) && ( zgUseDefaultTCLK == TRUE ))
- {
- osal_memset( tcLinkKey.extAddr, 0xFF, Z_EXTADDR_LEN );
- osal_memcpy( tcLinkKey.key, defaultTCLinkKey, SEC_KEY_LEN);
- }
- // If the item doesn't exist in NV memory, create and initialize
- // it with the default value passed in, either defaultTCLK or 0
- rtrn = osal_nv_item_init( (ZCD_NV_TCLK_TABLE_START + i),
- sizeof(APSME_TCLinkKey_t), &tcLinkKey);
- if (rtrn == SUCCESS)
- {
- // set the Frame counters to 0 to existing keys in NV
- osal_nv_read( ( ZCD_NV_TCLK_TABLE_START + i), 0,
- sizeof(APSME_TCLinkKey_t), &tcLinkKey );
- #if defined ( NV_RESTORE )
- if (setDefault == TRUE)
- {
- // clear the value stored in NV
- tcLinkKey.txFrmCntr = 0;
- }
- else
- {
- // increase the value stored in NV
- tcLinkKey.txFrmCntr += ( MAX_TCLK_FRAMECOUNTER_CHANGES + 1 );
- }
- #else
- // Clear the counters if NV_RESTORE is not enabled and this NV item
- // already existed in the NV memory
- tcLinkKey.txFrmCntr = 0;
- tcLinkKey.rxFrmCntr = 0;
- #endif // NV_RESTORE
- osal_nv_write( ( ZCD_NV_TCLK_TABLE_START + i), 0,
- sizeof(APSME_TCLinkKey_t), &tcLinkKey );
- // set initial values for counters in RAM
- TCLinkKeyFrmCntr[i].txFrmCntr = tcLinkKey.txFrmCntr;
- TCLinkKeyFrmCntr[i].rxFrmCntr = tcLinkKey.rxFrmCntr;
- }
- }
- // clear copy of key in RAM
- osal_memset( &tcLinkKey, 0x00, sizeof(APSME_TCLinkKey_t) );
- }
- /******************************************************************************
- * @fn APSME_TCLinkKeySync
- *
- * @brief Sync Trust Center LINK key data.
- *
- * @param srcAddr - [in] srcAddr
- * @param si - [in, out] SSP_Info_t
- *
- * @return ZStatus_t
- */
- ZStatus_t APSME_TCLinkKeySync( uint16 srcAddr, SSP_Info_t* si )
- {
- uint8 i;
- ZStatus_t status = ZSecNoKey;
- APSME_TCLinkKey_t tcLinkKey;
- uint32 *tclkRxFrmCntr;
- // Look up the IEEE address of the trust center if it's available
- if ( AddrMgrExtAddrValid( si->extAddr ) == FALSE )
- {
- APSME_LookupExtAddr( srcAddr, si->extAddr );
- }
- // Look up the TC link key associated with the device
- // or the default TC link key (extAddr is all FFs), whichever is found
- for( i = 0; i < ZDSECMGR_TC_DEVICE_MAX; i++ )
- {
- // Read entry i of the TC link key table from NV
- osal_nv_read( (ZCD_NV_TCLK_TABLE_START + i), 0,
- sizeof(APSME_TCLinkKey_t), &tcLinkKey );
- if( AddrMgrExtAddrEqual(si->extAddr, tcLinkKey.extAddr) ||
- APSME_IsDefaultTCLK(tcLinkKey.extAddr))
- {
- tclkRxFrmCntr = &TCLinkKeyFrmCntr[i].rxFrmCntr;
- // verify that the incoming frame counter is valid
- if ( si->frmCntr >= *tclkRxFrmCntr )
- {
- // set the keyNvId to use
- si->keyNvId = (ZCD_NV_TCLK_TABLE_START + i);
- // update the rx frame counter
- *tclkRxFrmCntr = si->frmCntr + 1;
- status = ZSuccess;
- }
- else
- {
- status = ZSecOldFrmCount;
- }
- // break from the loop
- break;
- }
- }
- // clear copy of key in RAM
- osal_memset( &tcLinkKey, 0x00, sizeof(APSME_TCLinkKey_t) );
- return status;
- }
- /******************************************************************************
- * @fn APSME_TCLinkKeyLoad
- *
- * @brief Load Trust Center LINK key data.
- *
- * @param dstAddr - [in] dstAddr
- * @param si - [in, out] SSP_Info_t
- *
- * @return ZStatus_t
- */
- ZStatus_t APSME_TCLinkKeyLoad( uint16 dstAddr, SSP_Info_t* si )
- {
- uint8 i;
- ZStatus_t status = ZSecNoKey;
- APSME_TCLinkKey_t tcLinkKey;
- AddrMgrEntry_t addrEntry;
- uint32 *tclkTxFrmCntr;
- uint8 extAddrFound;
- uint8 defaultTCLKIdx = ZDSECMGR_TC_DEVICE_MAX;
- // Look up the ami of the srcAddr if available
- addrEntry.user = ADDRMGR_USER_DEFAULT;
- addrEntry.nwkAddr = dstAddr;
- APSME_LookupExtAddr( dstAddr, si->extAddr );
- extAddrFound = AddrMgrExtAddrValid( si->extAddr );
- // Look up the TC link key associated with the device
- // or the master TC link key (ami = 0xFFFF), whichever is found
- for( i = 0; i < ZDSECMGR_TC_DEVICE_MAX; i++ )
- {
- // Read entry i of the TC link key table from NV
- osal_nv_read( (ZCD_NV_TCLK_TABLE_START + i), 0,
- sizeof(APSME_TCLinkKey_t), &tcLinkKey );
- if( extAddrFound && AddrMgrExtAddrEqual(si->extAddr, tcLinkKey.extAddr) )
- {
- status = ZSuccess;
- break; // break from the loop
- }
- if ( APSME_IsDefaultTCLK(tcLinkKey.extAddr) )
- {
- if ( !extAddrFound )
- {
- status = ZSuccess;
- break; // break from the loop
- }
- // Remember the default TCLK index
- defaultTCLKIdx = i;
- }
- }
- if ( (status != ZSuccess) && (defaultTCLKIdx < ZDSECMGR_TC_DEVICE_MAX) )
- {
- // Exact match was not found; use the default TC Link Key
- i = defaultTCLKIdx;
- status = ZSuccess;
- }
- if ( status == ZSuccess )
- {
- tclkTxFrmCntr = &TCLinkKeyFrmCntr[i].txFrmCntr;
- // set the keyNvId to use
- si->keyNvId = (ZCD_NV_TCLK_TABLE_START + i);
- // update link key related fields
- si->keyID = SEC_KEYID_LINK;
- si->frmCntr = *tclkTxFrmCntr;
- // update outgoing frame counter
- (*tclkTxFrmCntr)++;
- #if defined ( NV_RESTORE )
- // write periodically to NV
- if ( !(*tclkTxFrmCntr % MAX_TCLK_FRAMECOUNTER_CHANGES) )
- {
- // set the flag to write key to NV
- TCLinkKeyFrmCntr[i].pendingFlag = TRUE;
- // Notify the ZDApp that the frame counter has changed.
- osal_set_event( ZDAppTaskID, ZDO_TCLK_FRAMECOUNTER_CHANGE );
- }
- #endif
- }
- // If no TC link key found, remove the device from the address manager
- if ( (status != ZSuccess) && (AddrMgrEntryLookupNwk(&addrEntry) == TRUE) )
- {
- AddrMgrEntryRelease( &addrEntry );
- }
- // clear copy of key in RAM
- osal_memset( &tcLinkKey, 0x00, sizeof(APSME_TCLinkKey_t) );
- return status;
- }
- /******************************************************************************
- * @fn APSME_IsDefaultTCLK
- *
- * @brief Return TRUE or FALSE based on the extended address. If the
- * input ext address is all FFs, it means the trust center link
- * assoiciated with the address is the default trust center link key
- *
- * @param extAddr - [in] extended address
- *
- * @return uint8 TRUE/FALSE
- */
- uint8 APSME_IsDefaultTCLK( uint8 *extAddr )
- {
- uint8 i = 0;
- if( extAddr == NULL )
- {
- return FALSE;
- }
- while( i++ < Z_EXTADDR_LEN )
- {
- if( *extAddr++ != 0xFF )
- {
- return FALSE;
- }
- }
- return TRUE;
- }
- /******************************************************************************
- * @fn ZDSecMgrNwkKeyInit
- *
- * @brief Initialize the NV items for
- * ZCD_NV_NWKKEY,
- * ZCD_NV_NWK_ACTIVE_KEY_INFO and
- * ZCD_NV_NWK_ALTERN_KEY_INFO
- *
- * @param setDefault
- *
- * @return none
- */
- void ZDSecMgrNwkKeyInit(uint8 setDefault)
- {
- uint8 status;
- nwkKeyDesc nwkKey;
- // Initialize NV items for NWK key, this structure contains the frame counter
- // and is only used when NV_RESTORE is enabled
- nwkActiveKeyItems keyItems;
- osal_memset( &keyItems, 0, sizeof( nwkActiveKeyItems ) );
- status = osal_nv_item_init( ZCD_NV_NWKKEY, sizeof(nwkActiveKeyItems), (void *)&keyItems );
- #if defined ( NV_RESTORE )
- // reset the values of NV items if NV_RESTORE is not enabled
- if ((status == SUCCESS) && (setDefault == TRUE))
- {
- // clear NV data to default values
- osal_nv_write( ZCD_NV_NWKKEY, 0, sizeof(nwkActiveKeyItems), &keyItems );
- }
- #else
- (void)setDefault; // to eliminate compiler warning
- // reset the values of NV items if NV_RESTORE is not enabled
- if (status == SUCCESS)
- {
- osal_nv_write( ZCD_NV_NWKKEY, 0, sizeof(nwkActiveKeyItems), &keyItems );
- }
- #endif // defined (NV_RESTORE)
- // Initialize NV items for NWK Active and Alternate keys. These items are used
- // all the time, independently of NV_RESTORE being set or not
- osal_memset( &nwkKey, 0x00, sizeof(nwkKey) );
- status = osal_nv_item_init( ZCD_NV_NWK_ACTIVE_KEY_INFO, sizeof(nwkKey), &nwkKey);
- #if defined ( NV_RESTORE )
- // reset the values of NV items if NV_RESTORE is not enabled
- if ((status == SUCCESS) && (setDefault == TRUE))
- {
- // clear NV data to default values
- osal_nv_write( ZCD_NV_NWK_ACTIVE_KEY_INFO, 0, sizeof(nwkKey), &nwkKey );
- }
- #else
- // reset the values of NV items if NV_RESTORE is not enabled
- if (status == SUCCESS)
- {
- osal_nv_write( ZCD_NV_NWK_ACTIVE_KEY_INFO, 0, sizeof(nwkKey), &nwkKey );
- }
- #endif // defined (NV_RESTORE)
- status = osal_nv_item_init( ZCD_NV_NWK_ALTERN_KEY_INFO, sizeof(nwkKey), &nwkKey );
- #if defined ( NV_RESTORE )
- // reset the values of NV items if NV_RESTORE is not enabled
- if ((status == SUCCESS) && (setDefault == TRUE))
- {
- // clear NV data to default values
- osal_nv_write( ZCD_NV_NWK_ALTERN_KEY_INFO, 0, sizeof(nwkKey), &nwkKey );
- }
- #else
- // reset the values of NV items if NV_RESTORE is not enabled
- if (status == SUCCESS)
- {
- osal_nv_write( ZCD_NV_NWK_ALTERN_KEY_INFO, 0, sizeof(nwkKey), &nwkKey );
- }
- #endif // defined (NV_RESTORE)
- }
- /*********************************************************************
- * @fn ZDSecMgrReadKeyFromNv
- *
- * @brief Looks for a specific key in NV based on Index value
- *
- * @param keyNvId - Index of key to look in NV
- * valid values are:
- * ZCD_NV_NWK_ACTIVE_KEY_INFO
- * ZCD_NV_NWK_ALTERN_KEY_INFO
- * ZCD_NV_TCLK_TABLE_START + <offset_in_table>
- * ZCD_NV_APS_LINK_KEY_DATA_START + <offset_in_table>
- * ZCD_NV_MASTER_KEY_DATA_START + <offset_in_table>
- * ZCD_NV_PRECFGKEY
- *
- * @param *keyinfo - Data is read into this buffer.
- *
- * @return SUCCESS if NV data was copied to the keyinfo parameter .
- * Otherwise, NV_OPER_FAILED for failure.
- */
- ZStatus_t ZDSecMgrReadKeyFromNv(uint16 keyNvId, void *keyinfo)
- {
- if ((keyNvId == ZCD_NV_NWK_ACTIVE_KEY_INFO) ||
- (keyNvId == ZCD_NV_NWK_ALTERN_KEY_INFO))
- {
- // get NWK active or alternate key from NV
- return (osal_nv_read(keyNvId,
- osal_offsetof(nwkKeyDesc, key),
- SEC_KEY_LEN,
- keyinfo));
- }
- else if ((keyNvId >= ZCD_NV_TCLK_TABLE_START) &&
- (keyNvId < (ZCD_NV_TCLK_TABLE_START + ZDSECMGR_TC_DEVICE_MAX)))
- {
- // Read entry keyNvId of the TC link key table from NV. keyNvId should be
- // ZCD_NV_TCLK_TABLE_START + <offset_in_table>
- return (osal_nv_read(keyNvId,
- osal_offsetof(APSME_TCLinkKey_t, key),
- SEC_KEY_LEN,
- keyinfo));
- }
- else if ((keyNvId >= ZCD_NV_APS_LINK_KEY_DATA_START) &&
- (keyNvId < (ZCD_NV_APS_LINK_KEY_DATA_START + ZDSECMGR_ENTRY_MAX)))
- {
- // Read entry keyNvId of the APS link key table from NV. keyNvId should be
- // ZCD_NV_APS_LINK_KEY_DATA_START + <offset_in_table>
- return (osal_nv_read(keyNvId,
- osal_offsetof(APSME_LinkKeyData_t, key),
- SEC_KEY_LEN,
- keyinfo));
- }
- else if ((keyNvId >= ZCD_NV_MASTER_KEY_DATA_START) &&
- (keyNvId < (ZCD_NV_MASTER_KEY_DATA_START + ZDSECMGR_MASTERKEY_MAX)))
- {
- // Read entry keyNvId of the MASTER key table from NV. keyNvId should be
- // ZCD_NV_MASTER_KEY_DATA_START + <offset_in_table>
- return (osal_nv_read(keyNvId,
- osal_offsetof(ZDSecMgrMasterKeyData_t, key),
- SEC_KEY_LEN,
- keyinfo));
- }
- else if (keyNvId == ZCD_NV_PRECFGKEY)
- {
- // Read entry keyNvId of the Preconfig key from NV.
- return (osal_nv_read(keyNvId,
- 0,
- SEC_KEY_LEN,
- keyinfo));
- }
- return NV_OPER_FAILED;
- }
- /******************************************************************************
- * @fn ZDSecMgrApsLinkKeyInit
- *
- * @brief Initialize the NV table for Application link keys
- *
- * @param none
- *
- * @return none
- */
- void ZDSecMgrApsLinkKeyInit(void)
- {
- APSME_LinkKeyData_t pApsLinkKey;
- uint8 i;
- uint8 status;
- // Initialize all NV items for APS link key, if not exist already.
- osal_memset( &pApsLinkKey, 0x00, sizeof(APSME_LinkKeyData_t) );
- for( i = 0; i < ZDSECMGR_ENTRY_MAX; i++ )
- {
- status = osal_nv_item_init( (ZCD_NV_APS_LINK_KEY_DATA_START + i),
- sizeof(APSME_LinkKeyData_t), &pApsLinkKey );
- #if defined ( NV_RESTORE )
- (void)status; // to eliminate compiler warning
- #else
- // reset the values of NV items if NV_RESTORE is not enabled
- if (status == SUCCESS)
- {
- osal_nv_write( (ZCD_NV_APS_LINK_KEY_DATA_START + i), 0,
- sizeof(APSME_LinkKeyData_t), &pApsLinkKey );
- }
- #endif // defined (NV_RESTORE)
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrInitNVKeyTables
- *
- * @brief Initialize the NV table for All keys: NWK, Master, TCLK and APS
- *
- * @param setDefault - TRUE to set default values
- *
- * @return none
- */
- void ZDSecMgrInitNVKeyTables(uint8 setDefault)
- {
- ZDSecMgrNwkKeyInit(setDefault);
- ZDSecMgrMasterKeyInit();
- ZDSecMgrApsLinkKeyInit();
- APSME_TCLinkKeyInit(setDefault);
- }
- /******************************************************************************
- * @fn ZDSecMgrSaveApsLinkKey
- *
- * @brief Save APS Link Key to NV. It will loop through all the keys
- * to see which one to save.
- *
- * @param none
- *
- * @return none
- */
- void ZDSecMgrSaveApsLinkKey(void)
- {
- APSME_LinkKeyData_t *pKeyData = NULL;
- int i;
- pKeyData = (APSME_LinkKeyData_t *)osal_mem_alloc(sizeof(APSME_LinkKeyData_t));
- if (pKeyData != NULL)
- {
- // checks all pending flags to know which one to save
- for (i = 0; i < ZDSECMGR_ENTRY_MAX; i++)
- {
- if (ApsLinkKeyFrmCntr[i].pendingFlag == TRUE)
- {
- // retrieve key from NV
- if (osal_nv_read(ZCD_NV_APS_LINK_KEY_DATA_START + i, 0,
- sizeof(APSME_LinkKeyData_t), pKeyData) == SUCCESS)
- {
- pKeyData->txFrmCntr = ApsLinkKeyFrmCntr[i].txFrmCntr;
- pKeyData->rxFrmCntr = ApsLinkKeyFrmCntr[i].rxFrmCntr;
- // Write the APS link key back to the NV
- osal_nv_write(ZCD_NV_APS_LINK_KEY_DATA_START + i, 0,
- sizeof(APSME_LinkKeyData_t), pKeyData);
- // clear the pending write flag
- ApsLinkKeyFrmCntr[i].pendingFlag = FALSE;
- }
- }
- }
- // clear copy of key in RAM
- osal_memset( pKeyData, 0x00, sizeof(APSME_LinkKeyData_t) );
- osal_mem_free(pKeyData);
- }
- }
- /******************************************************************************
- * @fn ZDSecMgrSaveTCLinkKey
- *
- * @brief Save TC Link Key to NV. It will loop through all the keys
- * to see which one to save.
- *
- * @param none
- *
- * @return none
- */
- void ZDSecMgrSaveTCLinkKey(void)
- {
- APSME_TCLinkKey_t *pKeyData = NULL;
- uint16 i;
- pKeyData = (APSME_TCLinkKey_t *)osal_mem_alloc(sizeof(APSME_TCLinkKey_t));
- if (pKeyData != NULL)
- {
- for( i = 0; i < ZDSECMGR_TC_DEVICE_MAX; i++ )
- {
- if (TCLinkKeyFrmCntr[i].pendingFlag == TRUE)
- {
- if (osal_nv_read(ZCD_NV_TCLK_TABLE_START + i, 0,
- sizeof(APSME_TCLinkKey_t), pKeyData) == SUCCESS)
- {
- pKeyData->txFrmCntr = TCLinkKeyFrmCntr[i].txFrmCntr;
- pKeyData->rxFrmCntr = TCLinkKeyFrmCntr[i].rxFrmCntr;
- // Write the TC link key back to the NV
- osal_nv_write(ZCD_NV_TCLK_TABLE_START + i, 0,
- sizeof(APSME_TCLinkKey_t), pKeyData);
- // clear the pending write flag
- TCLinkKeyFrmCntr[i].pendingFlag = FALSE;
- }
- }
- }
- // clear copy of key in RAM
- osal_memset( pKeyData, 0x00, sizeof(APSME_TCLinkKey_t) );
- osal_mem_free(pKeyData);
- }
- }
- #if defined ( ZBA_FALLBACK_NWKKEY )
- /******************************************************************************
- * @fn ZDSecMgrFallbackNwkKey
- *
- * @brief Use the ZBA fallback network key.
- *
- * @param none
- *
- * @return none
- */
- void ZDSecMgrFallbackNwkKey( void )
- {
- if ( !_NIB.nwkKeyLoaded )
- {
- uint8 fallbackKey[SEC_KEY_LEN];
- ZDSecMgrReadKeyFromNv( ZCD_NV_PRECFGKEY, fallbackKey );
- SSP_UpdateNwkKey( fallbackKey, 0);
- SSP_SwitchNwkKey( 0 );
- // clear local copy of key
- osal_memset( fallbackKey, 0x00, SEC_KEY_LEN );
- // handle next step in authentication process
- ZDSecMgrAuthNwkKey();
- }
- }
- #endif // defined ( ZBA_FALLBACK_NWKKEY )
- #if defined ( NV_RESTORE )
- /******************************************************************************
- * @fn ZDSecMgrClearNVKeyValues
- *
- * @brief If NV_RESTORE is enabled and the status of the network needs
- * default values this fuction clears ZCD_NV_NWKKEY,
- * ZCD_NV_NWK_ACTIVE_KEY_INFO and ZCD_NV_NWK_ALTERN_KEY_INFO link
- *
- * @param none
- *
- * @return none
- */
- void ZDSecMgrClearNVKeyValues(void)
- {
- nwkActiveKeyItems keyItems;
- nwkKeyDesc nwkKey;
- osal_memset(&keyItems, 0x00, sizeof(nwkActiveKeyItems));
- osal_nv_write(ZCD_NV_NWKKEY, 0, sizeof(nwkActiveKeyItems), &keyItems);
- // Initialize NV items for NWK Active and Alternate keys.
- osal_memset( &nwkKey, 0x00, sizeof(nwkKeyDesc) );
- osal_nv_write(ZCD_NV_NWK_ACTIVE_KEY_INFO, 0, sizeof(nwkKeyDesc), &nwkKey);
- osal_nv_write(ZCD_NV_NWK_ALTERN_KEY_INFO, 0, sizeof(nwkKeyDesc), &nwkKey);
- }
- #endif // defined ( NV_RESTORE )
- /******************************************************************************
- ******************************************************************************/
|