zcl_key_establish.c 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908
  1. /**************************************************************************************************
  2. Filename: zcl_key_establish.c
  3. Revised: $Date: 2008-01-10 18:10:24 -0800 (Thu, 10 Jan 2008) $
  4. Revision: $Revision: 16190 $
  5. Description: Zigbee Cluster Library - General Function Domain - key
  6. establishment cluster.
  7. This application receives ZCL messages and handle them within
  8. ZCL layer, without passing to application.
  9. Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved.
  10. IMPORTANT: Your use of this Software is limited to those specific rights
  11. granted under the terms of a software license agreement between the user
  12. who downloaded the software, his/her employer (which must be your employer)
  13. and Texas Instruments Incorporated (the "License"). You may not use this
  14. Software unless you agree to abide by the terms of the License. The License
  15. limits your use, and you acknowledge, that the Software may not be modified,
  16. copied or distributed unless embedded on a Texas Instruments microcontroller
  17. or used solely and exclusively in conjunction with a Texas Instruments radio
  18. frequency transceiver, which is integrated into your product. Other than for
  19. the foregoing purpose, you may not use, reproduce, copy, prepare derivative
  20. works of, modify, distribute, perform, display or sell this Software and/or
  21. its documentation for any purpose.
  22. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  23. PROVIDED “AS IS?WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  24. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  25. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  26. TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
  27. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  28. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  29. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  30. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  31. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  32. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  33. Should you have any questions regarding your right to use this Software,
  34. contact Texas Instruments Incorporated at www.TI.com.
  35. **************************************************************************************************/
  36. /*********************************************************************
  37. * INCLUDES
  38. */
  39. #include "ZComDef.h"
  40. #include "OSAL.h"
  41. #include "OSAL_Nv.h"
  42. #include "zcl.h"
  43. #include "ZDApp.h"
  44. #include "ssp_hash.h"
  45. #include "AddrMgr.h"
  46. #include "ZDSecMgr.h"
  47. #include "APSMEDE.h"
  48. #include "eccapi.h"
  49. #include "zcl_key_establish.h"
  50. #include "DebugTrace.h"
  51. #include "se.h"
  52. #if defined ( INTER_PAN )
  53. #include "stub_aps.h"
  54. #endif
  55. /*********************************************************************
  56. * MACROS
  57. */
  58. /*********************************************************************
  59. * CONSTANTS
  60. */
  61. #define KEY_ESTABLISHMENT_DEVICE_VERSION 0
  62. #define KEY_ESTABLISHMENT_FLAGS 0
  63. #define KEY_ESTABLISHMENT_SUITE 1 // For CBKE with ECMQV
  64. #define KEY_ESTABLISHMENT_AVG_TIMEOUT ( 2 * ( ZCL_KEY_ESTABLISHMENT_KEY_GENERATE_TIMEOUT + \
  65. ZCL_KEY_ESTABLISHMENT_MAC_GENERATE_TIMEOUT ) )
  66. #define ZCL_KEY_ESTABLISH_DEVICE_VERSION 0
  67. #define ZCL_KEY_ESTABLISH_FLAGS 0
  68. #define INVALID_TASK_ID 0xFF
  69. /*********************************************************************
  70. * TYPEDEFS
  71. */
  72. /*********************************************************************
  73. * GLOBAL VARIABLES
  74. */
  75. // For debug and testing purpose, use a fixed ephermeral key pair instead
  76. // of the randomly generated one.
  77. #if defined (DEBUG_STATIC_ECC)
  78. uint8 public1[22] = {
  79. 0x03, 0x06, 0xAB, 0x52, 0x06, 0x22, 0x01, 0xD9,
  80. 0x95, 0xB8, 0xB8, 0x59, 0x1F, 0x3F, 0x08, 0x6A,
  81. 0x3A, 0x2E, 0x21, 0x4D, 0x84, 0x5E
  82. };
  83. uint8 private1[21] = {
  84. 0x03, 0xD4, 0x8C, 0x72, 0x10, 0xDD, 0xBC, 0xC4,
  85. 0xFB, 0x2E, 0x5E, 0x7A, 0x0A, 0xA1, 0x6A, 0x0D,
  86. 0xB8, 0x95, 0x40, 0x82, 0x0B
  87. };
  88. uint8 public2[22] = {
  89. 0x03, 0x00, 0xE1, 0x17, 0xC8, 0x6D, 0x0E, 0x7C,
  90. 0xD1, 0x28, 0xB2, 0xF3, 0x4E, 0x90, 0x76, 0xCF,
  91. 0xF2, 0x4A, 0xF4, 0x6D, 0x72, 0x88
  92. };
  93. uint8 private2[21] = {
  94. 0x00, 0x13, 0xD3, 0x6D, 0xE4, 0xB1, 0xEA, 0x8E,
  95. 0x22, 0x73, 0x9C, 0x38, 0x13, 0x70, 0x82, 0x3F,
  96. 0x40, 0x4B, 0xFF, 0x88, 0x62
  97. };
  98. #endif
  99. zclOptionRec_t zclKeyEstablish_Options[1] =
  100. {
  101. {
  102. ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
  103. ( AF_ACK_REQUEST ),
  104. },
  105. };
  106. YieldFunc *zclKeyEstablish_YieldFunc = NULL;
  107. uint8 zclKeyEstablish_YieldLevel = 0;
  108. /*********************************************************************
  109. * GLOBAL FUNCTIONS
  110. */
  111. extern uint8* SSP_MemCpyReverse( uint8* dst, uint8* src, unsigned int len );
  112. /*********************************************************************
  113. * LOCAL VARIABLES
  114. */
  115. #if defined(ZCL_KEY_ESTABLISH)
  116. static uint8 zcl_KeyEstablishment_TaskID; // Task ID of the key Establishment cluster
  117. #endif
  118. /*********************************************************************
  119. * SIMPLE DESCRIPTOR
  120. */
  121. // This is the Cluster ID List and should be filled with Application
  122. // specific cluster IDs.
  123. #define ZCL_KEY_ESTABLISH_MAX_INCLUSTERS 1
  124. const cId_t zclKeyEstablish_InClusterList[ZCL_KEY_ESTABLISH_MAX_INCLUSTERS] =
  125. {
  126. ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
  127. };
  128. #define ZCL_KEY_ESTABLISH_MAX_OUTCLUSTERS 1
  129. const cId_t zclKeyEstablish_OutClusterList[ZCL_KEY_ESTABLISH_MAX_OUTCLUSTERS] =
  130. {
  131. ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
  132. };
  133. SimpleDescriptionFormat_t zclKeyEstablish_SimpleDesc =
  134. {
  135. ZCL_KEY_ESTABLISHMENT_ENDPOINT, // int Endpoint;
  136. ZCL_SE_PROFILE_ID, // uint16 AppProfId[2];
  137. ZCL_SE_DEVICEID_ESP, // uint16 AppDeviceId[2];
  138. ZCL_KEY_ESTABLISH_DEVICE_VERSION, // int AppDevVer:4;
  139. ZCL_KEY_ESTABLISH_FLAGS, // int AppFlags:4;
  140. ZCL_KEY_ESTABLISH_MAX_INCLUSTERS, // byte AppNumInClusters;
  141. (cId_t *)zclKeyEstablish_InClusterList, // byte *pAppInClusterList;
  142. ZCL_KEY_ESTABLISH_MAX_OUTCLUSTERS, // byte AppNumInClusters;
  143. (cId_t *)zclKeyEstablish_OutClusterList // byte *pAppInClusterList;
  144. };
  145. #if defined (ZCL_KEY_ESTABLISH)
  146. // Endpoint for Key Establishment Cluster
  147. static endPointDesc_t zclKeyEstablish_Ep =
  148. {
  149. ZCL_KEY_ESTABLISHMENT_ENDPOINT, // Test endpoint
  150. &zcl_TaskID,
  151. (SimpleDescriptionFormat_t *)&zclKeyEstablish_SimpleDesc,
  152. (afNetworkLatencyReq_t)0 // No Network Latency req
  153. };
  154. #endif
  155. // Pointer to the application sequence number for ZCL commands
  156. #if defined ( ZCL_KEY_ESTABLISH)
  157. static uint8 zclKeyEstablishPluginRegisted = FALSE;
  158. static zclKeyEstablishRec_t keyEstablishRec[MAX_KEY_ESTABLISHMENT_REC_ENTRY];
  159. /*********************************************************************
  160. * LOCAL FUNCTIONS
  161. */
  162. static ZStatus_t zclGeneral_KeyEstablish_HdlIncoming( zclIncoming_t *pInMsg );
  163. static ZStatus_t zclGeneral_KeyEstablish_HdlInSpecificCommands( zclIncoming_t *pInMsg );
  164. // Key Establish Cluster Command Processing functions
  165. static ZStatus_t zclGeneral_ProcessInCmd_InitiateKeyEstablish( zclIncoming_t *pInMsg );
  166. static ZStatus_t zclGeneral_ProcessInCmd_InitiateKeyEstablishRsp( zclIncoming_t *pInMsg );
  167. static ZStatus_t zclGeneral_ProcessInCmd_EphemeralDataReq( zclIncoming_t *pInMsg );
  168. static ZStatus_t zclGeneral_ProcessInCmd_EphemeralDataRsp( zclIncoming_t *pInMsg );
  169. static ZStatus_t zclGeneral_ProcessInCmd_ConfirmKey( zclIncoming_t *pInMsg );
  170. static ZStatus_t zclGeneral_ProcessInCmd_ConfirmKeyRsp( zclIncoming_t *pInMsg );
  171. static ZStatus_t zclGeneral_ProcessInCmd_TerminateKeyEstablish( zclIncoming_t *pInMsg );
  172. // Event driven key calculation function
  173. static ZStatus_t zclGeneral_InitiateKeyEstablish_Cmd_CalculateKey(void);
  174. static ZStatus_t zclGeneral_InitiateKeyEstablish_Rsp_CalculateKey(void);
  175. // Key establishment rec table management function
  176. static void zclGeneral_InitKeyEstablishRecTable( void );
  177. static uint8 zclGeneral_GetKeyEstablishRecIndex( uint16 partnerAddress );
  178. static uint8 zclGeneral_GetKeyEstablishRecIndex_State( KeyEstablishState_t state );
  179. static ZStatus_t zclGeneral_RemoveKeyEstablishRec( uint16 partnerAddress );
  180. static uint8 zclGeneral_AddKeyEstablishRec( afAddrType_t *addr );
  181. static void zclGeneral_AgeKeyEstablishRec( void );
  182. // Call back function supplying to ECC library
  183. static int zclGeneral_KeyEstablishment_GetRandom(unsigned char *buffer, unsigned long len);
  184. static int zclGeneral_KeyEstablishment_HashFunc(unsigned char *digest, unsigned long len, unsigned char *data);
  185. // Security related functions
  186. static void zclGeneral_KeyEstablishment_KeyDeriveFunction( uint8 *zData,
  187. uint8 keyBitLen,
  188. uint8 *keyBit );
  189. static ZStatus_t zclGeneral_KeyEstablishment_GenerateMAC(uint8 recIndex,
  190. uint8 ifMACu,
  191. uint8 *MAC);
  192. /*********************************************************************
  193. * @fn zclGeneral_KeyEstablish_Init
  194. *
  195. * @brief Call to initialize the Key Establishment Task
  196. *
  197. * @param task_id
  198. *
  199. * @return none
  200. */
  201. void zclGeneral_KeyEstablish_Init( uint8 task_id )
  202. {
  203. zcl_KeyEstablishment_TaskID = task_id;
  204. // Register for the key establishment cluster endpoint
  205. afRegister( &zclKeyEstablish_Ep );
  206. zcl_registerClusterOptionList( ZCL_KEY_ESTABLISHMENT_ENDPOINT, 1,
  207. zclKeyEstablish_Options );
  208. // Register as a ZCL Plugin
  209. if ( !zclKeyEstablishPluginRegisted )
  210. {
  211. zcl_registerPlugin( ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
  212. ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
  213. zclGeneral_KeyEstablish_HdlIncoming );
  214. zclKeyEstablishPluginRegisted = true;
  215. }
  216. // Initialize the keyEstablishRec table
  217. zclGeneral_InitKeyEstablishRecTable();
  218. // Start the Key Establishment Rec aging timer
  219. osal_start_timerEx( task_id, KEY_ESTABLISHMENT_REC_AGING_EVT,
  220. KEY_ESTABLISHMENT_REC_AGING_INTERVAL );
  221. }
  222. /*********************************************************************
  223. * @fn zclKeyEstablish_event_loop
  224. *
  225. * @brief Event Loop Processor for Key establish task.
  226. *
  227. * @param task_id - TaskId
  228. * events - events
  229. *
  230. * @return none
  231. */
  232. uint16 zclKeyEstablish_event_loop( uint8 task_id, uint16 events )
  233. {
  234. afIncomingMSGPacket_t *MSGpkt;
  235. if ( events & SYS_EVENT_MSG )
  236. {
  237. while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( task_id )) )
  238. {
  239. switch ( MSGpkt->hdr.event )
  240. {
  241. default:
  242. break;
  243. }
  244. // Release the memory
  245. osal_msg_deallocate( (uint8 *)MSGpkt );
  246. }
  247. // return unprocessed events
  248. return (events ^ SYS_EVENT_MSG);
  249. }
  250. if ( events & KEY_ESTABLISHMENT_REC_AGING_EVT )
  251. {
  252. // Start the timer for next evt right away
  253. osal_start_timerEx(task_id, KEY_ESTABLISHMENT_REC_AGING_EVT,
  254. KEY_ESTABLISHMENT_REC_AGING_INTERVAL );
  255. zclGeneral_AgeKeyEstablishRec();
  256. return ( events ^ KEY_ESTABLISHMENT_REC_AGING_EVT );
  257. }
  258. if ( events & KEY_ESTABLISHMENT_CMD_PROCESS_EVT )
  259. {
  260. zclGeneral_InitiateKeyEstablish_Cmd_CalculateKey();
  261. return ( events ^ KEY_ESTABLISHMENT_CMD_PROCESS_EVT );
  262. }
  263. if ( events & KEY_ESTABLISHMENT_RSP_PROCESS_EVT )
  264. {
  265. zclGeneral_InitiateKeyEstablish_Rsp_CalculateKey();
  266. return ( events ^ KEY_ESTABLISHMENT_RSP_PROCESS_EVT );
  267. }
  268. // Discard unknown events
  269. return 0;
  270. }
  271. /*********************************************************************
  272. * @fn zclGeneral_KeyEstablish_InitiateKeyEstablishment
  273. *
  274. * @brief Call to initiate key establishment with partner device
  275. *
  276. * @param appTaskID - task ID of the application that initates the key establish
  277. * @param partnerAddr - short address and endpoint of the partner to establish key with
  278. * @param seqNum - pointer to the sequence number of application (ZCL)
  279. *
  280. * @return ZStatus_t ZSuccess or ZFailure
  281. */
  282. ZStatus_t zclGeneral_KeyEstablish_InitiateKeyEstablishment(uint8 appTaskID,
  283. afAddrType_t *partnerAddr,
  284. uint8 seqNum)
  285. {
  286. uint8 index;
  287. // Assign the app seqnum pointer
  288. zcl_SeqNum = seqNum;
  289. // Start a new key establishment rec entry
  290. index = zclGeneral_AddKeyEstablishRec( partnerAddr );
  291. if( index < MAX_KEY_ESTABLISHMENT_REC_ENTRY ) // valid entry
  292. {
  293. keyEstablishRec[index].role = KEY_ESTABLISHMENT_INITIATOR;
  294. // Assign the application task ID that initiates the key establishment
  295. keyEstablishRec[index].appTaskID = appTaskID;
  296. }
  297. else
  298. {
  299. return ZFailure;
  300. }
  301. // Generate Ephemeral Public/Private Key Pair
  302. ZSE_ECCGenerateKey( ( unsigned char *)keyEstablishRec[index].pLocalEPrivateKey,
  303. ( unsigned char *)keyEstablishRec[index].pLocalEPublicKey,
  304. zclGeneral_KeyEstablishment_GetRandom,
  305. zclKeyEstablish_YieldFunc, zclKeyEstablish_YieldLevel);
  306. #if defined (DEBUG_STATIC_ECC)
  307. // For debug and testing purpose, use a fixed ephermeral key pair instead
  308. // of the randomly generated one.
  309. osal_memcpy( keyEstablishRec[index].pLocalEPrivateKey, private1, 21 );
  310. osal_memcpy( keyEstablishRec[index].pLocalEPublicKey, public1, 22 );
  311. #endif
  312. keyEstablishRec[index].state = KeyEstablishState_InitiatePending;
  313. // Send Initiate Key Establishment Command
  314. zclGeneral_KeyEstablish_Send_InitiateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
  315. partnerAddr,
  316. KEY_ESTABLISHMENT_SUITE,
  317. ZCL_KEY_ESTABLISHMENT_EKEY_GENERATE_TIMEOUT,
  318. ZCL_KEY_ESTABLISHMENT_MAC_GENERATE_TIMEOUT + ZCL_KEY_ESTABLISHMENT_KEY_GENERATE_TIMEOUT,
  319. zgLocalCertificate,
  320. true, zcl_SeqNum++ );
  321. return ZSuccess;
  322. }
  323. /*********************************************************************
  324. * @fn zclGeneral_KeyEstablish_Send_InitiateKeyEstablishment
  325. *
  326. * @brief Call to send out a Initiate Key Establishment Command
  327. *
  328. * @param srcEP - Sending application's endpoint
  329. * @param dstAddr - where you want the message to go
  330. * @param keyEstablishmentSuite - key establishment suite bitmap
  331. * @param keyGenerateTime - how long it takes to generate key
  332. * @param macGenerateTime - how long it takes to generate mac
  333. * @param certificate - identity. For CBKE, it's the implicit certificate.
  334. * @param disableDefaultRsp - disable default response
  335. * @param seqNum - ZCL sequence number
  336. *
  337. * @return ZStatus_t
  338. */
  339. ZStatus_t zclGeneral_KeyEstablish_Send_InitiateKeyEstablishment( uint8 srcEP, afAddrType_t *dstAddr,
  340. uint16 keyEstablishmentSuite,
  341. uint8 keyGenerateTime,
  342. uint8 macGenerateTime,
  343. uint8 *certificate,
  344. uint8 disableDefaultRsp, uint8 seqNum )
  345. {
  346. uint8 *buf;
  347. uint8 *pBuf;
  348. uint8 status;
  349. uint8 bufLen;
  350. (void)srcEP; // Intentionally unreferenced parameter
  351. // keyEstablishmentSuite + eDataGenerateTime + macGenerateTime + certificate
  352. bufLen = 2 + 1 + 1 + ZCL_KEY_ESTABLISHMENT_CERTIFICATE_LENGTH;
  353. if ((buf = osal_mem_alloc(bufLen)) == NULL)
  354. {
  355. return ZMemError;
  356. }
  357. pBuf = buf;
  358. *pBuf++ = LO_UINT16( keyEstablishmentSuite );
  359. *pBuf++ = HI_UINT16( keyEstablishmentSuite );
  360. *pBuf++ = keyGenerateTime;
  361. *pBuf++ = macGenerateTime;
  362. osal_memcpy( pBuf, certificate, ZCL_KEY_ESTABLISHMENT_CERTIFICATE_LENGTH );
  363. status = zcl_SendCommand( ZCL_KEY_ESTABLISHMENT_ENDPOINT, dstAddr,
  364. ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
  365. COMMAND_INITIATE_KEY_ESTABLISHMENT, TRUE,
  366. ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp,
  367. 0, seqNum, bufLen, buf );
  368. osal_mem_free(buf);
  369. return status;
  370. }
  371. /*********************************************************************
  372. * @fn zclGeneral_KeyEstablish_Send_EphemeralDataReq
  373. *
  374. * @brief Call to send out a Ephemeral Data Request Command
  375. *
  376. * @param srcEP - Sending application's endpoint
  377. * @param dstAddr - where you want the message to go
  378. * @param eData - ephemeral data.
  379. * @param disableDefaultRsp - disable default response
  380. * @param seqNum - ZCL sequence number
  381. *
  382. * @return ZStatus_t
  383. */
  384. ZStatus_t zclGeneral_KeyEstablish_Send_EphemeralDataReq( uint8 srcEP, afAddrType_t *dstAddr,
  385. uint8 *eData,
  386. uint8 disableDefaultRsp, uint8 seqNum )
  387. {
  388. return zcl_SendCommand( srcEP, dstAddr,
  389. ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
  390. COMMAND_EPHEMERAL_DATA_REQUEST, TRUE,
  391. ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp,
  392. 0, seqNum, ZCL_KEY_ESTABLISHMENT_PUBLIC_KEY_LENGTH, eData );
  393. }
  394. /*********************************************************************
  395. * @fn zclGeneral_KeyEstablish_Send_ConfirmKey
  396. *
  397. * @brief Call to send out a Confirm Key Command
  398. *
  399. * @param srcEP - Sending application's endpoint
  400. * @param dstAddr - where you want the message to go
  401. * @param mac - MAC.
  402. * @param disableDefaultRsp - disable default response
  403. * @param seqNum - ZCL sequence number
  404. *
  405. * @return ZStatus_t
  406. */
  407. ZStatus_t zclGeneral_KeyEstablish_Send_ConfirmKey( uint8 srcEP, afAddrType_t *dstAddr,
  408. uint8 *mac,
  409. uint8 disableDefaultRsp, uint8 seqNum )
  410. {
  411. return (zcl_SendCommand(srcEP, dstAddr,
  412. ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
  413. COMMAND_CONFIRM_KEY, TRUE,
  414. ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp,
  415. 0, seqNum, KEY_ESTABLISH_MAC_LENGTH, mac ));
  416. }
  417. /*********************************************************************
  418. * @fn zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment
  419. *
  420. * @brief Call to send out a Terminate Key Establishment Command
  421. *
  422. * @param srcEP - Sending application's endpoint
  423. * @param dstAddr - where you want the message to go
  424. * @param status - status of the key establishment procedure.
  425. * @param disableDefaultRsp - disable default response
  426. * @param seqNum - ZCL sequence number
  427. *
  428. * @return ZStatus_t
  429. */
  430. ZStatus_t zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( uint8 srcEP,
  431. afAddrType_t *dstAddr,
  432. TermKeyStatus_t status,
  433. uint8 waitTime,
  434. uint16 keyEstablishmentSuite,
  435. uint8 disableDefaultRsp, uint8 seqNum )
  436. {
  437. uint8 buf[4];
  438. buf[0] = status;
  439. buf[1] = waitTime;
  440. buf[2] = LO_UINT16(keyEstablishmentSuite);
  441. buf[3] = HI_UINT16(keyEstablishmentSuite);
  442. return zcl_SendCommand(srcEP, dstAddr,
  443. ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
  444. COMMAND_TERMINATE_KEY_ESTABLISHMENT, TRUE,
  445. ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp,
  446. 0, seqNum, 4, buf );
  447. }
  448. /*********************************************************************
  449. * @fn zclGeneral_KeyEstablish_Send_InitiateKeyEstablishmentRsp
  450. *
  451. * @brief Call to send out a Initiate Key Establishment Response
  452. *
  453. * @param srcEP - Sending application's endpoint
  454. * @param dstAddr - where you want the message to go
  455. * @param status - status of the key establishment response.
  456. * @param keyEstablishmentSuite - requested key establishment suite bitmap
  457. * @param keyGenerateTime - how long it takes to generate key
  458. * @param macGenerateTime - how long it takes to generate mac
  459. * @param certificate - identity. For CBKE, it's the implicit certificate.
  460. * @param disableDefaultRsp - disable default response
  461. * @param seqNum - ZCL sequence number
  462. *
  463. * @return ZStatus_t
  464. */
  465. ZStatus_t zclGeneral_KeyEstablish_Send_InitiateKeyEstablishmentRsp( uint8 srcEP, afAddrType_t *dstAddr,
  466. uint16 keyEstablishmentSuite,
  467. uint8 keyGenerateTime,
  468. uint8 macGenerateTime,
  469. uint8 *certificate,
  470. uint8 disableDefaultRsp, uint8 seqNum )
  471. {
  472. uint8 *buf;
  473. uint8 bufLen;
  474. uint8 ret;
  475. uint8 *pBuf;
  476. bufLen = 2 + 1 + 1 + ZCL_KEY_ESTABLISHMENT_CERTIFICATE_LENGTH;
  477. if ((buf = osal_mem_alloc(bufLen)) == NULL)
  478. {
  479. return ZMemError;
  480. }
  481. pBuf = buf;
  482. *pBuf++ = LO_UINT16( keyEstablishmentSuite );
  483. *pBuf++ = HI_UINT16( keyEstablishmentSuite );
  484. *pBuf++ = keyGenerateTime;
  485. *pBuf++ = macGenerateTime;
  486. osal_memcpy( pBuf, certificate, ZCL_KEY_ESTABLISHMENT_CERTIFICATE_LENGTH );
  487. ret = zcl_SendCommand( srcEP, dstAddr,
  488. ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
  489. COMMAND_INITIATE_KEY_ESTABLISHMENT_RESPONSE, TRUE,
  490. ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp,
  491. 0, seqNum, bufLen, buf );
  492. osal_mem_free(buf);
  493. return ret;
  494. }
  495. /*********************************************************************
  496. * @fn zclGeneral_KeyEstablish_Send_EphemeralDataRsp
  497. *
  498. * @brief Call to send out a Ephemeral Data Response Command
  499. *
  500. * @param srcEP - Sending application's endpoint
  501. * @param dstAddr - where you want the message to go
  502. * @param eData - ephemeral data.
  503. * @param disableDefaultRsp - disable default response
  504. * @param seqNum - ZCL sequence number
  505. *
  506. * @return ZStatus_t
  507. */
  508. ZStatus_t zclGeneral_KeyEstablish_Send_EphemeralDataRsp( uint8 srcEP, afAddrType_t *dstAddr,
  509. uint8 *eData,
  510. uint8 disableDefaultRsp, uint8 seqNum )
  511. {
  512. return (zcl_SendCommand( srcEP, dstAddr,
  513. ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
  514. COMMAND_EPHEMERAL_DATA_RESPONSE, TRUE,
  515. ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp,
  516. 0, seqNum, ZCL_KEY_ESTABLISHMENT_PUBLIC_KEY_LENGTH, eData ));
  517. }
  518. /*********************************************************************
  519. * @fn zclGeneral_KeyEstablish_Send_ConfirmKeyRsp
  520. *
  521. * @brief Call to send out a Confirm Key Response
  522. *
  523. * @param srcEP - Sending application's endpoint
  524. * @param dstAddr - where you want the message to go
  525. * @param mac - MAC
  526. * @param disableDefaultRsp - disable default response
  527. * @param seqNum - ZCL sequence number
  528. *
  529. * @return ZStatus_t
  530. */
  531. ZStatus_t zclGeneral_KeyEstablish_Send_ConfirmKeyRsp( uint8 srcEP, afAddrType_t *dstAddr,
  532. uint8 *mac,
  533. uint8 disableDefaultRsp, uint8 seqNum )
  534. {
  535. return (zcl_SendCommand(srcEP, dstAddr,
  536. ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
  537. COMMAND_CONFIRM_KEY_RESPONSE, TRUE,
  538. ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp,
  539. 0, seqNum, KEY_ESTABLISH_MAC_LENGTH, mac ));
  540. }
  541. /*********************************************************************
  542. * @fn zclGeneral_KeyEstablish_Send_ConfirmKeyRsp
  543. *
  544. * @brief Register the user defined yielding function
  545. *
  546. * @param yield - Pointer to a function to allow user defined yielding.
  547. * YieldFunc may be NULL if yieldLevel is 0
  548. * @param yieldLevel - The yield level determines how often the user defined
  549. * yield function will be called. This is a number from 0 to 10.
  550. * 0 will never yield. 1 will yield the most often. 10 will yield the
  551. * least often.
  552. */
  553. void zclGeneral_KeyEstablishment_RegYieldCB( YieldFunc *pFnYield,
  554. uint8 yieldLevel )
  555. {
  556. if( pFnYield == NULL )
  557. {
  558. zclKeyEstablish_YieldLevel = 0;
  559. }
  560. else
  561. {
  562. zclKeyEstablish_YieldFunc = pFnYield;
  563. zclKeyEstablish_YieldLevel = yieldLevel;
  564. }
  565. }
  566. /*********************************************************************
  567. * @fn zclGeneral_KeyEstablish_HdlIncoming
  568. *
  569. * @brief Callback from ZCL to process incoming Commands specific
  570. * to this cluster library or Profile commands
  571. *
  572. * @param pInMsg - pointer to the incoming message
  573. *
  574. * @return ZStatus_t
  575. */
  576. static ZStatus_t zclGeneral_KeyEstablish_HdlIncoming( zclIncoming_t *pInMsg )
  577. {
  578. ZStatus_t stat = ZSuccess;
  579. #if defined ( INTER_PAN )
  580. if ( StubAPS_InterPan( pInMsg->msg->srcAddr.panId, pInMsg->msg->srcAddr.endPoint ) )
  581. return ( stat ); // Cluster not supported thru Inter-PAN
  582. #endif
  583. if ( zcl_ClusterCmd( pInMsg->hdr.fc.type ) )
  584. {
  585. // Is this a manufacturer specific command?
  586. if ( pInMsg->hdr.fc.manuSpecific == 0 )
  587. {
  588. stat = zclGeneral_KeyEstablish_HdlInSpecificCommands( pInMsg );
  589. }
  590. else
  591. {
  592. // We don't support any manufacturer specific command.
  593. stat = ZFailure;
  594. }
  595. }
  596. else
  597. {
  598. // Handle all the normal (Read, Write...) commands -- should never get here
  599. stat = ZFailure;
  600. }
  601. return ( stat );
  602. }
  603. /*********************************************************************
  604. * @fn zclGeneral_KeyEstablish_HdlInSpecificCommands
  605. *
  606. * @brief Callback from ZCL to process incoming Commands specific
  607. * to this cluster library
  608. * @param pInMsg - pointer to the incoming message
  609. *
  610. * @return ZStatus_t
  611. */
  612. static ZStatus_t zclGeneral_KeyEstablish_HdlInSpecificCommands( zclIncoming_t *pInMsg )
  613. {
  614. ZStatus_t stat;
  615. if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
  616. {
  617. switch ( pInMsg->hdr.commandID )
  618. {
  619. case COMMAND_INITIATE_KEY_ESTABLISHMENT:
  620. stat = zclGeneral_ProcessInCmd_InitiateKeyEstablish( pInMsg );
  621. break;
  622. case COMMAND_EPHEMERAL_DATA_REQUEST:
  623. stat = zclGeneral_ProcessInCmd_EphemeralDataReq( pInMsg );
  624. break;
  625. case COMMAND_CONFIRM_KEY:
  626. stat = zclGeneral_ProcessInCmd_ConfirmKey( pInMsg );
  627. break;
  628. case COMMAND_TERMINATE_KEY_ESTABLISHMENT:
  629. stat = zclGeneral_ProcessInCmd_TerminateKeyEstablish( pInMsg );
  630. break;
  631. default:
  632. stat = ZFailure;
  633. break;
  634. }
  635. }
  636. else
  637. {
  638. if ( pInMsg->hdr.commandID == COMMAND_INITIATE_KEY_ESTABLISHMENT_RESPONSE )
  639. {
  640. stat = zclGeneral_ProcessInCmd_InitiateKeyEstablishRsp( pInMsg );
  641. }
  642. else if ( pInMsg->hdr.commandID == COMMAND_EPHEMERAL_DATA_RESPONSE )
  643. {
  644. stat = zclGeneral_ProcessInCmd_EphemeralDataRsp( pInMsg );
  645. }
  646. else if ( pInMsg->hdr.commandID == COMMAND_CONFIRM_KEY_RESPONSE )
  647. {
  648. stat = zclGeneral_ProcessInCmd_ConfirmKeyRsp( pInMsg );
  649. }
  650. else
  651. {
  652. stat = ZFailure;
  653. }
  654. }
  655. return ( stat );
  656. }
  657. /*********************************************************************
  658. * @fn zclGeneral_ProcessInCmd_InitiateKeyEstablish
  659. *
  660. * @brief Process the received Initiate Key Establishment Response.
  661. *
  662. * @param pInMsg - pointer to the incoming message
  663. *
  664. * @return ZStatus_t - ZFailure @ Unsupported
  665. * ZCL_STATUS_MALFORMED_COMMAND
  666. * ZCL_STATUS_CMD_HAS_RSP
  667. * ZCL_STATUS_SOFTWARE_FAILURE
  668. */
  669. static ZStatus_t zclGeneral_ProcessInCmd_InitiateKeyEstablish( zclIncoming_t *pInMsg )
  670. {
  671. uint8 index;
  672. TermKeyStatus_t status = TermKeyStatus_Success;
  673. uint16 remoteKeyEstablishmentSuite;
  674. // Omit checking the incoming packet length
  675. // Start a new key establishment rec entry
  676. index = zclGeneral_AddKeyEstablishRec( &pInMsg->msg->srcAddr );
  677. if( index == MAX_KEY_ESTABLISHMENT_REC_ENTRY ) // Fail to add an entry
  678. {
  679. // keyEstablishRec table is full or partner extAddr not available, terminate.
  680. zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
  681. &pInMsg->msg->srcAddr,
  682. TermKeyStatus_NoResources,
  683. KEY_ESTABLISHMENT_AVG_TIMEOUT,
  684. KEY_ESTABLISHMENT_SUITE,
  685. false, zcl_SeqNum++ );
  686. return ZCL_STATUS_CMD_HAS_RSP;
  687. }
  688. // Parse the incoming message
  689. // Copy the remote device certificate
  690. osal_memcpy(keyEstablishRec[index].pRemoteCertificate, &(pInMsg->pData[KEY_ESTABLISH_CERT_IDX]),
  691. ZCL_KEY_ESTABLISHMENT_CERTIFICATE_LENGTH );
  692. // Verify the certificate issuer and key establishment suite
  693. remoteKeyEstablishmentSuite = BUILD_UINT16( pInMsg->pData[0], pInMsg->pData[1] );
  694. if ( remoteKeyEstablishmentSuite != KEY_ESTABLISHMENT_SUITE )
  695. {
  696. status = TermKeyStatus_UnSupportedSuite;
  697. }
  698. if ( !osal_memcmp( &(keyEstablishRec[index].pRemoteCertificate[KEY_ESTABLISH_CERT_ISSUER_IDX]),
  699. &(zgLocalCertificate[KEY_ESTABLISH_CERT_ISSUER_IDX]),
  700. KEY_ESTABLISH_CERT_ISSUER_LENTGH ) )
  701. {
  702. status = TermKeyStatus_UnknowIssuer;
  703. }
  704. if ( status != ZSuccess )
  705. {
  706. zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
  707. &pInMsg->msg->srcAddr,
  708. status,
  709. KEY_ESTABLISHMENT_AVG_TIMEOUT,
  710. KEY_ESTABLISHMENT_SUITE,
  711. false, zcl_SeqNum++ );
  712. return ZCL_STATUS_CMD_HAS_RSP;
  713. }
  714. // Fill in partner's extended address
  715. SSP_MemCpyReverse( keyEstablishRec[index].partnerExtAddr,
  716. &(keyEstablishRec[index].pRemoteCertificate[KEY_ESTABLISH_CERT_EXT_ADDR_IDX]),
  717. Z_EXTADDR_LEN); // ID(L)
  718. // Change the state and wait for the Key Confirma Command
  719. keyEstablishRec[index].lastSeqNum = pInMsg->hdr.transSeqNum;
  720. keyEstablishRec[index].state = KeyEstablishState_EDataPending;
  721. keyEstablishRec[index].role = KEY_ESTABLISHMENT_RESPONDER;
  722. zclGeneral_KeyEstablish_Send_InitiateKeyEstablishmentRsp( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
  723. &pInMsg->msg->srcAddr,
  724. KEY_ESTABLISHMENT_SUITE,
  725. ZCL_KEY_ESTABLISHMENT_EKEY_GENERATE_TIMEOUT + ZCL_KEY_ESTABLISHMENT_KEY_GENERATE_TIMEOUT,
  726. ZCL_KEY_ESTABLISHMENT_MAC_GENERATE_TIMEOUT * 2 ,
  727. zgLocalCertificate,
  728. false, pInMsg->hdr.transSeqNum );
  729. return ZCL_STATUS_CMD_HAS_RSP;
  730. }
  731. /*********************************************************************
  732. * @fn zclGeneral_ProcessInCmd_EphemeralDataReq
  733. *
  734. * @brief Process the received Initiate Key Establishment Command.
  735. *
  736. * @param pInMsg - pointer to the incoming message
  737. *
  738. * @return ZStatus_t - ZFailure @ Unsupported
  739. * ZCL_STATUS_MALFORMED_COMMAND
  740. * ZCL_STATUS_CMD_HAS_RSP
  741. */
  742. static ZStatus_t zclGeneral_ProcessInCmd_EphemeralDataReq( zclIncoming_t *pInMsg )
  743. {
  744. uint8 index;
  745. // Omit checking the incoming packet length
  746. // Check state of the key establishment record. If not match, terminate the procedure
  747. if ( ( index = zclGeneral_GetKeyEstablishRecIndex( pInMsg->msg->srcAddr.addr.shortAddr ) )
  748. < MAX_KEY_ESTABLISHMENT_REC_ENTRY )
  749. {
  750. if ( keyEstablishRec[index].role == KEY_ESTABLISHMENT_RESPONDER &&
  751. keyEstablishRec[index].state == KeyEstablishState_EDataPending )
  752. {
  753. // Copy the remote device Ephemeral Public key
  754. osal_memcpy( keyEstablishRec[index].pRemotePublicKey,
  755. &(pInMsg->pData[0]),
  756. ZCL_KEY_ESTABLISHMENT_PUBLIC_KEY_LENGTH );
  757. }
  758. }
  759. else
  760. {
  761. // Either the entry doesn't exist or in the wrong state, send termination back
  762. zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
  763. &pInMsg->msg->srcAddr,
  764. TermKeyStatus_BadMessage,
  765. KEY_ESTABLISHMENT_AVG_TIMEOUT,
  766. KEY_ESTABLISHMENT_SUITE,
  767. false, zcl_SeqNum++ );
  768. }
  769. // Generate Ephemeral Public/Private Key Pair
  770. ZSE_ECCGenerateKey( (unsigned char *)keyEstablishRec[index].pLocalEPrivateKey,
  771. (unsigned char *)keyEstablishRec[index].pLocalEPublicKey,
  772. zclGeneral_KeyEstablishment_GetRandom,
  773. zclKeyEstablish_YieldFunc, zclKeyEstablish_YieldLevel );
  774. #if defined (DEBUG_STATIC_ECC)
  775. // For debug and testing purpose, use a fixed ephermeral key pair instead
  776. // of the randomly generated one.
  777. osal_memcpy( keyEstablishRec[index].pLocalEPrivateKey, private2, 21 );
  778. osal_memcpy( keyEstablishRec[index].pLocalEPublicKey, public2, 22 );
  779. #endif
  780. // Change the state and wait for the Key to be calculated
  781. keyEstablishRec[index].state = KeyEstablishState_KeyCalculatePending;
  782. osal_start_timerEx( zcl_KeyEstablishment_TaskID, KEY_ESTABLISHMENT_CMD_PROCESS_EVT,
  783. KEY_ESTABLISHMENT_WAIT_PERIOD );
  784. return ZCL_STATUS_CMD_HAS_RSP;
  785. }
  786. /*********************************************************************
  787. * @fn zclGeneral_ProcessInCmd_InitiateKeyEstablishRsp
  788. *
  789. * @brief Process the received Initiate Key Establishment Response.
  790. *
  791. * @param pInMsg - pointer to the incoming message
  792. *
  793. * @return ZStatus_t - ZFailure @ Unsupported
  794. * ZCL_STATUS_MALFORMED_COMMAND
  795. * ZCL_STATUS_CMD_HAS_RSP
  796. * ZCL_STATUS_SOFTWARE_FAILURE
  797. */
  798. static ZStatus_t zclGeneral_ProcessInCmd_InitiateKeyEstablishRsp( zclIncoming_t *pInMsg )
  799. {
  800. uint8 index;
  801. uint8 status = ZFailure;
  802. TermKeyStatus_t keyStatus = TermKeyStatus_Success;
  803. uint16 remoteKeyEstablishmentSuite;
  804. // Check state of the key establishment record. If not match, terminate the procedure
  805. if ( ( index = zclGeneral_GetKeyEstablishRecIndex( pInMsg->msg->srcAddr.addr.shortAddr ) )
  806. < MAX_KEY_ESTABLISHMENT_REC_ENTRY )
  807. {
  808. if ( keyEstablishRec[index].role == KEY_ESTABLISHMENT_INITIATOR &&
  809. keyEstablishRec[index].state == KeyEstablishState_InitiatePending )
  810. {
  811. status = ZSuccess;
  812. // Parse the incoming message
  813. // Copy the remote device certificate
  814. osal_memcpy( keyEstablishRec[index].pRemoteCertificate, &(pInMsg->pData[KEY_ESTABLISH_CERT_IDX]),
  815. ZCL_KEY_ESTABLISHMENT_CERTIFICATE_LENGTH );
  816. SSP_MemCpyReverse( keyEstablishRec[index].partnerExtAddr,
  817. &(keyEstablishRec[index].pRemoteCertificate[KEY_ESTABLISH_CERT_EXT_ADDR_IDX]), Z_EXTADDR_LEN);
  818. }
  819. else
  820. {
  821. // Remove the entry from the rec table
  822. zclGeneral_RemoveKeyEstablishRec( pInMsg->msg->srcAddr.addr.shortAddr );
  823. }
  824. }
  825. if ( status == ZFailure )
  826. {
  827. // No existing record found or the record found has a wrong state, terminate the procedure
  828. zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
  829. &pInMsg->msg->srcAddr,
  830. TermKeyStatus_BadMessage,
  831. KEY_ESTABLISHMENT_AVG_TIMEOUT,
  832. KEY_ESTABLISHMENT_SUITE,
  833. false, zcl_SeqNum++ );
  834. return ZCL_STATUS_CMD_HAS_RSP;
  835. }
  836. // Verify the certificate issuer and key establishment suite
  837. remoteKeyEstablishmentSuite = BUILD_UINT16( pInMsg->pData[0], pInMsg->pData[1] );
  838. if ( remoteKeyEstablishmentSuite != KEY_ESTABLISHMENT_SUITE )
  839. {
  840. keyStatus = TermKeyStatus_UnSupportedSuite;
  841. }
  842. if ( !osal_memcmp( &(keyEstablishRec[index].pRemoteCertificate[KEY_ESTABLISH_CERT_ISSUER_IDX]),
  843. &(zgLocalCertificate[KEY_ESTABLISH_CERT_ISSUER_IDX]),
  844. KEY_ESTABLISH_CERT_ISSUER_LENTGH ) )
  845. {
  846. keyStatus = TermKeyStatus_UnknowIssuer;
  847. }
  848. if ( keyStatus != ZSuccess )
  849. {
  850. zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
  851. &pInMsg->msg->srcAddr,
  852. keyStatus,
  853. KEY_ESTABLISHMENT_AVG_TIMEOUT,
  854. KEY_ESTABLISHMENT_SUITE,
  855. false, zcl_SeqNum++ );
  856. return ZCL_STATUS_CMD_HAS_RSP;
  857. }
  858. keyEstablishRec[index].state = KeyEstablishState_EDataPending;
  859. // Send Ephemeral Data Request back
  860. zclGeneral_KeyEstablish_Send_EphemeralDataReq( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
  861. &pInMsg->msg->srcAddr,
  862. keyEstablishRec[index].pLocalEPublicKey,
  863. false, zcl_SeqNum++ );
  864. return ZCL_STATUS_CMD_HAS_RSP;
  865. }
  866. /*********************************************************************
  867. * @fn zclGeneral_ProcessInCmd_EphemeralDataRsp
  868. *
  869. * @brief Process the received Initiate Key Establishment Response.
  870. *
  871. * @param pInMsg - pointer to the incoming message
  872. *
  873. * @return ZStatus_t - ZFailure @ Unsupported
  874. * ZCL_STATUS_MALFORMED_COMMAND
  875. * ZCL_STATUS_CMD_HAS_RSP
  876. * ZCL_STATUS_SOFTWARE_FAILURE
  877. */
  878. static ZStatus_t zclGeneral_ProcessInCmd_EphemeralDataRsp( zclIncoming_t *pInMsg )
  879. {
  880. uint8 index;
  881. uint8 status = ZFailure;
  882. // Check state of the key establishment record. If not match, terminate the procedure
  883. if ( ( index = zclGeneral_GetKeyEstablishRecIndex( pInMsg->msg->srcAddr.addr.shortAddr ) )
  884. < MAX_KEY_ESTABLISHMENT_REC_ENTRY )
  885. {
  886. if ( keyEstablishRec[index].role == KEY_ESTABLISHMENT_INITIATOR &&
  887. keyEstablishRec[index].state == KeyEstablishState_EDataPending )
  888. {
  889. status = ZSuccess;
  890. // Copy the remote device Ephemeral Public key
  891. osal_memcpy( keyEstablishRec[index].pRemotePublicKey,
  892. &(pInMsg->pData[0]),
  893. ZCL_KEY_ESTABLISHMENT_PUBLIC_KEY_LENGTH );
  894. }
  895. else
  896. {
  897. // Remove the entry from the rec table
  898. zclGeneral_RemoveKeyEstablishRec( pInMsg->msg->srcAddr.addr.shortAddr );
  899. }
  900. }
  901. if ( status == ZFailure )
  902. {
  903. // No existing record found or the record found has a wrong state, terminate the procedure
  904. zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
  905. &pInMsg->msg->srcAddr,
  906. TermKeyStatus_BadMessage,
  907. KEY_ESTABLISHMENT_AVG_TIMEOUT,
  908. KEY_ESTABLISHMENT_SUITE,
  909. false, zcl_SeqNum++ );
  910. return ZCL_STATUS_CMD_HAS_RSP;
  911. }
  912. keyEstablishRec[index].state = KeyEstablishState_KeyCalculatePending;
  913. osal_start_timerEx( zcl_KeyEstablishment_TaskID, KEY_ESTABLISHMENT_RSP_PROCESS_EVT,
  914. KEY_ESTABLISHMENT_WAIT_PERIOD );
  915. return ZCL_STATUS_CMD_HAS_RSP;
  916. }
  917. /*********************************************************************
  918. * @fn zclGeneral_ProcessInCmd_ConfirmKey
  919. *
  920. * @brief Process the received Confirm Key Command.
  921. *
  922. * @param pInMsg - pointer to the incoming message
  923. *
  924. * @return ZStatus_t - ZFailure @ Unsupported
  925. * ZCL_STATUS_CMD_HAS_RSP
  926. * ZCL_STATUS_SOFTWARE_FAILURE
  927. */
  928. static ZStatus_t zclGeneral_ProcessInCmd_ConfirmKey( zclIncoming_t *pInMsg )
  929. {
  930. uint8 index;
  931. uint8 status = ZFailure;
  932. uint8 MACu[KEY_ESTABLISH_MAC_KEY_LENGTH];
  933. uint8 MACv[KEY_ESTABLISH_MAC_KEY_LENGTH];
  934. // Check state of the key establishment record. If not match, terminate the procedure
  935. if ( ( index = zclGeneral_GetKeyEstablishRecIndex( pInMsg->msg->srcAddr.addr.shortAddr ) )
  936. < MAX_KEY_ESTABLISHMENT_REC_ENTRY )
  937. {
  938. if ( keyEstablishRec[index].role == KEY_ESTABLISHMENT_RESPONDER &&
  939. keyEstablishRec[index].state == KeyEstablishState_ConfirmPending )
  940. {
  941. status = ZSuccess;
  942. }
  943. else
  944. {
  945. // Remove the entry from the rec table
  946. zclGeneral_RemoveKeyEstablishRec( pInMsg->msg->srcAddr.addr.shortAddr );
  947. }
  948. }
  949. if ( status == ZFailure )
  950. {
  951. // No existing record found or the record found has a wrong state, terminate the procedure
  952. zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
  953. &pInMsg->msg->srcAddr,
  954. TermKeyStatus_BadMessage,
  955. KEY_ESTABLISHMENT_AVG_TIMEOUT,
  956. KEY_ESTABLISHMENT_SUITE,
  957. false, zcl_SeqNum++ );
  958. return ZCL_STATUS_CMD_HAS_RSP;
  959. }
  960. // Calculate MAC(U). Note that the zData is also pointing to the macKey
  961. zclGeneral_KeyEstablishment_GenerateMAC( index, TRUE, MACu );
  962. // Compare MAC(U) with MAC(V)
  963. if ( osal_memcmp( MACu, pInMsg->pData, KEY_ESTABLISH_MAC_LENGTH ) == TRUE )
  964. {
  965. // Send Confirm Key Response with Status - SUCCESS
  966. keyEstablishRec[index].state = KeyEstablishState_TerminationPending;
  967. // Store the key in the key table
  968. ZDSecMgrAddLinkKey( pInMsg->msg->srcAddr.addr.shortAddr,
  969. keyEstablishRec[index].partnerExtAddr,
  970. keyEstablishRec[index].pKey );
  971. // Calculate MAC(V) and send it back
  972. zclGeneral_KeyEstablishment_GenerateMAC( index, FALSE, MACv );
  973. zclGeneral_KeyEstablish_Send_ConfirmKeyRsp( pInMsg->msg->endPoint,
  974. &pInMsg->msg->srcAddr,
  975. MACv,
  976. false, pInMsg->hdr.transSeqNum );
  977. }
  978. else
  979. {
  980. // If MAC(U) does not match MAC(V), send response with failure
  981. zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
  982. &pInMsg->msg->srcAddr,
  983. TermKeyStatus_BadKeyConfirm,
  984. KEY_ESTABLISHMENT_AVG_TIMEOUT,
  985. KEY_ESTABLISHMENT_SUITE,
  986. false, zcl_SeqNum++ );
  987. }
  988. return ZCL_STATUS_CMD_HAS_RSP;
  989. }
  990. /*********************************************************************
  991. * @fn zclGeneral_ProcessInCmd_ConfirmKeyRsp
  992. *
  993. * @brief Process the received Confirm Key Response.
  994. *
  995. * @param pInMsg - pointer to the incoming message
  996. *
  997. * @return ZStatus_t - ZFailure @ Unsupported
  998. * ZCL_STATUS_MALFORMED_COMMAND
  999. * ZCL_STATUS_CMD_HAS_RSP
  1000. * ZCL_STATUS_SOFTWARE_FAILURE
  1001. */
  1002. static ZStatus_t zclGeneral_ProcessInCmd_ConfirmKeyRsp( zclIncoming_t *pInMsg )
  1003. {
  1004. uint8 index;
  1005. uint8 status = ZFailure;
  1006. uint8 MACv[KEY_ESTABLISH_MAC_LENGTH];
  1007. // Check state of the key establishment record. If not match, terminate the procedure
  1008. if ( ( index = zclGeneral_GetKeyEstablishRecIndex( pInMsg->msg->srcAddr.addr.shortAddr ) )
  1009. < MAX_KEY_ESTABLISHMENT_REC_ENTRY )
  1010. {
  1011. if ( keyEstablishRec[index].role == KEY_ESTABLISHMENT_INITIATOR &&
  1012. keyEstablishRec[index].state == KeyEstablishState_ConfirmPending )
  1013. {
  1014. status = ZSuccess;
  1015. }
  1016. }
  1017. if ( status == ZFailure )
  1018. {
  1019. status = TermKeyStatus_BadMessage;
  1020. }
  1021. else
  1022. {
  1023. // Calculate MAC(V)
  1024. zclGeneral_KeyEstablishment_GenerateMAC( index, FALSE, MACv);
  1025. // Compare M(U) with M(V)
  1026. if ( osal_memcmp( MACv, pInMsg->pData, KEY_ESTABLISH_MAC_LENGTH ) == TRUE )
  1027. {
  1028. status = TermKeyStatus_Success;
  1029. // Store the link key
  1030. ZDSecMgrAddLinkKey( pInMsg->msg->srcAddr.addr.shortAddr,
  1031. keyEstablishRec[index].partnerExtAddr,
  1032. keyEstablishRec[index].pKey );
  1033. }
  1034. else
  1035. {
  1036. // If MAC(U) does not match MAC(V), send response with failure
  1037. status = TermKeyStatus_BadKeyConfirm;
  1038. }
  1039. }
  1040. if( status != TermKeyStatus_Success )
  1041. {
  1042. zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
  1043. &pInMsg->msg->srcAddr,
  1044. (TermKeyStatus_t)status,
  1045. KEY_ESTABLISHMENT_AVG_TIMEOUT,
  1046. KEY_ESTABLISHMENT_SUITE,
  1047. false, zcl_SeqNum++ );
  1048. }
  1049. // Send Osal message to the application to indicate the completion
  1050. if ( keyEstablishRec[index].appTaskID != INVALID_TASK_ID )
  1051. {
  1052. keyEstablishmentInd_t *ind;
  1053. ind = (keyEstablishmentInd_t *)osal_msg_allocate( sizeof( keyEstablishmentInd_t ) );
  1054. if ( ind )
  1055. {
  1056. ind->hdr.event = ZCL_KEY_ESTABLISH_IND;
  1057. ind->hdr.status = status;
  1058. // Clear remaining fields
  1059. ind->waitTime = 0;
  1060. ind->keyEstablishmentSuite = 0;
  1061. osal_msg_send( keyEstablishRec[index].appTaskID, (uint8*)ind );
  1062. }
  1063. }
  1064. // End of this transection. Remove the entry from the rec table
  1065. zclGeneral_RemoveKeyEstablishRec( pInMsg->msg->srcAddr.addr.shortAddr );
  1066. return ZCL_STATUS_CMD_HAS_RSP;
  1067. }
  1068. /*********************************************************************
  1069. * @fn zclGeneral_ProcessInCmd_TerminateKeyEstablish
  1070. *
  1071. * @brief Process the received Terminate Key Establishment Command.
  1072. *
  1073. * @param pInMsg - pointer to the incoming message
  1074. *
  1075. * @return ZStatus_t - ZFailure @ Unsupported
  1076. * ZSuccess @ Success
  1077. */
  1078. static ZStatus_t zclGeneral_ProcessInCmd_TerminateKeyEstablish( zclIncoming_t *pInMsg )
  1079. {
  1080. uint8 index;
  1081. // Find the key establishment record and delete the record entry.
  1082. if ( ( index = zclGeneral_GetKeyEstablishRecIndex( pInMsg->msg->srcAddr.addr.shortAddr ) )
  1083. < MAX_KEY_ESTABLISHMENT_REC_ENTRY )
  1084. {
  1085. if ( keyEstablishRec[index].appTaskID != INVALID_TASK_ID )
  1086. {
  1087. keyEstablishmentInd_t *ind;
  1088. // Send osal message to the application
  1089. ind = (keyEstablishmentInd_t *)osal_msg_allocate( sizeof( keyEstablishmentInd_t ) );
  1090. if ( ind )
  1091. {
  1092. ind->hdr.event = ZCL_KEY_ESTABLISH_IND;
  1093. ind->hdr.status = pInMsg->pData[0];
  1094. ind->waitTime = pInMsg->pData[1];
  1095. ind->keyEstablishmentSuite = BUILD_UINT16( pInMsg->pData[2], pInMsg->pData[3] );
  1096. osal_msg_send( keyEstablishRec[index].appTaskID, (uint8*)ind );
  1097. }
  1098. }
  1099. // In either case, remove the entry from the rec table
  1100. zclGeneral_RemoveKeyEstablishRec( pInMsg->msg->srcAddr.addr.shortAddr );
  1101. }
  1102. return ZSuccess;
  1103. }
  1104. /*********************************************************************
  1105. * @fn zclGeneral_InitiateKeyEstablish_Cmd_CalculateKey
  1106. *
  1107. * @brief Calculate the Key using ECC library upon receipt of Initiate
  1108. Key Establishment Command.
  1109. *
  1110. * @param none
  1111. *
  1112. * @return ZStatus_t - ZFailure @ Entry pending key calculation not found
  1113. * ZSuccess
  1114. */
  1115. static ZStatus_t zclGeneral_InitiateKeyEstablish_Cmd_CalculateKey( void )
  1116. {
  1117. uint8 index;
  1118. uint8 status;
  1119. uint8 tmp;
  1120. uint8 zData[KEY_ESTABLISH_SHARED_SECRET_LENGTH];
  1121. uint8 *keyBit;
  1122. // It is possible to have multiple entries in the keyCalulationPending state.
  1123. // Here we assume the partner that starts the key establishment procedure earlier
  1124. // will have a smaller index in the table.
  1125. // However, this might not apply due to different processing capability of
  1126. // different processors.
  1127. if ( (index = zclGeneral_GetKeyEstablishRecIndex_State( KeyEstablishState_KeyCalculatePending ))
  1128. >= MAX_KEY_ESTABLISHMENT_REC_ENTRY )
  1129. {
  1130. return ZFailure;
  1131. }
  1132. // Turn off the radio
  1133. tmp = false;
  1134. ZMacSetReq( ZMacRxOnIdle, &tmp );
  1135. status = ZSE_ECCKeyBitGenerate( zgStaticPrivateKey, keyEstablishRec[index].pLocalEPrivateKey,
  1136. keyEstablishRec[index].pLocalEPublicKey,
  1137. keyEstablishRec[index].pRemoteCertificate,
  1138. keyEstablishRec[index].pRemotePublicKey,
  1139. zgCAPublicKey, zData,
  1140. zclGeneral_KeyEstablishment_HashFunc,
  1141. zclKeyEstablish_YieldFunc, zclKeyEstablish_YieldLevel);
  1142. tmp = true;
  1143. ZMacSetReq( ZMacRxOnIdle, &tmp ); // Turn the radio back on
  1144. if( status == MCE_SUCCESS )
  1145. {
  1146. // Allocate buffer to store KDF(Z) = MacKey || KeyData
  1147. if ( (keyBit = osal_mem_alloc( KEY_ESTABLISH_KEY_DATA_LENGTH +
  1148. KEY_ESTABLISH_MAC_KEY_LENGTH)) == NULL )
  1149. {
  1150. return ZCL_STATUS_SOFTWARE_FAILURE; // Memory allocation failure
  1151. }
  1152. // Derive the keying data using KDF function
  1153. zclGeneral_KeyEstablishment_KeyDeriveFunction(zData,
  1154. KEY_ESTABLISH_SHARED_SECRET_LENGTH,
  1155. keyBit );
  1156. // Save the derived 128-bit key and macKey
  1157. osal_memcpy( keyEstablishRec[index].pMacKey, keyBit, KEY_ESTABLISH_MAC_KEY_LENGTH );
  1158. osal_memcpy( keyEstablishRec[index].pKey, &(keyBit[KEY_ESTABLISH_MAC_KEY_LENGTH]),
  1159. KEY_ESTABLISH_KEY_DATA_LENGTH);
  1160. osal_mem_free( keyBit );
  1161. // Key Bit generation success, send Ephemeral Data Response back
  1162. zclGeneral_KeyEstablish_Send_EphemeralDataRsp( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
  1163. &(keyEstablishRec[index].dstAddr),
  1164. keyEstablishRec[index].pLocalEPublicKey,
  1165. false, keyEstablishRec[index].lastSeqNum );
  1166. }
  1167. else
  1168. {
  1169. // Key Bit generation failure. Send terminate key command
  1170. zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
  1171. &(keyEstablishRec[index].dstAddr),
  1172. TermKeyStatus_BadKeyConfirm,
  1173. KEY_ESTABLISHMENT_AVG_TIMEOUT,
  1174. KEY_ESTABLISHMENT_SUITE,
  1175. false, zcl_SeqNum++ );
  1176. return ZFailure;
  1177. }
  1178. keyEstablishRec[index].state = KeyEstablishState_ConfirmPending;
  1179. return ZSuccess;
  1180. }
  1181. /*********************************************************************
  1182. * @fn zclGeneral_InitiateKeyEstablish_Rsp_CalculateKey
  1183. *
  1184. * @brief Calculate the Key using ECC library upon receipt of Initiate
  1185. Key Establishment Response.
  1186. *
  1187. * @param none
  1188. *
  1189. * @return ZStatus_t - ZFailure @ Unsupported
  1190. * ZCL_STATUS_MALFORMED_COMMAND
  1191. * ZCL_STATUS_CMD_HAS_RSP
  1192. */
  1193. static ZStatus_t zclGeneral_InitiateKeyEstablish_Rsp_CalculateKey( void )
  1194. {
  1195. uint8 index;
  1196. uint8 ret,tmp;
  1197. uint8 zData[KEY_ESTABLISH_SHARED_SECRET_LENGTH];
  1198. uint8 *keyBit;
  1199. uint8 MACu[KEY_ESTABLISH_MAC_LENGTH];
  1200. // It is possible to have multiple entries in the keyCalulationPending state.
  1201. // Here we assume the partner that starts the key establishment procedure earlier
  1202. // will have a smaller index in the table.
  1203. // However, this might not apply due to different processing capability of
  1204. // different processors.
  1205. if ( (index = zclGeneral_GetKeyEstablishRecIndex_State( KeyEstablishState_KeyCalculatePending ))
  1206. >= MAX_KEY_ESTABLISHMENT_REC_ENTRY )
  1207. {
  1208. return ZFailure;
  1209. }
  1210. // Turn off the radio before the key bit generation
  1211. tmp = false;
  1212. ZMacSetReq( ZMacRxOnIdle, &tmp ); // Set Receiver back to RxOnWhenIdle
  1213. // Generate the Key Bits
  1214. ret = ZSE_ECCKeyBitGenerate( zgStaticPrivateKey, keyEstablishRec[index].pLocalEPrivateKey,
  1215. keyEstablishRec[index].pLocalEPublicKey,
  1216. keyEstablishRec[index].pRemoteCertificate,
  1217. keyEstablishRec[index].pRemotePublicKey,
  1218. zgCAPublicKey, zData,
  1219. zclGeneral_KeyEstablishment_HashFunc,
  1220. zclKeyEstablish_YieldFunc, zclKeyEstablish_YieldLevel);
  1221. tmp = true;
  1222. ZMacSetReq( ZMacRxOnIdle, &tmp ); // Turn the radio back on
  1223. if ( ret != MCE_SUCCESS )
  1224. {
  1225. // Key Bit generation failure. Send terminate key command
  1226. zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
  1227. &(keyEstablishRec[index].dstAddr),
  1228. TermKeyStatus_BadKeyConfirm,
  1229. KEY_ESTABLISHMENT_AVG_TIMEOUT,
  1230. KEY_ESTABLISHMENT_SUITE,
  1231. false, zcl_SeqNum++ );
  1232. return ZFailure;
  1233. }
  1234. else
  1235. {
  1236. // Allocate buffer to store KDF(Z) = MacKey || KeyData
  1237. if ( (keyBit = osal_mem_alloc( KEY_ESTABLISH_KEY_DATA_LENGTH +
  1238. KEY_ESTABLISH_MAC_KEY_LENGTH)) == NULL )
  1239. {
  1240. return ZCL_STATUS_SOFTWARE_FAILURE; // Memory allocation failure
  1241. }
  1242. // Derive the keying data using KDF function
  1243. zclGeneral_KeyEstablishment_KeyDeriveFunction(zData,
  1244. KEY_ESTABLISH_SHARED_SECRET_LENGTH,
  1245. keyBit );
  1246. // Save the derived 128-bit keyData
  1247. osal_memcpy( keyEstablishRec[index].pMacKey, keyBit, KEY_ESTABLISH_KEY_DATA_LENGTH);
  1248. osal_memcpy( keyEstablishRec[index].pKey, &(keyBit[KEY_ESTABLISH_MAC_KEY_LENGTH]),
  1249. KEY_ESTABLISH_KEY_DATA_LENGTH);
  1250. // Calculate MAC(U). Note that the keyBit is also pointing to the macKey
  1251. zclGeneral_KeyEstablishment_GenerateMAC( index, TRUE, MACu );
  1252. osal_mem_free( keyBit );
  1253. // Send MAC(U) to the Partner
  1254. zclGeneral_KeyEstablish_Send_ConfirmKey( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
  1255. &(keyEstablishRec[index].dstAddr),
  1256. MACu,
  1257. false, zcl_SeqNum++ );
  1258. keyEstablishRec[index].state = KeyEstablishState_ConfirmPending;
  1259. return ZSuccess;
  1260. }
  1261. }
  1262. /*********************************************************************
  1263. * @fn zclGeneral_InitKeyEstablishRecTable
  1264. *
  1265. * @brief Initializae key establishment record table entries.
  1266. *
  1267. * @param none
  1268. *
  1269. * @return none
  1270. */
  1271. static void zclGeneral_InitKeyEstablishRecTable( void )
  1272. {
  1273. uint8 i;
  1274. for ( i = 0; i < MAX_KEY_ESTABLISHMENT_REC_ENTRY; i++ )
  1275. {
  1276. keyEstablishRec[i].dstAddr.addrMode = afAddrNotPresent;
  1277. keyEstablishRec[i].dstAddr.addr.shortAddr = INVALID_PARTNER_ADDR;
  1278. keyEstablishRec[i].state = KeyEstablishState_Idle;
  1279. keyEstablishRec[i].appTaskID = INVALID_TASK_ID;
  1280. }
  1281. }
  1282. /*********************************************************************
  1283. * @fn zclGeneral_GetKeyEstablishRecIndex
  1284. *
  1285. * @brief Get the index of a particular key establishment record.
  1286. * If the input is INVALID_PARTNER_ADDR, return an empty slot.
  1287. *
  1288. * @param partnerAddress - address of the partner that the local device
  1289. * is establishing key with.
  1290. *
  1291. * @return index of the record
  1292. */
  1293. static uint8 zclGeneral_GetKeyEstablishRecIndex( uint16 partnerAddress )
  1294. {
  1295. uint8 i;
  1296. // Find an existing entry or vacant entry, depends on what DstAddress is
  1297. for ( i = 0; i < MAX_KEY_ESTABLISHMENT_REC_ENTRY ; i++ )
  1298. {
  1299. if ( keyEstablishRec[i].dstAddr.addr.shortAddr == partnerAddress )
  1300. {
  1301. // entry found
  1302. break;
  1303. }
  1304. }
  1305. return i;
  1306. }
  1307. /*********************************************************************
  1308. * @fn zclGeneral_GetKeyEstablishRecIndex
  1309. *
  1310. * @brief Get the index of a particular key establishment record.
  1311. * If the input is INVALID_PARTNER_ADDR, return an empty slot.
  1312. *
  1313. * @param state - state to find.
  1314. *
  1315. * @return index of the record
  1316. */
  1317. static uint8 zclGeneral_GetKeyEstablishRecIndex_State( KeyEstablishState_t state )
  1318. {
  1319. uint8 i;
  1320. // Find an existing entry or vacant entry, depends on what DstAddress is
  1321. for ( i = 0; i < MAX_KEY_ESTABLISHMENT_REC_ENTRY ; i++ )
  1322. {
  1323. if ( keyEstablishRec[i].state == state )
  1324. {
  1325. // entry found
  1326. break;
  1327. }
  1328. }
  1329. return i;
  1330. }
  1331. /*********************************************************************
  1332. * @fn zclGeneral_RemoveKeyEstablishRec
  1333. *
  1334. * @brief Reset a particular key establishment record to initial value.
  1335. *
  1336. * @param partnerAddress - address of the partner that the local device
  1337. * is establishing key with.
  1338. *
  1339. * @return ZStatus_t - ZSuccess or ZFailure
  1340. */
  1341. static ZStatus_t zclGeneral_RemoveKeyEstablishRec( uint16 partnerAddress )
  1342. {
  1343. uint8 index;
  1344. index = zclGeneral_GetKeyEstablishRecIndex( partnerAddress );
  1345. if ( index < MAX_KEY_ESTABLISHMENT_REC_ENTRY )
  1346. {
  1347. // Reset the entry
  1348. keyEstablishRec[index].dstAddr.addrMode = afAddrNotPresent;
  1349. keyEstablishRec[index].dstAddr.addr.shortAddr = INVALID_PARTNER_ADDR;
  1350. // Free the allocated memory
  1351. osal_mem_free( keyEstablishRec[index].pLocalEPrivateKey );
  1352. return ZSuccess;
  1353. }
  1354. return ZFailure;
  1355. }
  1356. /*********************************************************************
  1357. * @fn zclGeneral_AddKeyEstablishRec
  1358. *
  1359. * @brief Add a new key establishment record. If one already exist,
  1360. * remove the existng entry. After initialization, fill in
  1361. * partner short address and extended address. If partner extended
  1362. * address not available, return failure.
  1363. *
  1364. * @param addr - address of the partner
  1365. *
  1366. * @return index - 0 ~ (MAX_KEY_ESTABLISHMENT_REC_ENTRY-1) @ success
  1367. * MAX_KEY_ESTABLISHMENT_REC_ENTRY @ failure due to rec
  1368. * table full or partner IEEE address not available
  1369. */
  1370. static uint8 zclGeneral_AddKeyEstablishRec( afAddrType_t *addr )
  1371. {
  1372. uint8 index;
  1373. uint8 *pBuf;
  1374. // Search for all current key establishment record
  1375. // If not found, create a new entry
  1376. if ( ( index = zclGeneral_GetKeyEstablishRecIndex(addr->addr.shortAddr) )
  1377. < MAX_KEY_ESTABLISHMENT_REC_ENTRY )
  1378. {
  1379. // expire the existing entry for this address
  1380. zclGeneral_RemoveKeyEstablishRec( addr->addr.shortAddr );
  1381. }
  1382. // Create a new Entry
  1383. if ( (index = zclGeneral_GetKeyEstablishRecIndex(INVALID_PARTNER_ADDR))
  1384. < MAX_KEY_ESTABLISHMENT_REC_ENTRY )
  1385. {
  1386. osal_memset( &(keyEstablishRec[index]), 0, sizeof ( zclKeyEstablishRec_t ) );
  1387. // Fill in initial values
  1388. keyEstablishRec[index].dstAddr.addrMode = addr->addrMode;
  1389. keyEstablishRec[index].dstAddr.addr.shortAddr = addr->addr.shortAddr;
  1390. keyEstablishRec[index].dstAddr.endPoint = addr->endPoint;
  1391. keyEstablishRec[index].age = KEY_ESTABLISHMENT_REC_EXPIRY_TIME;
  1392. keyEstablishRec[index].state = KeyEstablishState_Idle;
  1393. // extAddr will be unknown when the initator first initiates the key establishment
  1394. // It will be filled in later after the remote certificate is received.
  1395. // Allocate memory for the rest of the fields
  1396. if( ( pBuf = osal_mem_alloc( ZCL_KEY_ESTABLSIHMENT_PRIVATE_KEY_LENTGH +
  1397. ZCL_KEY_ESTABLISHMENT_PUBLIC_KEY_LENGTH +
  1398. ZCL_KEY_ESTABLISHMENT_PUBLIC_KEY_LENGTH +
  1399. ZCL_KEY_ESTABLISHMENT_CERTIFICATE_LENGTH +
  1400. KEY_ESTABLISH_KEY_DATA_LENGTH +
  1401. KEY_ESTABLISH_MAC_KEY_LENGTH )) != NULL )
  1402. {
  1403. keyEstablishRec[index].pLocalEPrivateKey = pBuf;
  1404. pBuf += ZCL_KEY_ESTABLSIHMENT_PRIVATE_KEY_LENTGH;
  1405. keyEstablishRec[index].pLocalEPublicKey = pBuf;
  1406. pBuf += ZCL_KEY_ESTABLISHMENT_PUBLIC_KEY_LENGTH;
  1407. keyEstablishRec[index].pRemotePublicKey = pBuf;
  1408. pBuf += ZCL_KEY_ESTABLISHMENT_PUBLIC_KEY_LENGTH;
  1409. keyEstablishRec[index].pRemoteCertificate = pBuf;
  1410. pBuf += ZCL_KEY_ESTABLISHMENT_CERTIFICATE_LENGTH;
  1411. keyEstablishRec[index].pKey = pBuf;
  1412. pBuf += KEY_ESTABLISH_KEY_DATA_LENGTH;
  1413. keyEstablishRec[index].pMacKey = pBuf;
  1414. }
  1415. else
  1416. return ZMemError;
  1417. }
  1418. return index;
  1419. }
  1420. /*********************************************************************
  1421. * @fn zclGeneral_AgeKeyEstablishRec
  1422. *
  1423. * @brief Function to age Key Establish Rec. This function is called
  1424. * as event handler for KEY_ESTABLISHMENT_REC_AGING_EVT every
  1425. * second.
  1426. *
  1427. * @param none
  1428. *
  1429. * @return none
  1430. */
  1431. static void zclGeneral_AgeKeyEstablishRec( void )
  1432. {
  1433. uint8 i;
  1434. for ( i = 0; i < MAX_KEY_ESTABLISHMENT_REC_ENTRY; i++ )
  1435. {
  1436. // Only age valid rec entry
  1437. if (keyEstablishRec[i].dstAddr.addrMode == afAddrNotPresent)
  1438. continue;
  1439. if (--(keyEstablishRec[i].age) == 0)
  1440. {
  1441. keyEstablishRec[i].dstAddr.addrMode = afAddrNotPresent;
  1442. keyEstablishRec[i].dstAddr.addr.shortAddr = INVALID_PARTNER_ADDR;
  1443. }
  1444. }
  1445. }
  1446. /*********************************************************************
  1447. * @fn zclGeneral_KeyEstablishment_GetRandom
  1448. *
  1449. * @brief Fill in a buffer with random numbers
  1450. *
  1451. * @param buffer - output buffer
  1452. * len - length of the buffer
  1453. *
  1454. * @return MCE_SUCCESS indicates success
  1455. */
  1456. static int zclGeneral_KeyEstablishment_GetRandom(unsigned char *buffer, unsigned long len)
  1457. {
  1458. uint8 i;
  1459. uint8 *pBuf;
  1460. pBuf = buffer;
  1461. for ( i = 0; i < len; i++ )
  1462. {
  1463. *pBuf++ = LO_UINT16( osal_rand() );
  1464. }
  1465. return MCE_SUCCESS;
  1466. }
  1467. /*********************************************************************
  1468. * @fn zclGeneral_KeyEstablishment_HashFunc
  1469. *
  1470. * @brief Hash Function
  1471. *
  1472. * @param digest - output buffer 16 bytes
  1473. * len - length of the input buffer
  1474. * data - input buffer
  1475. *
  1476. * @return MCE_SUCCESS indicates success
  1477. */
  1478. static int zclGeneral_KeyEstablishment_HashFunc(unsigned char *digest, unsigned long len, unsigned char *data)
  1479. {
  1480. len *= 8; // Convert to bit length
  1481. sspMMOHash( NULL, 0, data, (uint16)len, digest );
  1482. return MCE_SUCCESS;
  1483. }
  1484. /*********************************************************************
  1485. * @fn zclGeneral_KeyEstablishment_KeyDeriveFunction
  1486. *
  1487. * @brief Key Derive Function (ANSI X9.63).
  1488. * Note this is not a generalized KDF. It only applies to the KDF
  1489. * specified in ZigBee SE profile. Only the first two hashed keys
  1490. * are calculated and concatenated.
  1491. *
  1492. * @param zData - input shared secret (length = KEY_ESTABLISH_SHARED_SECRET_LENGTH)
  1493. * keyBitLen - input key data length
  1494. * keyBit - output buffer ( 16*2 bytes)
  1495. *
  1496. * @return none
  1497. */
  1498. static void zclGeneral_KeyEstablishment_KeyDeriveFunction( uint8 *zData,
  1499. uint8 keyBitLen,
  1500. uint8 *keyBit )
  1501. {
  1502. uint8 hashCounter[4] = {0x00, 0x00, 0x00, 0x01};
  1503. uint8 hashedData[KEY_ESTABLISH_SHARED_SECRET_LENGTH + 4];
  1504. uint8 bitLen;
  1505. bitLen = (keyBitLen + 4 ) * 8;
  1506. // Calculate K1: Ki = Hash(Z || Counter1 )
  1507. osal_memcpy( hashedData, zData, KEY_ESTABLISH_SHARED_SECRET_LENGTH );
  1508. osal_memcpy( &(hashedData[KEY_ESTABLISH_SHARED_SECRET_LENGTH]), hashCounter, 4);
  1509. sspMMOHash(NULL, 0, hashedData, bitLen, keyBit);
  1510. // Indrement the counter
  1511. hashedData[KEY_ESTABLISH_SHARED_SECRET_LENGTH + 3] = 0x02;
  1512. sspMMOHash(NULL, 0, hashedData, bitLen, &(keyBit[KEY_ESTABLISH_KEY_DATA_LENGTH]));
  1513. }
  1514. /*********************************************************************
  1515. * @fn zclGeneral_KeyEstablishment_GenerateMAC
  1516. *
  1517. * @brief Key Derive Function (ANSI X9.63).
  1518. * Note this is not a generalized KDF. It only applies to the KDF
  1519. * specified in ZigBee SE profile. Only the first two hashed keys
  1520. * are calculated and concatenated.
  1521. *
  1522. * @param recIndex - input key establishment record index
  1523. * AesKey - input AES key ( 16 bytes )
  1524. * MAC - output buffer ( 16 bytes )
  1525. *
  1526. * @return ZStatus_t - success
  1527. */
  1528. static ZStatus_t zclGeneral_KeyEstablishment_GenerateMAC(uint8 recIndex,
  1529. uint8 ifMACu,
  1530. uint8 *MAC)
  1531. {
  1532. uint8 M;
  1533. uint8 *hashBuf;
  1534. uint16 bufLen;
  1535. // Assumption for M(U) and M(V) is: M(U) = 0x02, M(V) = 0x03
  1536. if( ifMACu == TRUE )
  1537. {
  1538. M = 0x02; // Assumption
  1539. }
  1540. else
  1541. {
  1542. M = 0x03; // Assumption
  1543. }
  1544. // When this step is executed, it is assumed the device has already
  1545. // obtained the IEEE address of the partner device.
  1546. if ( keyEstablishRec[recIndex].partnerExtAddr == NULL )
  1547. {
  1548. return ZFailure; // Partner IEEE address not available, return failure.
  1549. }
  1550. // MAC(U) = MAC(MacKey) { M(U) || ID(U) || ID(V) || E(U) || E(V) }
  1551. bufLen = (1 + (Z_EXTADDR_LEN * 2) + (ZCL_KEY_ESTABLISHMENT_PUBLIC_KEY_LENGTH * 2));
  1552. if( ( hashBuf = osal_mem_alloc( (bufLen) )) == NULL )
  1553. {
  1554. return ZMemError; // Memory allocation error
  1555. }
  1556. // Fill in the buffer
  1557. hashBuf[0] = M; // M(U)
  1558. bufLen = bufLen * 8; // Convert to bitlength
  1559. if ( (keyEstablishRec[recIndex].role == KEY_ESTABLISHMENT_INITIATOR && ifMACu == TRUE) ||
  1560. (keyEstablishRec[recIndex].role == KEY_ESTABLISHMENT_RESPONDER && ifMACu == FALSE))
  1561. {
  1562. // MAC = MAC(MacKey) { M() || ID(L) || ID(R) || E(L) || E(R) }
  1563. // L - Local, R - Remote
  1564. SSP_MemCpyReverse( &(hashBuf[1]), NLME_GetExtAddr(), Z_EXTADDR_LEN); // ID(U)
  1565. SSP_MemCpyReverse( &(hashBuf[1+Z_EXTADDR_LEN]), keyEstablishRec[recIndex].partnerExtAddr,
  1566. Z_EXTADDR_LEN); // ID(V)
  1567. osal_memcpy( &(hashBuf[1 + (2 * Z_EXTADDR_LEN)]), // E(U)
  1568. keyEstablishRec[recIndex].pLocalEPublicKey,
  1569. ZCL_KEY_ESTABLISHMENT_PUBLIC_KEY_LENGTH );
  1570. osal_memcpy( &(hashBuf[1 + (2 * Z_EXTADDR_LEN) + ZCL_KEY_ESTABLISHMENT_PUBLIC_KEY_LENGTH]), // E(V)
  1571. keyEstablishRec[recIndex].pRemotePublicKey, ZCL_KEY_ESTABLISHMENT_PUBLIC_KEY_LENGTH );
  1572. SSP_KeyedHash (hashBuf, bufLen, keyEstablishRec[recIndex].pMacKey, MAC);
  1573. }
  1574. else
  1575. {
  1576. // MAC = MAC(MacKey) { M() || ID(R) || ID(L) || E(R) || E(L) }
  1577. // L - Local, R - Remote
  1578. SSP_MemCpyReverse( &(hashBuf[1]), keyEstablishRec[recIndex].partnerExtAddr,
  1579. Z_EXTADDR_LEN); // ID(R)
  1580. SSP_MemCpyReverse( &(hashBuf[1 + Z_EXTADDR_LEN]), NLME_GetExtAddr(), Z_EXTADDR_LEN); // ID(L)
  1581. osal_memcpy( &(hashBuf[ 1 + (2 * Z_EXTADDR_LEN)]), // E(R)
  1582. keyEstablishRec[recIndex].pRemotePublicKey,
  1583. ZCL_KEY_ESTABLISHMENT_PUBLIC_KEY_LENGTH );
  1584. osal_memcpy( &(hashBuf[1 + (2 * Z_EXTADDR_LEN) + ZCL_KEY_ESTABLISHMENT_PUBLIC_KEY_LENGTH]), // E(U)
  1585. keyEstablishRec[recIndex].pLocalEPublicKey,
  1586. ZCL_KEY_ESTABLISHMENT_PUBLIC_KEY_LENGTH );
  1587. SSP_KeyedHash (hashBuf, bufLen, keyEstablishRec[recIndex].pMacKey, MAC);
  1588. }
  1589. osal_mem_free(hashBuf);
  1590. return ZSuccess;
  1591. }
  1592. #endif // ZCL_KEY_ESTABLISH
  1593. /*********************************************************************
  1594. * @fn zclGeneral_KeyEstablishment_ECDSASign
  1595. *
  1596. * @brief Creates an ECDSA signature of a message digest.
  1597. *
  1598. * @param input - input data buffer
  1599. * inputLen - byte length of the input buffer
  1600. * output - output buffer ( 21x2 bytes )
  1601. *
  1602. * @return ZStatus_t - success
  1603. */
  1604. ZStatus_t zclGeneral_KeyEstablishment_ECDSASign( uint8 *input, uint8 inputLen,
  1605. uint8 *output)
  1606. {
  1607. uint8 msgDigest[KEY_ESTABLISH_AES_MMO_HASH_SIZE];
  1608. uint16 bitLen;
  1609. #if defined (ZCL_KEY_ESTABLISH)
  1610. uint8 status;
  1611. #endif
  1612. bitLen = inputLen * 8;
  1613. // First hash the input buffer
  1614. sspMMOHash(NULL, 0, input, bitLen, msgDigest);
  1615. #if defined (ZCL_KEY_ESTABLISH)
  1616. status = ZSE_ECDSASign( (unsigned char*)zgStaticPrivateKey, (unsigned char*)msgDigest,
  1617. zclGeneral_KeyEstablishment_GetRandom,
  1618. (unsigned char*)output, (unsigned char*)output + KEY_ESTABLISH_POINT_ORDER_SIZE,
  1619. zclKeyEstablish_YieldFunc, zclKeyEstablish_YieldLevel );
  1620. if (status == MCE_SUCCESS )
  1621. return ZSuccess;
  1622. #endif
  1623. return ZFailure;
  1624. }
  1625. /*********************************************************************
  1626. * @fn zclGeneral_KeyEstablishment_ECDSAVerify
  1627. *
  1628. * @brief Verify an ECDSA signature of a message digest.
  1629. *
  1630. * @param input - input data buffer
  1631. * inputLen - byte length of the input buffer
  1632. * signature - input signature ( 21x2 bytes )
  1633. *
  1634. * @return ZSuccess - success verify
  1635. * ZFailure - fail to verify
  1636. */
  1637. ZStatus_t zclGeneral_KeyEstablishment_ECDSAVerify( uint8 *input, uint8 inputLen,
  1638. uint8 *signature)
  1639. {
  1640. uint8 msgDigest[KEY_ESTABLISH_AES_MMO_HASH_SIZE];
  1641. uint16 bitLen;
  1642. #if defined (ZCL_KEY_ESTABLISH)
  1643. uint8 ret;
  1644. #endif
  1645. bitLen = inputLen * 8;
  1646. // First hash the input buffer
  1647. sspMMOHash(NULL, 0, input, bitLen, msgDigest);
  1648. #if defined (ZCL_KEY_ESTABLISH)
  1649. ret = ZSE_ECDSAVerify( (unsigned char*)zgRemotePublicKey, (unsigned char*)msgDigest,
  1650. (unsigned char*)signature, (unsigned char*)signature + KEY_ESTABLISH_POINT_ORDER_SIZE,
  1651. zclKeyEstablish_YieldFunc, zclKeyEstablish_YieldLevel );
  1652. if ( ret == MCE_SUCCESS )
  1653. return ZSuccess;
  1654. #endif
  1655. return ZFailure;
  1656. }
  1657. /***************************************************************************
  1658. ****************************************************************************/