1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236 |
- /******************************************************************************
- Filename: zcl_key_establish.c
- Revised: $Date: 2012-04-02 17:02:19 -0700 (Mon, 02 Apr 2012) $
- Revision: $Revision: 29996 $
- Description: Zigbee Cluster Library - General Function Domain - key
- establishment cluster.
- This application receives ZCL messages and handles them
- within the ZCL layer, without passing to application.
- Copyright 2007-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.
- ******************************************************************************/
- /*********************************************************************
- * INCLUDES
- */
- #include "ZComDef.h"
- #include "OSAL.h"
- #include "OSAL_Nv.h"
- #include "zcl.h"
- #include "ZDApp.h"
- #include "ssp_hash.h"
- #include "AddrMgr.h"
- #include "ZDSecMgr.h"
- #include "APSMEDE.h"
- #include "eccapi.h"
- #include "zcl_key_establish.h"
- #include "DebugTrace.h"
- #include "se.h"
- #if defined ( INTER_PAN )
- #include "stub_aps.h"
- #endif
- /*********************************************************************
- * MACROS
- */
- /*********************************************************************
- * CONSTANTS
- */
- #define KEY_ESTABLISHMENT_DEVICE_VERSION 0
- #define KEY_ESTABLISHMENT_FLAGS 0
- #define KEY_ESTABLISHMENT_SUITE 1 // For CBKE with ECMQV
- #define KEY_ESTABLISHMENT_AVG_TIMEOUT ( 2 * ( ZCL_KEY_ESTABLISHMENT_KEY_GENERATE_TIMEOUT + \
- ZCL_KEY_ESTABLISHMENT_MAC_GENERATE_TIMEOUT ) )
- #define ZCL_KEY_ESTABLISH_DEVICE_VERSION 0
- #define ZCL_KEY_ESTABLISH_FLAGS 0
- #define INVALID_TASK_ID 0xFF
- /*********************************************************************
- * TYPEDEFS
- */
- /*********************************************************************
- * GLOBAL VARIABLES
- */
- // For debug and testing purpose, use a fixed ephermeral key pair instead
- // of the randomly generated one.
- #if defined (DEBUG_STATIC_ECC)
- uint8 public1[22] = {
- 0x03, 0x06, 0xAB, 0x52, 0x06, 0x22, 0x01, 0xD9,
- 0x95, 0xB8, 0xB8, 0x59, 0x1F, 0x3F, 0x08, 0x6A,
- 0x3A, 0x2E, 0x21, 0x4D, 0x84, 0x5E
- };
- uint8 private1[21] = {
- 0x03, 0xD4, 0x8C, 0x72, 0x10, 0xDD, 0xBC, 0xC4,
- 0xFB, 0x2E, 0x5E, 0x7A, 0x0A, 0xA1, 0x6A, 0x0D,
- 0xB8, 0x95, 0x40, 0x82, 0x0B
- };
- uint8 public2[22] = {
- 0x03, 0x00, 0xE1, 0x17, 0xC8, 0x6D, 0x0E, 0x7C,
- 0xD1, 0x28, 0xB2, 0xF3, 0x4E, 0x90, 0x76, 0xCF,
- 0xF2, 0x4A, 0xF4, 0x6D, 0x72, 0x88
- };
- uint8 private2[21] = {
- 0x00, 0x13, 0xD3, 0x6D, 0xE4, 0xB1, 0xEA, 0x8E,
- 0x22, 0x73, 0x9C, 0x38, 0x13, 0x70, 0x82, 0x3F,
- 0x40, 0x4B, 0xFF, 0x88, 0x62
- };
- #endif
- zclOptionRec_t zclKeyEstablish_Options[1] =
- {
- {
- ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
- ( AF_ACK_REQUEST ),
- },
- };
- YieldFunc *zclKeyEstablish_YieldFunc = NULL;
- uint8 zclKeyEstablish_YieldLevel = 0;
- #if defined (NWK_AUTO_POLL)
- uint16 zclSavedPollRate = POLL_RATE;
- #endif
- /*********************************************************************
- * GLOBAL FUNCTIONS
- */
- extern uint8* SSP_MemCpyReverse( uint8* dst, uint8* src, unsigned int len );
- /*********************************************************************
- * LOCAL VARIABLES
- */
- #if defined(ZCL_KEY_ESTABLISH)
- static uint8 zcl_KeyEstablishment_TaskID; // Task ID of the key Establishment cluster
- #endif
- /*********************************************************************
- * SIMPLE DESCRIPTOR
- */
- // This is the Cluster ID List and should be filled with Application
- // specific cluster IDs.
- #define ZCL_KEY_ESTABLISH_MAX_INCLUSTERS 1
- const cId_t zclKeyEstablish_InClusterList[ZCL_KEY_ESTABLISH_MAX_INCLUSTERS] =
- {
- ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
- };
- #define ZCL_KEY_ESTABLISH_MAX_OUTCLUSTERS 1
- const cId_t zclKeyEstablish_OutClusterList[ZCL_KEY_ESTABLISH_MAX_OUTCLUSTERS] =
- {
- ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
- };
- SimpleDescriptionFormat_t zclKeyEstablish_SimpleDesc =
- {
- ZCL_KEY_ESTABLISHMENT_ENDPOINT, // int Endpoint;
- ZCL_SE_PROFILE_ID, // uint16 AppProfId[2];
- ZCL_SE_DEVICEID_PHYSICAL, // uint16 AppDeviceId[2];
- ZCL_KEY_ESTABLISH_DEVICE_VERSION, // int AppDevVer:4;
- ZCL_KEY_ESTABLISH_FLAGS, // int AppFlags:4;
- ZCL_KEY_ESTABLISH_MAX_INCLUSTERS, // byte AppNumInClusters;
- (cId_t *)zclKeyEstablish_InClusterList, // byte *pAppInClusterList;
- ZCL_KEY_ESTABLISH_MAX_OUTCLUSTERS, // byte AppNumInClusters;
- (cId_t *)zclKeyEstablish_OutClusterList // byte *pAppInClusterList;
- };
- #if defined (ZCL_KEY_ESTABLISH)
- // Endpoint for Key Establishment Cluster
- static endPointDesc_t zclKeyEstablish_Ep =
- {
- ZCL_KEY_ESTABLISHMENT_ENDPOINT, // Test endpoint
- &zcl_TaskID,
- (SimpleDescriptionFormat_t *)&zclKeyEstablish_SimpleDesc,
- (afNetworkLatencyReq_t)0 // No Network Latency req
- };
- #endif
- // Pointer to the application sequence number for ZCL commands
- #if defined ( ZCL_KEY_ESTABLISH)
- static uint8 zclKeyEstablishPluginRegisted = FALSE;
- static zclKeyEstablishRec_t keyEstablishRec[MAX_KEY_ESTABLISHMENT_REC_ENTRY];
- /*********************************************************************
- * LOCAL FUNCTIONS
- */
- static ZStatus_t zclGeneral_KeyEstablish_HdlIncoming( zclIncoming_t *pInMsg );
- static ZStatus_t zclGeneral_KeyEstablish_HdlInSpecificCommands( zclIncoming_t *pInMsg );
- // Key Establish Cluster Command Processing functions
- static ZStatus_t zclGeneral_ProcessInCmd_InitiateKeyEstablish( zclIncoming_t *pInMsg );
- static ZStatus_t zclGeneral_ProcessInCmd_InitiateKeyEstablishRsp( zclIncoming_t *pInMsg );
- static ZStatus_t zclGeneral_ProcessInCmd_EphemeralDataReq( zclIncoming_t *pInMsg );
- static ZStatus_t zclGeneral_ProcessInCmd_EphemeralDataRsp( zclIncoming_t *pInMsg );
- static ZStatus_t zclGeneral_ProcessInCmd_ConfirmKey( zclIncoming_t *pInMsg );
- static ZStatus_t zclGeneral_ProcessInCmd_ConfirmKeyRsp( zclIncoming_t *pInMsg );
- static ZStatus_t zclGeneral_ProcessInCmd_TerminateKeyEstablish( zclIncoming_t *pInMsg );
- // Event driven key calculation function
- static ZStatus_t zclGeneral_InitiateKeyEstablish_Cmd_CalculateKey(void);
- static ZStatus_t zclGeneral_InitiateKeyEstablish_Rsp_CalculateKey(void);
- // Key establishment rec table management function
- static void zclGeneral_InitKeyEstablishRecTable( void );
- static uint8 zclGeneral_GetKeyEstablishRecIndex( uint16 partnerAddress );
- static uint8 zclGeneral_GetKeyEstablishRecIndex_State( KeyEstablishState_t state );
- static uint8 zclGeneral_AddKeyEstablishRec( afAddrType_t *addr );
- static void zclGeneral_AgeKeyEstablishRec( void );
- static void zclGeneral_ResetKeyEstablishRec( uint8 index );
- // Call back function supplying to ECC library
- static int zclGeneral_KeyEstablishment_GetRandom(unsigned char *buffer, unsigned long len);
- static int zclGeneral_KeyEstablishment_HashFunc(unsigned char *digest, unsigned long len, unsigned char *data);
- // Security related functions
- static void zclGeneral_KeyEstablishment_KeyDeriveFunction( uint8 *zData,
- uint8 keyBitLen,
- uint8 *keyBit );
- static ZStatus_t zclGeneral_KeyEstablishment_GenerateMAC(uint8 recIndex,
- uint8 ifMACu,
- uint8 *MAC);
- /*********************************************************************
- * @fn zclGeneral_KeyEstablish_Init
- *
- * @brief Call to initialize the Key Establishment Task
- *
- * @param task_id
- *
- * @return none
- */
- void zclGeneral_KeyEstablish_Init( uint8 task_id )
- {
- zcl_KeyEstablishment_TaskID = task_id;
- // Register for the key establishment cluster endpoint
- afRegister( &zclKeyEstablish_Ep );
- zcl_registerClusterOptionList( ZCL_KEY_ESTABLISHMENT_ENDPOINT, 1,
- zclKeyEstablish_Options );
- // Register as a ZCL Plugin
- if ( !zclKeyEstablishPluginRegisted )
- {
- zcl_registerPlugin( ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
- ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
- zclGeneral_KeyEstablish_HdlIncoming );
- zclKeyEstablishPluginRegisted = TRUE;
- }
- // Initialize the keyEstablishRec table
- zclGeneral_InitKeyEstablishRecTable();
- }
- /*********************************************************************
- * @fn zclKeyEstablish_event_loop
- *
- * @brief Event Loop Processor for Key establish task.
- *
- * @param task_id - TaskId
- * events - events
- *
- * @return none
- */
- uint16 zclKeyEstablish_event_loop( uint8 task_id, uint16 events )
- {
- afIncomingMSGPacket_t *MSGpkt;
- if ( events & SYS_EVENT_MSG )
- {
- while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( task_id )) )
- {
- switch ( MSGpkt->hdr.event )
- {
- default:
- break;
- }
- // Release the memory
- osal_msg_deallocate( (uint8 *)MSGpkt );
- }
- // return unprocessed events
- return (events ^ SYS_EVENT_MSG);
- }
- if ( events & KEY_ESTABLISHMENT_REC_AGING_EVT )
- {
- zclGeneral_AgeKeyEstablishRec();
- return ( events ^ KEY_ESTABLISHMENT_REC_AGING_EVT );
- }
- if ( events & KEY_ESTABLISHMENT_CMD_PROCESS_EVT )
- {
- zclGeneral_InitiateKeyEstablish_Cmd_CalculateKey();
- return ( events ^ KEY_ESTABLISHMENT_CMD_PROCESS_EVT );
- }
- if ( events & KEY_ESTABLISHMENT_RSP_PROCESS_EVT )
- {
- zclGeneral_InitiateKeyEstablish_Rsp_CalculateKey();
- return ( events ^ KEY_ESTABLISHMENT_RSP_PROCESS_EVT );
- }
- // Discard unknown events
- return 0;
- }
- /*********************************************************************
- * @fn zclGeneral_KeyEstablish_InitiateKeyEstablishment
- *
- * @brief Call to initiate key establishment with partner device
- *
- * @param appTaskID - task ID of the application that initates the key establish
- * @param partnerAddr - short address and endpoint of the partner to establish key with
- * @param seqNum - pointer to the sequence number of application (ZCL)
- *
- * @return ZStatus_t ZSuccess or ZFailure
- */
- ZStatus_t zclGeneral_KeyEstablish_InitiateKeyEstablishment(uint8 appTaskID,
- afAddrType_t *partnerAddr,
- uint8 seqNum)
- {
- uint8 *implicitCert, index;
- // Assign the app seqnum pointer
- zcl_SeqNum = seqNum;
- // Start a new key establishment rec entry
- index = zclGeneral_AddKeyEstablishRec( partnerAddr );
- if( index < MAX_KEY_ESTABLISHMENT_REC_ENTRY ) // valid entry
- {
- keyEstablishRec[index].role = KEY_ESTABLISHMENT_INITIATOR;
- // Assign the application task ID that initiates the key establishment
- keyEstablishRec[index].appTaskID = appTaskID;
- }
- else
- {
- return ZFailure;
- }
- // Generate Ephemeral Public/Private Key Pair
- ZSE_ECCGenerateKey( ( unsigned char *)keyEstablishRec[index].pLocalEPrivateKey,
- ( unsigned char *)keyEstablishRec[index].pLocalEPublicKey,
- zclGeneral_KeyEstablishment_GetRandom,
- zclKeyEstablish_YieldFunc, zclKeyEstablish_YieldLevel);
- #if defined (DEBUG_STATIC_ECC)
- // For debug and testing purpose, use a fixed ephermeral key pair instead
- // of the randomly generated one.
- osal_memcpy( keyEstablishRec[index].pLocalEPrivateKey, private1, 21 );
- osal_memcpy( keyEstablishRec[index].pLocalEPublicKey, public1, 22 );
- #endif
- keyEstablishRec[index].state = KeyEstablishState_InitiatePending;
- if ((implicitCert = osal_mem_alloc(ZCL_KE_IMPLICIT_CERTIFICATE_LEN)) == NULL)
- {
- return ZCL_STATUS_SOFTWARE_FAILURE; // Memory allocation failure.
- }
- osal_nv_read(ZCD_NV_IMPLICIT_CERTIFICATE, 0, ZCL_KE_IMPLICIT_CERTIFICATE_LEN, implicitCert);
- // Send Initiate Key Establishment Command
- zclGeneral_KeyEstablish_Send_InitiateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
- partnerAddr,
- KEY_ESTABLISHMENT_SUITE,
- ZCL_KEY_ESTABLISHMENT_EKEY_GENERATE_TIMEOUT,
- ZCL_KEY_ESTABLISHMENT_MAC_GENERATE_TIMEOUT + ZCL_KEY_ESTABLISHMENT_KEY_GENERATE_TIMEOUT,
- implicitCert, TRUE, zcl_SeqNum++ );
- // Start the Key Establishment aging timer, this has to be started to make sure the record
- // is going to be deleted in the event that "Key Establishment Response" is not received for
- // any reason. This way we do not have hanging records in the table and memory leak issues.
- osal_start_reload_timer( zcl_KeyEstablishment_TaskID, KEY_ESTABLISHMENT_REC_AGING_EVT,
- KEY_ESTABLISHMENT_REC_AGING_INTERVAL );
- osal_mem_free(implicitCert);
- #if defined (NWK_AUTO_POLL)
- // Start the key establishment process and set the Key Establish poll rate
- zclSavedPollRate = zgPollRate;
- NLME_SetPollRate(ZCL_KEY_ESTABLISH_POLL_RATE);
- #endif
- return ZSuccess;
- }
- /*********************************************************************
- * @fn zclGeneral_KeyEstablish_Send_InitiateKeyEstablishment
- *
- * @brief Call to send out a Initiate Key Establishment Command
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param keyEstablishmentSuite - key establishment suite bitmap
- * @param keyGenerateTime - how long it takes to generate key
- * @param macGenerateTime - how long it takes to generate mac
- * @param certificate - identity. For CBKE, it's the implicit certificate.
- * @param disableDefaultRsp - disable default response
- * @param seqNum - ZCL sequence number
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_KeyEstablish_Send_InitiateKeyEstablishment( uint8 srcEP, afAddrType_t *dstAddr,
- uint16 keyEstablishmentSuite,
- uint8 keyGenerateTime,
- uint8 macGenerateTime,
- uint8 *certificate,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 *buf;
- uint8 *pBuf;
- uint8 status;
- uint8 bufLen;
- (void)srcEP; // Intentionally unreferenced parameter
- // keyEstablishmentSuite + eDataGenerateTime + macGenerateTime + certificate
- bufLen = 2 + 1 + 1 + ZCL_KE_IMPLICIT_CERTIFICATE_LEN;
- if ((buf = osal_mem_alloc(bufLen)) == NULL)
- {
- return ZMemError;
- }
- pBuf = buf;
- *pBuf++ = LO_UINT16( keyEstablishmentSuite );
- *pBuf++ = HI_UINT16( keyEstablishmentSuite );
- *pBuf++ = keyGenerateTime;
- *pBuf++ = macGenerateTime;
- osal_memcpy( pBuf, certificate, ZCL_KE_IMPLICIT_CERTIFICATE_LEN );
- status = zcl_SendCommand( ZCL_KEY_ESTABLISHMENT_ENDPOINT, dstAddr,
- ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
- COMMAND_INITIATE_KEY_ESTABLISHMENT, TRUE,
- ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp,
- 0, seqNum, bufLen, buf );
- osal_mem_free(buf);
- return status;
- }
- /*********************************************************************
- * @fn zclGeneral_KeyEstablish_Send_EphemeralDataReq
- *
- * @brief Call to send out a Ephemeral Data Request Command
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param eData - ephemeral data.
- * @param disableDefaultRsp - disable default response
- * @param seqNum - ZCL sequence number
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_KeyEstablish_Send_EphemeralDataReq( uint8 srcEP, afAddrType_t *dstAddr,
- uint8 *eData,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- return zcl_SendCommand( srcEP, dstAddr,
- ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
- COMMAND_EPHEMERAL_DATA_REQUEST, TRUE,
- ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp,
- 0, seqNum, ZCL_KE_CA_PUBLIC_KEY_LEN, eData );
- }
- /*********************************************************************
- * @fn zclGeneral_KeyEstablish_Send_ConfirmKey
- *
- * @brief Call to send out a Confirm Key Command
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param mac - MAC.
- * @param disableDefaultRsp - disable default response
- * @param seqNum - ZCL sequence number
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_KeyEstablish_Send_ConfirmKey( uint8 srcEP, afAddrType_t *dstAddr,
- uint8 *mac,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- return (zcl_SendCommand(srcEP, dstAddr,
- ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
- COMMAND_CONFIRM_KEY, TRUE,
- ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp,
- 0, seqNum, KEY_ESTABLISH_MAC_LENGTH, mac ));
- }
- /*********************************************************************
- * @fn zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment
- *
- * @brief Call to send out a Terminate Key Establishment Command
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param status - status of the key establishment procedure.
- * @param direction - client/server direction of the command
- * @param disableDefaultRsp - disable default response
- * @param seqNum - ZCL sequence number
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( uint8 srcEP,
- afAddrType_t *dstAddr,
- TermKeyStatus_t status,
- uint8 waitTime,
- uint16 keyEstablishmentSuite, uint8 direction,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 buf[4];
- buf[0] = status;
- buf[1] = waitTime;
- buf[2] = LO_UINT16(keyEstablishmentSuite);
- buf[3] = HI_UINT16(keyEstablishmentSuite);
- return zcl_SendCommand(srcEP, dstAddr,
- ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
- COMMAND_TERMINATE_KEY_ESTABLISHMENT, TRUE,
- direction, disableDefaultRsp,
- 0, seqNum, 4, buf );
- }
- /*********************************************************************
- * @fn zclGeneral_KeyEstablish_Send_InitiateKeyEstablishmentRsp
- *
- * @brief Call to send out a Initiate Key Establishment Response
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param status - status of the key establishment response.
- * @param keyEstablishmentSuite - requested key establishment suite bitmap
- * @param keyGenerateTime - how long it takes to generate key
- * @param macGenerateTime - how long it takes to generate mac
- * @param certificate - identity. For CBKE, it's the implicit certificate.
- * @param disableDefaultRsp - disable default response
- * @param seqNum - ZCL sequence number
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_KeyEstablish_Send_InitiateKeyEstablishmentRsp( uint8 srcEP, afAddrType_t *dstAddr,
- uint16 keyEstablishmentSuite,
- uint8 keyGenerateTime,
- uint8 macGenerateTime,
- uint8 *certificate,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- uint8 *buf;
- uint8 bufLen;
- uint8 ret;
- uint8 *pBuf;
- bufLen = 2 + 1 + 1 + ZCL_KE_IMPLICIT_CERTIFICATE_LEN;
- if ((buf = osal_mem_alloc(bufLen)) == NULL)
- {
- return ZMemError;
- }
- pBuf = buf;
- *pBuf++ = LO_UINT16( keyEstablishmentSuite );
- *pBuf++ = HI_UINT16( keyEstablishmentSuite );
- *pBuf++ = keyGenerateTime;
- *pBuf++ = macGenerateTime;
- osal_memcpy( pBuf, certificate, ZCL_KE_IMPLICIT_CERTIFICATE_LEN );
- ret = zcl_SendCommand( srcEP, dstAddr,
- ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
- COMMAND_INITIATE_KEY_ESTABLISHMENT_RESPONSE, TRUE,
- ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp,
- 0, seqNum, bufLen, buf );
- osal_mem_free(buf);
- return ret;
- }
- /*********************************************************************
- * @fn zclGeneral_KeyEstablish_Send_EphemeralDataRsp
- *
- * @brief Call to send out a Ephemeral Data Response Command
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param eData - ephemeral data.
- * @param disableDefaultRsp - disable default response
- * @param seqNum - ZCL sequence number
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_KeyEstablish_Send_EphemeralDataRsp( uint8 srcEP, afAddrType_t *dstAddr,
- uint8 *eData,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- return (zcl_SendCommand( srcEP, dstAddr,
- ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
- COMMAND_EPHEMERAL_DATA_RESPONSE, TRUE,
- ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp,
- 0, seqNum, ZCL_KE_CA_PUBLIC_KEY_LEN, eData ));
- }
- /*********************************************************************
- * @fn zclGeneral_KeyEstablish_Send_ConfirmKeyRsp
- *
- * @brief Call to send out a Confirm Key Response
- *
- * @param srcEP - Sending application's endpoint
- * @param dstAddr - where you want the message to go
- * @param mac - MAC
- * @param disableDefaultRsp - disable default response
- * @param seqNum - ZCL sequence number
- *
- * @return ZStatus_t
- */
- ZStatus_t zclGeneral_KeyEstablish_Send_ConfirmKeyRsp( uint8 srcEP, afAddrType_t *dstAddr,
- uint8 *mac,
- uint8 disableDefaultRsp, uint8 seqNum )
- {
- return (zcl_SendCommand(srcEP, dstAddr,
- ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT,
- COMMAND_CONFIRM_KEY_RESPONSE, TRUE,
- ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp,
- 0, seqNum, KEY_ESTABLISH_MAC_LENGTH, mac ));
- }
- /*********************************************************************
- * @fn zclGeneral_KeyEstablish_Send_ConfirmKeyRsp
- *
- * @brief Register the user defined yielding function
- *
- * @param yield - Pointer to a function to allow user defined yielding.
- * YieldFunc may be NULL if yieldLevel is 0
- * @param yieldLevel - The yield level determines how often the user defined
- * yield function will be called. This is a number from 0 to 10.
- * 0 will never yield. 1 will yield the most often. 10 will yield the
- * least often.
- */
- void zclGeneral_KeyEstablishment_RegYieldCB( YieldFunc *pFnYield,
- uint8 yieldLevel )
- {
- if( pFnYield == NULL )
- {
- zclKeyEstablish_YieldLevel = 0;
- }
- else
- {
- zclKeyEstablish_YieldFunc = pFnYield;
- zclKeyEstablish_YieldLevel = yieldLevel;
- }
- }
- /*********************************************************************
- * @fn zclGeneral_KeyEstablish_HdlIncoming
- *
- * @brief Callback from ZCL to process incoming Commands specific
- * to this cluster library or Profile commands
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t
- */
- static ZStatus_t zclGeneral_KeyEstablish_HdlIncoming( zclIncoming_t *pInMsg )
- {
- ZStatus_t stat = ZSuccess;
- #if defined ( INTER_PAN )
- if ( StubAPS_InterPan( pInMsg->msg->srcAddr.panId, pInMsg->msg->srcAddr.endPoint ) )
- return ( stat ); // Cluster not supported thru Inter-PAN
- #endif
- if ( zcl_ClusterCmd( pInMsg->hdr.fc.type ) )
- {
- // Is this a manufacturer specific command?
- if ( pInMsg->hdr.fc.manuSpecific == 0 )
- {
- stat = zclGeneral_KeyEstablish_HdlInSpecificCommands( pInMsg );
- }
- else
- {
- // We don't support any manufacturer specific command.
- stat = ZFailure;
- }
- }
- else
- {
- // Handle all the normal (Read, Write...) commands -- should never get here
- stat = ZFailure;
- }
- return ( stat );
- }
- /*********************************************************************
- * @fn zclGeneral_KeyEstablish_HdlInSpecificCommands
- *
- * @brief Callback from ZCL to process incoming Commands specific
- * to this cluster library
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t
- */
- static ZStatus_t zclGeneral_KeyEstablish_HdlInSpecificCommands( zclIncoming_t *pInMsg )
- {
- ZStatus_t stat;
- if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
- {
- // Commands received by Server
- switch ( pInMsg->hdr.commandID )
- {
- case COMMAND_INITIATE_KEY_ESTABLISHMENT:
- stat = zclGeneral_ProcessInCmd_InitiateKeyEstablish( pInMsg );
- break;
- case COMMAND_EPHEMERAL_DATA_REQUEST:
- stat = zclGeneral_ProcessInCmd_EphemeralDataReq( pInMsg );
- break;
- case COMMAND_CONFIRM_KEY:
- stat = zclGeneral_ProcessInCmd_ConfirmKey( pInMsg );
- break;
- case COMMAND_TERMINATE_KEY_ESTABLISHMENT:
- stat = zclGeneral_ProcessInCmd_TerminateKeyEstablish( pInMsg );
- break;
- default:
- stat = ZFailure;
- break;
- }
- }
- else
- {
- // Commands received by Client
- switch ( pInMsg->hdr.commandID )
- {
- case COMMAND_INITIATE_KEY_ESTABLISHMENT_RESPONSE:
- stat = zclGeneral_ProcessInCmd_InitiateKeyEstablishRsp( pInMsg );
- break;
- case COMMAND_EPHEMERAL_DATA_RESPONSE:
- stat = zclGeneral_ProcessInCmd_EphemeralDataRsp( pInMsg );
- break;
- case COMMAND_CONFIRM_KEY_RESPONSE:
- stat = zclGeneral_ProcessInCmd_ConfirmKeyRsp( pInMsg );
- break;
- case COMMAND_TERMINATE_KEY_ESTABLISHMENT:
- stat = zclGeneral_ProcessInCmd_TerminateKeyEstablish( pInMsg );
- break;
- default:
- stat = ZFailure;
- break;
- }
- }
- return ( stat );
- }
- /*********************************************************************
- * @fn zclGeneral_ProcessInCmd_InitiateKeyEstablish
- *
- * @brief Process the received Initiate Key Establishment Request.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t - ZFailure @ Unsupported
- * ZCL_STATUS_MALFORMED_COMMAND
- * ZCL_STATUS_CMD_HAS_RSP
- * ZCL_STATUS_SOFTWARE_FAILURE
- */
- static ZStatus_t zclGeneral_ProcessInCmd_InitiateKeyEstablish( zclIncoming_t *pInMsg )
- {
- TermKeyStatus_t status = TermKeyStatus_Success;
- uint16 remoteKeyEstablishmentSuite;
- uint8 *implicitCert = NULL;
- uint8 index = MAX_KEY_ESTABLISHMENT_REC_ENTRY; // set to non valid value
- // Check the incoming packet length
- if ( pInMsg->pDataLen < PACKET_LEN_INITIATE_KEY_EST_REQ )
- {
- status = TermKeyStatus_BadMessage;
- }
- else
- {
- // Start a new key establishment rec entry
- index = zclGeneral_AddKeyEstablishRec( &pInMsg->msg->srcAddr );
- if( index >= MAX_KEY_ESTABLISHMENT_REC_ENTRY )
- {
- // Failed to add an entry
- status = TermKeyStatus_NoResources;
- }
- else
- {
- // Parse the incoming message
- // Copy the remote device certificate
- osal_memcpy(keyEstablishRec[index].pRemoteCertificate, &(pInMsg->pData[KEY_ESTABLISH_CERT_IDX]),
- ZCL_KE_IMPLICIT_CERTIFICATE_LEN );
- // Verify the certificate issuer and key establishment suite
- remoteKeyEstablishmentSuite = BUILD_UINT16( pInMsg->pData[0], pInMsg->pData[1] );
- if ( remoteKeyEstablishmentSuite != KEY_ESTABLISHMENT_SUITE )
- {
- status = TermKeyStatus_UnSupportedSuite;
- }
- else
- {
- // continue parsing message
- // Save Ephemeral Data Generate Key and Confirm Key Time
- if (pInMsg->pData[2] >= KEY_ESTABLISHMENT_EPH_DATA_GEN_INVALID_TIME)
- {
- status = TermKeyStatus_BadMessage;
- }
- else
- {
- // continue parsing message
- keyEstablishRec[index].remoteEphDataGenTime = pInMsg->pData[2];
- if (pInMsg->pData[3] >= KEY_ESTABLISHMENT_CONF_KEY_GEN_INVALID_TIME)
- {
- status = TermKeyStatus_BadMessage;
- }
- else
- {
- // continue parsing message
- keyEstablishRec[index].remoteConfKeyGenTime = pInMsg->pData[3];
- if ((implicitCert = osal_mem_alloc(ZCL_KE_IMPLICIT_CERTIFICATE_LEN)) == NULL)
- {
- // Reset the entry
- zclGeneral_ResetKeyEstablishRec( index );
- return ZCL_STATUS_SOFTWARE_FAILURE; // Memory allocation failure.
- }
- osal_nv_read(ZCD_NV_IMPLICIT_CERTIFICATE, 0, ZCL_KE_IMPLICIT_CERTIFICATE_LEN, implicitCert);
- if ( !osal_memcmp( &(keyEstablishRec[index].pRemoteCertificate[KEY_ESTABLISH_CERT_ISSUER_IDX]),
- &(implicitCert[KEY_ESTABLISH_CERT_ISSUER_IDX]),
- KEY_ESTABLISH_CERT_ISSUER_LENTGH ) )
- {
- status = TermKeyStatus_UnknowIssuer;
- }
- }
- }
- }
- } // end of parsing of the message
- }
- if ( status != TermKeyStatus_Success )
- {
- zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
- &pInMsg->msg->srcAddr,
- status,
- KEY_ESTABLISHMENT_AVG_TIMEOUT,
- KEY_ESTABLISHMENT_SUITE,
- ZCL_FRAME_SERVER_CLIENT_DIR,
- FALSE, zcl_SeqNum++ );
- if ( implicitCert != NULL )
- {
- osal_mem_free(implicitCert);
- }
- // Reset the entry
- if ( index < MAX_KEY_ESTABLISHMENT_REC_ENTRY )
- {
- zclGeneral_ResetKeyEstablishRec( index );
- }
- return ZCL_STATUS_CMD_HAS_RSP;
- }
- // Fill in partner's extended address
- SSP_MemCpyReverse( keyEstablishRec[index].partnerExtAddr,
- &(keyEstablishRec[index].pRemoteCertificate[KEY_ESTABLISH_CERT_EXT_ADDR_IDX]),
- Z_EXTADDR_LEN); // ID(L)
- // Change the state and wait for the Ephemeral Data Request
- keyEstablishRec[index].lastSeqNum = pInMsg->hdr.transSeqNum;
- keyEstablishRec[index].state = KeyEstablishState_EDataPending;
- keyEstablishRec[index].role = KEY_ESTABLISHMENT_RESPONDER;
- zclGeneral_KeyEstablish_Send_InitiateKeyEstablishmentRsp( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
- &pInMsg->msg->srcAddr,
- KEY_ESTABLISHMENT_SUITE,
- ZCL_KEY_ESTABLISHMENT_EKEY_GENERATE_TIMEOUT + ZCL_KEY_ESTABLISHMENT_KEY_GENERATE_TIMEOUT,
- ZCL_KEY_ESTABLISHMENT_MAC_GENERATE_TIMEOUT * 2 ,
- implicitCert, FALSE, pInMsg->hdr.transSeqNum );
- // The Request was processed successfuly, now the age timer needs to start based on the
- // remote Ephemeral Data Generate Time
- keyEstablishRec[index].age = keyEstablishRec[index].remoteEphDataGenTime;
- // Start the Ephemeral Data Generate aging timer
- osal_start_reload_timer( zcl_KeyEstablishment_TaskID, KEY_ESTABLISHMENT_REC_AGING_EVT,
- KEY_ESTABLISHMENT_REC_AGING_INTERVAL );
- osal_mem_free(implicitCert);
- #if defined (NWK_AUTO_POLL)
- // For polling end device, set the Key Establishment poll rate
- zclSavedPollRate = zgPollRate;
- NLME_SetPollRate(ZCL_KEY_ESTABLISH_POLL_RATE);
- #endif
- return ZCL_STATUS_CMD_HAS_RSP;
- }
- /*********************************************************************
- * @fn zclGeneral_ProcessInCmd_EphemeralDataReq
- *
- * @brief Process the received Ephemeral Data Request.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t - ZFailure @ Unsupported
- * ZCL_STATUS_MALFORMED_COMMAND
- * ZCL_STATUS_CMD_HAS_RSP
- */
- static ZStatus_t zclGeneral_ProcessInCmd_EphemeralDataReq( zclIncoming_t *pInMsg )
- {
- uint8 index;
- uint8 status = ZFailure;
- // Omit checking the incoming packet length
- // Stop the Ephemeral Data Generate timer because the message has been received
- osal_stop_timerEx( zcl_KeyEstablishment_TaskID, KEY_ESTABLISHMENT_REC_AGING_EVT );
- // Check state of the key establishment record. If not match, terminate the procedure
- if ( ( index = zclGeneral_GetKeyEstablishRecIndex( pInMsg->msg->srcAddr.addr.shortAddr ) )
- < MAX_KEY_ESTABLISHMENT_REC_ENTRY )
- {
- if ( keyEstablishRec[index].role == KEY_ESTABLISHMENT_RESPONDER &&
- keyEstablishRec[index].state == KeyEstablishState_EDataPending )
- {
- status = ZSuccess;
- // Copy the remote device Ephemeral Public key
- osal_memcpy( keyEstablishRec[index].pRemotePublicKey,
- &(pInMsg->pData[0]),
- ZCL_KE_CA_PUBLIC_KEY_LEN );
- }
- else
- {
- // Reset the entry
- zclGeneral_ResetKeyEstablishRec( index );
- }
- }
- if( status != ZSuccess )
- {
- // Either the entry doesn't exist or in the wrong state, send termination back
- zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
- &pInMsg->msg->srcAddr,
- TermKeyStatus_BadMessage,
- KEY_ESTABLISHMENT_AVG_TIMEOUT,
- KEY_ESTABLISHMENT_SUITE,
- ZCL_FRAME_SERVER_CLIENT_DIR,
- FALSE, zcl_SeqNum++ );
- #if defined (NWK_AUTO_POLL)
- // Restore the saved poll rate for end device
- NLME_SetPollRate(zclSavedPollRate);
- #endif
- return ZCL_STATUS_CMD_HAS_RSP;
- }
- // Generate Ephemeral Public/Private Key Pair
- ZSE_ECCGenerateKey( (unsigned char *)keyEstablishRec[index].pLocalEPrivateKey,
- (unsigned char *)keyEstablishRec[index].pLocalEPublicKey,
- zclGeneral_KeyEstablishment_GetRandom,
- zclKeyEstablish_YieldFunc, zclKeyEstablish_YieldLevel );
- #if defined (DEBUG_STATIC_ECC)
- // For debug and testing purpose, use a fixed ephermeral key pair instead
- // of the randomly generated one.
- osal_memcpy( keyEstablishRec[index].pLocalEPrivateKey, private2, 21 );
- osal_memcpy( keyEstablishRec[index].pLocalEPublicKey, public2, 22 );
- #endif
- // Update Sequence Number
- keyEstablishRec[index].lastSeqNum = pInMsg->hdr.transSeqNum;
- // Change the state and wait for the Key to be calculated
- keyEstablishRec[index].state = KeyEstablishState_KeyCalculatePending;
- osal_start_timerEx( zcl_KeyEstablishment_TaskID, KEY_ESTABLISHMENT_CMD_PROCESS_EVT,
- KEY_ESTABLISHMENT_WAIT_PERIOD );
- return ZCL_STATUS_CMD_HAS_RSP;
- }
- /*********************************************************************
- * @fn zclGeneral_ProcessInCmd_InitiateKeyEstablishRsp
- *
- * @brief Process the received Initiate Key Establishment Response.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t - ZFailure @ Unsupported
- * ZCL_STATUS_MALFORMED_COMMAND
- * ZCL_STATUS_CMD_HAS_RSP
- * ZCL_STATUS_SOFTWARE_FAILURE
- */
- static ZStatus_t zclGeneral_ProcessInCmd_InitiateKeyEstablishRsp( zclIncoming_t *pInMsg )
- {
- TermKeyStatus_t keyStatus = TermKeyStatus_Success;
- uint16 remoteKeyEstablishmentSuite;
- uint8 index = MAX_KEY_ESTABLISHMENT_REC_ENTRY; // set to non valid value
- uint8 status = ZFailure;
- uint8 recvExtAddr[Z_EXTADDR_LEN];
- // Stop the Key Establishment aging timer because the message has been received
- osal_stop_timerEx( zcl_KeyEstablishment_TaskID, KEY_ESTABLISHMENT_REC_AGING_EVT );
- // Check the incoming packet length
- if ( pInMsg->pDataLen >= PACKET_LEN_INITIATE_KEY_EST_RSP )
- {
- // Check state of the key establishment record. If not match, terminate the procedure
- if ( ( index = zclGeneral_GetKeyEstablishRecIndex( pInMsg->msg->srcAddr.addr.shortAddr ) )
- < MAX_KEY_ESTABLISHMENT_REC_ENTRY )
- {
- if ( keyEstablishRec[index].role == KEY_ESTABLISHMENT_INITIATOR &&
- keyEstablishRec[index].state == KeyEstablishState_InitiatePending )
- {
- // Parse the incoming message
- // Copy the remote device certificate
- osal_memcpy( keyEstablishRec[index].pRemoteCertificate, &(pInMsg->pData[KEY_ESTABLISH_CERT_IDX]),
- ZCL_KE_IMPLICIT_CERTIFICATE_LEN );
- // look for extended address of partner device
- AddrMgrExtAddrLookup(keyEstablishRec[index].dstAddr.addr.shortAddr,
- keyEstablishRec[index].partnerExtAddr);
- // retrieve extended address from certificate and reverse bytes
- SSP_MemCpyReverse( recvExtAddr,
- &(keyEstablishRec[index].pRemoteCertificate[KEY_ESTABLISH_CERT_EXT_ADDR_IDX]),
- Z_EXTADDR_LEN);
- // verify extended address in certificate matches partner's extended address
- if (osal_memcmp(keyEstablishRec[index].partnerExtAddr, recvExtAddr, Z_EXTADDR_LEN))
- {
- status = ZSuccess;
- }
- }
- else
- {
- // Reset the entry from the rec table
- zclGeneral_ResetKeyEstablishRec( index );
- }
- }
- }
- if ( status == ZFailure )
- {
- keyStatus = TermKeyStatus_BadMessage;
- }
- else
- {
- uint8 *implicitCert;
- // Parse the incoming message
- // Verify the certificate issuer and key establishment suite
- remoteKeyEstablishmentSuite = BUILD_UINT16( pInMsg->pData[0], pInMsg->pData[1] );
- if ( remoteKeyEstablishmentSuite != KEY_ESTABLISHMENT_SUITE )
- {
- keyStatus = TermKeyStatus_UnSupportedSuite;
- }
- else
- {
- // continue parsing message
- // Save Ephemeral Data Generate Key and Confirm Key Time
- if (pInMsg->pData[2] >= KEY_ESTABLISHMENT_EPH_DATA_GEN_INVALID_TIME)
- {
- status = TermKeyStatus_BadMessage;
- }
- else
- {
- // continue parsing message
- keyEstablishRec[index].remoteEphDataGenTime = pInMsg->pData[2];
- if (pInMsg->pData[3] >= KEY_ESTABLISHMENT_CONF_KEY_GEN_INVALID_TIME)
- {
- status = TermKeyStatus_BadMessage;
- }
- else
- {
- // continue parsing message
- keyEstablishRec[index].remoteConfKeyGenTime = pInMsg->pData[3];
- if ((implicitCert = osal_mem_alloc(ZCL_KE_IMPLICIT_CERTIFICATE_LEN)) == NULL)
- {
- // Reset the entry
- zclGeneral_ResetKeyEstablishRec( index );
- return ZCL_STATUS_SOFTWARE_FAILURE; // Memory allocation failure.
- }
- osal_nv_read(ZCD_NV_IMPLICIT_CERTIFICATE, 0, ZCL_KE_IMPLICIT_CERTIFICATE_LEN, implicitCert);
- if ( !osal_memcmp( &(keyEstablishRec[index].pRemoteCertificate[KEY_ESTABLISH_CERT_ISSUER_IDX]),
- &(implicitCert[KEY_ESTABLISH_CERT_ISSUER_IDX]),
- KEY_ESTABLISH_CERT_ISSUER_LENTGH ) )
- {
- keyStatus = TermKeyStatus_UnknowIssuer;
- }
- osal_mem_free(implicitCert);
- }
- }
- }
- } // end of parsing of the message
- if ( keyStatus == TermKeyStatus_Success )
- {
- keyEstablishRec[index].state = KeyEstablishState_EDataPending;
- // Send Ephemeral Data Request back
- zclGeneral_KeyEstablish_Send_EphemeralDataReq( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
- &pInMsg->msg->srcAddr,
- keyEstablishRec[index].pLocalEPublicKey,
- FALSE, zcl_SeqNum++ );
- // The Request was processed successfuly, now the age timer needs to start based on the
- // remote Ephemeral Data Generate Time
- keyEstablishRec[index].age = keyEstablishRec[index].remoteEphDataGenTime;
- // Start the Ephemeral Data Generate aging timer
- osal_start_reload_timer( zcl_KeyEstablishment_TaskID, KEY_ESTABLISHMENT_REC_AGING_EVT,
- KEY_ESTABLISHMENT_REC_AGING_INTERVAL );
- }
- else
- {
- zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
- &pInMsg->msg->srcAddr,
- keyStatus,
- KEY_ESTABLISHMENT_AVG_TIMEOUT,
- KEY_ESTABLISHMENT_SUITE,
- ZCL_FRAME_CLIENT_SERVER_DIR,
- FALSE, zcl_SeqNum++ );
- // Reset the entry
- if ( index < MAX_KEY_ESTABLISHMENT_REC_ENTRY )
- {
- zclGeneral_ResetKeyEstablishRec( index );
- }
- #if defined (NWK_AUTO_POLL)
- // Restore the saved poll rate for end device
- NLME_SetPollRate(zclSavedPollRate);
- #endif
- }
- return ZCL_STATUS_CMD_HAS_RSP;
- }
- /*********************************************************************
- * @fn zclGeneral_ProcessInCmd_EphemeralDataRsp
- *
- * @brief Process the received Initiate Key Establishment Response.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t - ZFailure @ Unsupported
- * ZCL_STATUS_MALFORMED_COMMAND
- * ZCL_STATUS_CMD_HAS_RSP
- * ZCL_STATUS_SOFTWARE_FAILURE
- */
- static ZStatus_t zclGeneral_ProcessInCmd_EphemeralDataRsp( zclIncoming_t *pInMsg )
- {
- uint8 index;
- uint8 status = ZFailure;
- // Stop the Ephemeral Data Generate timer because the message has been received
- osal_stop_timerEx( zcl_KeyEstablishment_TaskID, KEY_ESTABLISHMENT_REC_AGING_EVT );
- // Check state of the key establishment record. If not match, terminate the procedure
- if ( ( index = zclGeneral_GetKeyEstablishRecIndex( pInMsg->msg->srcAddr.addr.shortAddr ) )
- < MAX_KEY_ESTABLISHMENT_REC_ENTRY )
- {
- if ( keyEstablishRec[index].role == KEY_ESTABLISHMENT_INITIATOR &&
- keyEstablishRec[index].state == KeyEstablishState_EDataPending )
- {
- status = ZSuccess;
- // Copy the remote device Ephemeral Public key
- osal_memcpy( keyEstablishRec[index].pRemotePublicKey,
- &(pInMsg->pData[0]),
- ZCL_KE_CA_PUBLIC_KEY_LEN );
- }
- else
- {
- // Reset the entry from the rec table
- zclGeneral_ResetKeyEstablishRec( index );
- }
- }
- if ( status == ZFailure )
- {
- // No existing record found or the record found has a wrong state, terminate the procedure
- zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
- &pInMsg->msg->srcAddr,
- TermKeyStatus_BadMessage,
- KEY_ESTABLISHMENT_AVG_TIMEOUT,
- KEY_ESTABLISHMENT_SUITE,
- ZCL_FRAME_CLIENT_SERVER_DIR,
- FALSE, zcl_SeqNum++ );
- #if defined (NWK_AUTO_POLL)
- // Restore the saved poll rate for end device
- NLME_SetPollRate(zclSavedPollRate);
- #endif
- }
- else
- {
- keyEstablishRec[index].state = KeyEstablishState_KeyCalculatePending;
- osal_start_timerEx( zcl_KeyEstablishment_TaskID, KEY_ESTABLISHMENT_RSP_PROCESS_EVT,
- KEY_ESTABLISHMENT_WAIT_PERIOD );
- }
- return ZCL_STATUS_CMD_HAS_RSP;
- }
- /*********************************************************************
- * @fn zclGeneral_ProcessInCmd_ConfirmKey
- *
- * @brief Process the received Confirm Key Command.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t - ZFailure @ Unsupported
- * ZCL_STATUS_CMD_HAS_RSP
- * ZCL_STATUS_SOFTWARE_FAILURE
- */
- static ZStatus_t zclGeneral_ProcessInCmd_ConfirmKey( zclIncoming_t *pInMsg )
- {
- uint8 index;
- uint8 status = ZFailure;
- uint8 MACu[KEY_ESTABLISH_MAC_KEY_LENGTH];
- uint8 MACv[KEY_ESTABLISH_MAC_KEY_LENGTH];
- TermKeyStatus_t keyStatus = TermKeyStatus_Success;
- // Stop the Config Key Generate aging timer because the message has been received
- osal_stop_timerEx( zcl_KeyEstablishment_TaskID, KEY_ESTABLISHMENT_REC_AGING_EVT );
- // Check state of the key establishment record. If not match, terminate the procedure
- if ( ( index = zclGeneral_GetKeyEstablishRecIndex( pInMsg->msg->srcAddr.addr.shortAddr ) )
- < MAX_KEY_ESTABLISHMENT_REC_ENTRY )
- {
- if ( keyEstablishRec[index].role == KEY_ESTABLISHMENT_RESPONDER &&
- keyEstablishRec[index].state == KeyEstablishState_ConfirmPending )
- {
- status = ZSuccess;
- }
- else
- {
- // Reset the entry
- zclGeneral_ResetKeyEstablishRec( index );
- }
- }
- if ( status == ZFailure )
- {
- keyStatus = TermKeyStatus_BadMessage;
- }
- else
- {
- // Calculate MAC(U). Note that the zData is also pointing to the macKey
- zclGeneral_KeyEstablishment_GenerateMAC( index, TRUE, MACu );
- // Compare MAC(U) with MAC(V)
- if ( osal_memcmp( MACu, pInMsg->pData, KEY_ESTABLISH_MAC_LENGTH ) == TRUE )
- {
- // Send Confirm Key Response with Status - SUCCESS
- keyEstablishRec[index].state = KeyEstablishState_TerminationPending;
- // Store the key in the key table
- ZDSecMgrAddLinkKey( pInMsg->msg->srcAddr.addr.shortAddr,
- keyEstablishRec[index].partnerExtAddr,
- keyEstablishRec[index].pKey );
- // Calculate MAC(V) and send it back
- zclGeneral_KeyEstablishment_GenerateMAC( index, FALSE, MACv );
- zclGeneral_KeyEstablish_Send_ConfirmKeyRsp( pInMsg->msg->endPoint,
- &pInMsg->msg->srcAddr,
- MACv,
- FALSE, pInMsg->hdr.transSeqNum );
- }
- else
- {
- keyStatus = TermKeyStatus_BadKeyConfirm;
- }
- // Reset the entry, at this point the Key Establishment process has
- // finished and the record is not needed anymore
- zclGeneral_ResetKeyEstablishRec( index );
- }
- if( keyStatus != TermKeyStatus_Success)
- {
- // If MAC(U) does not match MAC(V), send response with failure
- zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
- &pInMsg->msg->srcAddr,
- keyStatus,
- KEY_ESTABLISHMENT_AVG_TIMEOUT,
- KEY_ESTABLISHMENT_SUITE,
- ZCL_FRAME_SERVER_CLIENT_DIR,
- FALSE, zcl_SeqNum++ );
- }
- #if defined (NWK_AUTO_POLL)
- // Key Establishment Procedure complete. Restore the saved poll rate for end device
- NLME_SetPollRate(zclSavedPollRate);
- #endif
- return ZCL_STATUS_CMD_HAS_RSP;
- }
- /*********************************************************************
- * @fn zclGeneral_ProcessInCmd_ConfirmKeyRsp
- *
- * @brief Process the received Confirm Key Response.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t - ZFailure @ Unsupported
- * ZCL_STATUS_MALFORMED_COMMAND
- * ZCL_STATUS_CMD_HAS_RSP
- * ZCL_STATUS_SOFTWARE_FAILURE
- */
- static ZStatus_t zclGeneral_ProcessInCmd_ConfirmKeyRsp( zclIncoming_t *pInMsg )
- {
- uint8 index;
- uint8 status = ZFailure;
- uint8 MACv[KEY_ESTABLISH_MAC_LENGTH];
- // Stop the Config Key Generate aging timer because the message has been received
- osal_stop_timerEx( zcl_KeyEstablishment_TaskID, KEY_ESTABLISHMENT_REC_AGING_EVT );
- // Check state of the key establishment record. If not match, terminate the procedure
- if ( ( index = zclGeneral_GetKeyEstablishRecIndex( pInMsg->msg->srcAddr.addr.shortAddr ) )
- < MAX_KEY_ESTABLISHMENT_REC_ENTRY )
- {
- if ( keyEstablishRec[index].role == KEY_ESTABLISHMENT_INITIATOR &&
- keyEstablishRec[index].state == KeyEstablishState_ConfirmPending )
- {
- status = ZSuccess;
- }
- else
- {
- // Reset the entry from the rec table
- zclGeneral_ResetKeyEstablishRec( index );
- }
- }
- if ( status == ZFailure )
- {
- status = TermKeyStatus_BadMessage;
- }
- else
- {
- // Calculate MAC(V)
- zclGeneral_KeyEstablishment_GenerateMAC( index, FALSE, MACv);
- // Compare M(U) with M(V)
- if ( osal_memcmp( MACv, pInMsg->pData, KEY_ESTABLISH_MAC_LENGTH ) == TRUE )
- {
- status = TermKeyStatus_Success;
- // Store the link key
- ZDSecMgrAddLinkKey( pInMsg->msg->srcAddr.addr.shortAddr,
- keyEstablishRec[index].partnerExtAddr,
- keyEstablishRec[index].pKey );
- }
- else
- {
- // If MAC(U) does not match MAC(V), send response with failure
- status = TermKeyStatus_BadKeyConfirm;
- }
- }
- if( status != TermKeyStatus_Success )
- {
- zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
- &pInMsg->msg->srcAddr,
- (TermKeyStatus_t)status,
- KEY_ESTABLISHMENT_AVG_TIMEOUT,
- KEY_ESTABLISHMENT_SUITE,
- ZCL_FRAME_CLIENT_SERVER_DIR,
- FALSE, zcl_SeqNum++ );
- }
- // Send Osal message to the application to indicate the completion
- if ( keyEstablishRec[index].appTaskID != INVALID_TASK_ID )
- {
- keyEstablishmentInd_t *ind;
- ind = (keyEstablishmentInd_t *)osal_msg_allocate( sizeof( keyEstablishmentInd_t ) );
- if ( ind )
- {
- ind->hdr.event = ZCL_KEY_ESTABLISH_IND;
- ind->hdr.status = status;
- // Clear remaining fields
- ind->waitTime = 0;
- ind->keyEstablishmentSuite = 0;
- osal_msg_send( keyEstablishRec[index].appTaskID, (uint8*)ind );
- }
- }
- // End of this transection. Reset the entry from the rec table
- zclGeneral_ResetKeyEstablishRec( index );
- #if defined (NWK_AUTO_POLL)
- // Key Establishment Procedure complete. Restore the saved poll rate for end device
- NLME_SetPollRate(zclSavedPollRate);
- #endif
- return ZCL_STATUS_CMD_HAS_RSP;
- }
- /*********************************************************************
- * @fn zclGeneral_ProcessInCmd_TerminateKeyEstablish
- *
- * @brief Process the received Terminate Key Establishment Command.
- *
- * @param pInMsg - pointer to the incoming message
- *
- * @return ZStatus_t - ZFailure @ Unsupported
- * ZSuccess @ Success
- */
- static ZStatus_t zclGeneral_ProcessInCmd_TerminateKeyEstablish( zclIncoming_t *pInMsg )
- {
- uint8 index;
- // Find the key establishment record and delete the record entry.
- if ( ( index = zclGeneral_GetKeyEstablishRecIndex( pInMsg->msg->srcAddr.addr.shortAddr ) )
- < MAX_KEY_ESTABLISHMENT_REC_ENTRY )
- {
- if ( keyEstablishRec[index].appTaskID != INVALID_TASK_ID )
- {
- keyEstablishmentInd_t *ind;
- // Send osal message to the application
- ind = (keyEstablishmentInd_t *)osal_msg_allocate( sizeof( keyEstablishmentInd_t ) );
- if ( ind )
- {
- ind->hdr.event = ZCL_KEY_ESTABLISH_IND;
- ind->hdr.status = pInMsg->pData[0];
- ind->waitTime = pInMsg->pData[1];
- ind->keyEstablishmentSuite = BUILD_UINT16( pInMsg->pData[2], pInMsg->pData[3] );
- osal_msg_send( keyEstablishRec[index].appTaskID, (uint8*)ind );
- }
- }
- // In either case, remove the entry from the rec table
- zclGeneral_ResetKeyEstablishRec( index );
- #if defined (NWK_AUTO_POLL)
- // Restore the saved poll rate for end device
- NLME_SetPollRate(zclSavedPollRate);
- #endif
- }
- return ZSuccess;
- }
- /*********************************************************************
- * @fn zclGeneral_InitiateKeyEstablish_Cmd_CalculateKey
- *
- * @brief Calculate the Key using ECC library upon receipt of Initiate
- Key Establishment Command.
- *
- * @param none
- *
- * @return ZStatus_t - ZFailure @ Entry pending key calculation not found
- * ZSuccess
- */
- static ZStatus_t zclGeneral_InitiateKeyEstablish_Cmd_CalculateKey( void )
- {
- uint8 zData[KEY_ESTABLISH_SHARED_SECRET_LENGTH];
- uint8 *caPublicKey, *devicePrivateKey, *keyBit;
- uint8 index, status, tmp;
- // It is possible to have multiple entries in the keyCalulationPending state.
- // Here we assume the partner that starts the key establishment procedure earlier
- // will have a smaller index in the table.
- // However, this might not apply due to different processing capability of
- // different processors.
- if ( (index = zclGeneral_GetKeyEstablishRecIndex_State( KeyEstablishState_KeyCalculatePending ))
- >= MAX_KEY_ESTABLISHMENT_REC_ENTRY )
- {
- return ZFailure;
- }
- if ((caPublicKey = osal_mem_alloc(ZCL_KE_CA_PUBLIC_KEY_LEN)) == NULL)
- {
- // Reset the entry
- zclGeneral_ResetKeyEstablishRec( index );
- return ZCL_STATUS_SOFTWARE_FAILURE; // Memory allocation failure.
- }
- if ((devicePrivateKey = osal_mem_alloc(ZCL_KE_DEVICE_PRIVATE_KEY_LEN)) == NULL)
- {
- osal_mem_free(caPublicKey);
- // Reset the entry
- zclGeneral_ResetKeyEstablishRec( index );
- return ZCL_STATUS_SOFTWARE_FAILURE; // Memory allocation failure.
- }
- osal_nv_read(ZCD_NV_CA_PUBLIC_KEY, 0, ZCL_KE_CA_PUBLIC_KEY_LEN, caPublicKey);
- osal_nv_read(ZCD_NV_DEVICE_PRIVATE_KEY, 0, ZCL_KE_DEVICE_PRIVATE_KEY_LEN, devicePrivateKey);
- // Turn off the radio
- tmp = FALSE;
- ZMacSetReq( ZMacRxOnIdle, &tmp );
- status = ZSE_ECCKeyBitGenerate( devicePrivateKey, keyEstablishRec[index].pLocalEPrivateKey,
- keyEstablishRec[index].pLocalEPublicKey,
- keyEstablishRec[index].pRemoteCertificate,
- keyEstablishRec[index].pRemotePublicKey,
- caPublicKey, zData,
- zclGeneral_KeyEstablishment_HashFunc,
- zclKeyEstablish_YieldFunc, zclKeyEstablish_YieldLevel);
- tmp = TRUE;
- ZMacSetReq( ZMacRxOnIdle, &tmp ); // Turn the radio back on
- osal_mem_free(caPublicKey);
- osal_mem_free(devicePrivateKey);
- if( status == MCE_SUCCESS )
- {
- // Allocate buffer to store KDF(Z) = MacKey || KeyData
- if ( (keyBit = osal_mem_alloc( KEY_ESTABLISH_KEY_DATA_LENGTH +
- KEY_ESTABLISH_MAC_KEY_LENGTH)) == NULL )
- {
- // Reset the entry
- zclGeneral_ResetKeyEstablishRec( index );
- return ZCL_STATUS_SOFTWARE_FAILURE; // Memory allocation failure
- }
- // Derive the keying data using KDF function
- zclGeneral_KeyEstablishment_KeyDeriveFunction(zData,
- KEY_ESTABLISH_SHARED_SECRET_LENGTH,
- keyBit );
- // Save the derived 128-bit key and macKey
- osal_memcpy( keyEstablishRec[index].pMacKey, keyBit, KEY_ESTABLISH_MAC_KEY_LENGTH );
- osal_memcpy( keyEstablishRec[index].pKey, &(keyBit[KEY_ESTABLISH_MAC_KEY_LENGTH]),
- KEY_ESTABLISH_KEY_DATA_LENGTH);
- osal_mem_free( keyBit );
- // Key Bit generation success, send Ephemeral Data Response back
- zclGeneral_KeyEstablish_Send_EphemeralDataRsp( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
- &(keyEstablishRec[index].dstAddr),
- keyEstablishRec[index].pLocalEPublicKey,
- FALSE, keyEstablishRec[index].lastSeqNum );
- // The Request was processed successfuly, now the age timer needs to start based on the
- // remote Config Key Generate
- keyEstablishRec[index].age = keyEstablishRec[index].remoteConfKeyGenTime;
- // Start the Config Key Generate aging timer
- osal_start_reload_timer( zcl_KeyEstablishment_TaskID, KEY_ESTABLISHMENT_REC_AGING_EVT,
- KEY_ESTABLISHMENT_REC_AGING_INTERVAL );
- }
- else
- {
- // Key Bit generation failure. Send terminate key command
- zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
- &(keyEstablishRec[index].dstAddr),
- TermKeyStatus_BadKeyConfirm,
- KEY_ESTABLISHMENT_AVG_TIMEOUT,
- KEY_ESTABLISHMENT_SUITE,
- ZCL_FRAME_SERVER_CLIENT_DIR,
- FALSE, zcl_SeqNum++ );
- // Reset the entry
- zclGeneral_ResetKeyEstablishRec( index );
- #if defined (NWK_AUTO_POLL)
- // Restore the saved poll rate for end device
- NLME_SetPollRate(zclSavedPollRate);
- #endif
- return ZFailure;
- }
- keyEstablishRec[index].state = KeyEstablishState_ConfirmPending;
- return ZSuccess;
- }
- /*********************************************************************
- * @fn zclGeneral_InitiateKeyEstablish_Rsp_CalculateKey
- *
- * @brief Calculate the Key using ECC library upon receipt of
- * Ephemeral Data Response.
- *
- * @param none
- *
- * @return ZStatus_t - ZFailure @ Unsupported
- * ZCL_STATUS_MALFORMED_COMMAND
- * ZCL_STATUS_CMD_HAS_RSP
- */
- static ZStatus_t zclGeneral_InitiateKeyEstablish_Rsp_CalculateKey( void )
- {
- uint8 zData[KEY_ESTABLISH_SHARED_SECRET_LENGTH];
- uint8 MACu[KEY_ESTABLISH_MAC_LENGTH];
- uint8 *caPublicKey, *devicePrivateKey, *keyBit;
- uint8 index, ret, tmp, currentRxState;
- // It is possible to have multiple entries in the keyCalulationPending state.
- // Here we assume the partner that starts the key establishment procedure earlier
- // will have a smaller index in the table.
- // However, this might not apply due to different processing capability of
- // different processors.
- if ( (index = zclGeneral_GetKeyEstablishRecIndex_State( KeyEstablishState_KeyCalculatePending ))
- >= MAX_KEY_ESTABLISHMENT_REC_ENTRY )
- {
- return ZFailure;
- }
- if ((caPublicKey = osal_mem_alloc(ZCL_KE_CA_PUBLIC_KEY_LEN)) == NULL)
- {
- // Reset the entry from the rec table
- zclGeneral_ResetKeyEstablishRec( index );
- return ZCL_STATUS_SOFTWARE_FAILURE; // Memory allocation failure.
- }
- if ((devicePrivateKey = osal_mem_alloc(ZCL_KE_DEVICE_PRIVATE_KEY_LEN)) == NULL)
- {
- // Reset the entry from the rec table
- zclGeneral_ResetKeyEstablishRec( index );
- osal_mem_free(caPublicKey);
- return ZCL_STATUS_SOFTWARE_FAILURE; // Memory allocation failure.
- }
- osal_nv_read(ZCD_NV_CA_PUBLIC_KEY, 0, ZCL_KE_CA_PUBLIC_KEY_LEN, caPublicKey);
- osal_nv_read(ZCD_NV_DEVICE_PRIVATE_KEY, 0, ZCL_KE_DEVICE_PRIVATE_KEY_LEN, devicePrivateKey);
- ZMacGetReq( ZMacRxOnIdle, ¤tRxState ); // Save current radio state
- // Turn off the radio before the key bit generation, in order to avoid
- // incoming messages accumulation by interrupts during the long process time.
- tmp = FALSE;
- ZMacSetReq( ZMacRxOnIdle, &tmp );
- // Generate the Key Bits
- ret = ZSE_ECCKeyBitGenerate( devicePrivateKey, keyEstablishRec[index].pLocalEPrivateKey,
- keyEstablishRec[index].pLocalEPublicKey,
- keyEstablishRec[index].pRemoteCertificate,
- keyEstablishRec[index].pRemotePublicKey,
- caPublicKey, zData,
- zclGeneral_KeyEstablishment_HashFunc,
- zclKeyEstablish_YieldFunc, zclKeyEstablish_YieldLevel);
- ZMacSetReq( ZMacRxOnIdle, ¤tRxState ); // Resume saved radio state
- osal_mem_free(caPublicKey);
- osal_mem_free(devicePrivateKey);
- if ( ret != MCE_SUCCESS )
- {
- // Key Bit generation failure. Send terminate key command
- zclGeneral_KeyEstablish_Send_TerminateKeyEstablishment( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
- &(keyEstablishRec[index].dstAddr),
- TermKeyStatus_BadKeyConfirm,
- KEY_ESTABLISHMENT_AVG_TIMEOUT,
- KEY_ESTABLISHMENT_SUITE,
- ZCL_FRAME_CLIENT_SERVER_DIR,
- FALSE, zcl_SeqNum++ );
- // Reset the entry from the rec table
- zclGeneral_ResetKeyEstablishRec( index );
- #if defined (NWK_AUTO_POLL)
- // Restore the saved poll rate for end device
- NLME_SetPollRate(zclSavedPollRate);
- #endif
- return ZFailure;
- }
- else
- {
- // Allocate buffer to store KDF(Z) = MacKey || KeyData
- if ( (keyBit = osal_mem_alloc( KEY_ESTABLISH_KEY_DATA_LENGTH +
- KEY_ESTABLISH_MAC_KEY_LENGTH)) == NULL )
- {
- // Reset the entry from the rec table
- zclGeneral_ResetKeyEstablishRec( index );
- return ZCL_STATUS_SOFTWARE_FAILURE; // Memory allocation failure
- }
- // Derive the keying data using KDF function
- zclGeneral_KeyEstablishment_KeyDeriveFunction(zData,
- KEY_ESTABLISH_SHARED_SECRET_LENGTH,
- keyBit );
- // Save the derived 128-bit keyData
- osal_memcpy( keyEstablishRec[index].pMacKey, keyBit, KEY_ESTABLISH_KEY_DATA_LENGTH);
- osal_memcpy( keyEstablishRec[index].pKey, &(keyBit[KEY_ESTABLISH_MAC_KEY_LENGTH]),
- KEY_ESTABLISH_KEY_DATA_LENGTH);
- // Calculate MAC(U). Note that the keyBit is also pointing to the macKey
- zclGeneral_KeyEstablishment_GenerateMAC( index, TRUE, MACu );
- osal_mem_free( keyBit );
- // Send MAC(U) to the Partner
- zclGeneral_KeyEstablish_Send_ConfirmKey( ZCL_KEY_ESTABLISHMENT_ENDPOINT,
- &(keyEstablishRec[index].dstAddr),
- MACu,
- FALSE, zcl_SeqNum++ );
- // The Request was processed successfuly, now the age timer needs to start based on the
- // remote Config Key Generate
- keyEstablishRec[index].age = keyEstablishRec[index].remoteConfKeyGenTime;
- // Start the Config Key Generate aging timer
- osal_start_reload_timer( zcl_KeyEstablishment_TaskID, KEY_ESTABLISHMENT_REC_AGING_EVT,
- KEY_ESTABLISHMENT_REC_AGING_INTERVAL );
- keyEstablishRec[index].state = KeyEstablishState_ConfirmPending;
- return ZSuccess;
- }
- }
- /*********************************************************************
- * @fn zclGeneral_InitKeyEstablishRecTable
- *
- * @brief Initializae key establishment record table entries.
- *
- * @param none
- *
- * @return none
- */
- static void zclGeneral_InitKeyEstablishRecTable( void )
- {
- uint8 i;
- for ( i = 0; i < MAX_KEY_ESTABLISHMENT_REC_ENTRY; i++ )
- {
- zclGeneral_ResetKeyEstablishRec(i);
- }
- }
- /*********************************************************************
- * @fn zclGeneral_GetKeyEstablishRecIndex
- *
- * @brief Get the index of a particular key establishment record.
- * If the input is INVALID_PARTNER_ADDR, return an empty slot.
- *
- * @param partnerAddress - address of the partner that the local device
- * is establishing key with.
- *
- * @return index of the record
- */
- static uint8 zclGeneral_GetKeyEstablishRecIndex( uint16 partnerAddress )
- {
- uint8 i;
- // Find an existing entry or vacant entry, depends on what DstAddress is
- for ( i = 0; i < MAX_KEY_ESTABLISHMENT_REC_ENTRY ; i++ )
- {
- if ( keyEstablishRec[i].dstAddr.addr.shortAddr == partnerAddress )
- {
- // entry found
- break;
- }
- }
- return i;
- }
- /*********************************************************************
- * @fn zclGeneral_GetKeyEstablishRecIndex
- *
- * @brief Get the index of a particular key establishment record.
- * If the input is INVALID_PARTNER_ADDR, return an empty slot.
- *
- * @param state - state to find.
- *
- * @return index of the record
- */
- static uint8 zclGeneral_GetKeyEstablishRecIndex_State( KeyEstablishState_t state )
- {
- uint8 i;
- // Find an existing entry or vacant entry, depends on what DstAddress is
- for ( i = 0; i < MAX_KEY_ESTABLISHMENT_REC_ENTRY ; i++ )
- {
- if ( keyEstablishRec[i].state == state )
- {
- // entry found
- break;
- }
- }
- return i;
- }
- /*********************************************************************
- * @fn zclGeneral_AddKeyEstablishRec
- *
- * @brief Add a new key establishment record. If one already exist,
- * remove the existng entry. After initialization, fill in
- * partner short address and extended address. If partner extended
- * address not available, return failure.
- *
- * @param addr - address of the partner
- *
- * @return index - 0..(MAX_KEY_ESTABLISHMENT_REC_ENTRY-1) @ success
- * - MAX_KEY_ESTABLISHMENT_REC_ENTRY @ failure due to rec table full or
- * partner IEEE address not available or failure to allocate key buffers.
- */
- static uint8 zclGeneral_AddKeyEstablishRec( afAddrType_t *addr )
- {
- uint8 index, *pBuf;
- // Search for all current key establishment record
- // If not found, create a new entry
- if ( ( index = zclGeneral_GetKeyEstablishRecIndex(addr->addr.shortAddr) )
- < MAX_KEY_ESTABLISHMENT_REC_ENTRY )
- {
- // expire the existing entry for this address
- zclGeneral_ResetKeyEstablishRec( index );
- }
- // Create a new Entry
- if ( (index = zclGeneral_GetKeyEstablishRecIndex(INVALID_PARTNER_ADDR))
- < MAX_KEY_ESTABLISHMENT_REC_ENTRY )
- {
- // Allocate memory for the rest of the fields
- if ( (pBuf = osal_mem_alloc( ZCL_KE_DEVICE_PRIVATE_KEY_LEN +
- ZCL_KE_CA_PUBLIC_KEY_LEN +
- ZCL_KE_CA_PUBLIC_KEY_LEN +
- ZCL_KE_IMPLICIT_CERTIFICATE_LEN +
- KEY_ESTABLISH_KEY_DATA_LENGTH +
- KEY_ESTABLISH_MAC_KEY_LENGTH )) != NULL )
- {
- keyEstablishRec[index].pLocalEPrivateKey = pBuf;
- pBuf += ZCL_KE_DEVICE_PRIVATE_KEY_LEN;
- keyEstablishRec[index].pLocalEPublicKey = pBuf;
- pBuf += ZCL_KE_CA_PUBLIC_KEY_LEN;
- keyEstablishRec[index].pRemotePublicKey = pBuf;
- pBuf += ZCL_KE_CA_PUBLIC_KEY_LEN;
- keyEstablishRec[index].pRemoteCertificate = pBuf;
- pBuf += ZCL_KE_IMPLICIT_CERTIFICATE_LEN;
- keyEstablishRec[index].pKey = pBuf;
- pBuf += KEY_ESTABLISH_KEY_DATA_LENGTH;
- keyEstablishRec[index].pMacKey = pBuf;
- (void)osal_memcpy(&keyEstablishRec[index].dstAddr, addr, sizeof(afAddrType_t));
- // extAddr will be unknown when the initator first initiates the key establishment
- // It will be filled in later after the remote certificate is received.
- }
- else
- {
- index = MAX_KEY_ESTABLISHMENT_REC_ENTRY;
- }
- }
- return index;
- }
- /*********************************************************************
- * @fn zclGeneral_AgeKeyEstablishRec
- *
- * @brief Function to age Key Establish Rec. This function is called
- * as event handler for KEY_ESTABLISHMENT_REC_AGING_EVT every
- * second.
- *
- * @param none
- *
- * @return none
- */
- static void zclGeneral_AgeKeyEstablishRec( void )
- {
- uint8 i;
- bool recFound = FALSE;
- for ( i = 0; i < MAX_KEY_ESTABLISHMENT_REC_ENTRY; i++ )
- {
- // Only age valid rec entry
- if (keyEstablishRec[i].dstAddr.addrMode == afAddrNotPresent)
- {
- continue;
- }
- if (--(keyEstablishRec[i].age) == 0)
- {
- // Reset this table entry
- zclGeneral_ResetKeyEstablishRec( i );
- }
- else
- {
- recFound = TRUE;
- }
- }
- if ( recFound == FALSE )
- {
- osal_stop_timerEx( zcl_KeyEstablishment_TaskID, KEY_ESTABLISHMENT_REC_AGING_EVT );
- }
- }
- /*********************************************************************
- * @fn zclGeneral_ResetKeyEstablishRec
- *
- * @brief Reset specified key establishment record to initial value.
- *
- * @param index - index of table entry to reset
- *
- * @return ZStatus_t - ZSuccess or ZFailure
- */
- static void zclGeneral_ResetKeyEstablishRec( uint8 index )
- {
- uint8 *pKeys;
- pKeys = keyEstablishRec[index].pLocalEPrivateKey;
- if ( pKeys != NULL )
- {
- // All "Key infomation" was allocated in one block,
- // Clear the allocated memory to remove all copies of keys,
- (void)osal_memset( pKeys, 0, ZCL_KE_DEVICE_PRIVATE_KEY_LEN +
- ZCL_KE_CA_PUBLIC_KEY_LEN +
- ZCL_KE_CA_PUBLIC_KEY_LEN +
- ZCL_KE_IMPLICIT_CERTIFICATE_LEN +
- KEY_ESTABLISH_KEY_DATA_LENGTH +
- KEY_ESTABLISH_MAC_KEY_LENGTH );
- osal_mem_free( pKeys );
- }
- // Reset the table entry to initial state
- (void)osal_memset( &(keyEstablishRec[index]), 0, sizeof( zclKeyEstablishRec_t ) );
- keyEstablishRec[index].dstAddr.addrMode = afAddrNotPresent;
- keyEstablishRec[index].dstAddr.addr.shortAddr = INVALID_PARTNER_ADDR;
- keyEstablishRec[index].appTaskID = INVALID_TASK_ID;
- keyEstablishRec[index].age = KEY_ESTABLISHMENT_REC_EXPIRY_TIME;
- keyEstablishRec[index].state = KeyEstablishState_Idle;
- keyEstablishRec[index].remoteEphDataGenTime = KEY_ESTABLISHMENT_EPH_DATA_GEN_INVALID_TIME;
- keyEstablishRec[index].remoteConfKeyGenTime = KEY_ESTABLISHMENT_CONF_KEY_GEN_INVALID_TIME;
- }
- /*********************************************************************
- * @fn zclGeneral_KeyEstablishment_GetRandom
- *
- * @brief Fill in a buffer with random numbers
- *
- * @param buffer - output buffer
- * len - length of the buffer
- *
- * @return MCE_SUCCESS indicates success
- */
- static int zclGeneral_KeyEstablishment_GetRandom(unsigned char *buffer, unsigned long len)
- {
- uint8 *pBuf;
- pBuf = buffer;
- // Input to SSP_GetTrueRandAES assumes len <= SEC_KEY_LEN
- // Therefore, call SSP_GetTrueRandAES multiple times to
- // fill out the buffer.
- while( len > SEC_KEY_LEN )
- {
- SSP_GetTrueRandAES( SEC_KEY_LEN, pBuf );
- len -= SEC_KEY_LEN;
- pBuf += SEC_KEY_LEN;
- }
- SSP_GetTrueRandAES( len, pBuf );
- return MCE_SUCCESS;
- }
- /*********************************************************************
- * @fn zclGeneral_KeyEstablishment_HashFunc
- *
- * @brief Hash Function
- *
- * @param digest - output buffer 16 bytes
- * len - length of the input buffer
- * data - input buffer
- *
- * @return MCE_SUCCESS indicates success
- */
- static int zclGeneral_KeyEstablishment_HashFunc(unsigned char *digest, unsigned long len, unsigned char *data)
- {
- len *= 8; // Convert to bit length
- sspMMOHash( NULL, 0, data, (uint16)len, digest );
- return MCE_SUCCESS;
- }
- /*********************************************************************
- * @fn zclGeneral_KeyEstablishment_KeyDeriveFunction
- *
- * @brief Key Derive Function (ANSI X9.63).
- * Note this is not a generalized KDF. It only applies to the KDF
- * specified in ZigBee SE profile. Only the first two hashed keys
- * are calculated and concatenated.
- *
- * @param zData - input shared secret (length = KEY_ESTABLISH_SHARED_SECRET_LENGTH)
- * keyBitLen - input key data length
- * keyBit - output buffer ( 16*2 bytes)
- *
- * @return none
- */
- static void zclGeneral_KeyEstablishment_KeyDeriveFunction( uint8 *zData,
- uint8 keyBitLen,
- uint8 *keyBit )
- {
- uint8 hashCounter[4] = {0x00, 0x00, 0x00, 0x01};
- uint8 hashedData[KEY_ESTABLISH_SHARED_SECRET_LENGTH + 4];
- uint8 bitLen;
- bitLen = (keyBitLen + 4 ) * 8;
- // Calculate K1: Ki = Hash(Z || Counter1 )
- osal_memcpy( hashedData, zData, KEY_ESTABLISH_SHARED_SECRET_LENGTH );
- osal_memcpy( &(hashedData[KEY_ESTABLISH_SHARED_SECRET_LENGTH]), hashCounter, 4);
- sspMMOHash(NULL, 0, hashedData, bitLen, keyBit);
- // Indrement the counter
- hashedData[KEY_ESTABLISH_SHARED_SECRET_LENGTH + 3] = 0x02;
- sspMMOHash(NULL, 0, hashedData, bitLen, &(keyBit[KEY_ESTABLISH_KEY_DATA_LENGTH]));
- }
- /*********************************************************************
- * @fn zclGeneral_KeyEstablishment_GenerateMAC
- *
- * @brief Key Derive Function (ANSI X9.63).
- * Note this is not a generalized KDF. It only applies to the KDF
- * specified in ZigBee SE profile. Only the first two hashed keys
- * are calculated and concatenated.
- *
- * @param recIndex - input key establishment record index
- * ifMACu - use M(U) if TRUE, otherwise M(V)
- * MAC - output buffer ( 16 bytes )
- *
- * @return ZStatus_t - success
- */
- static ZStatus_t zclGeneral_KeyEstablishment_GenerateMAC(uint8 recIndex,
- uint8 ifMACu,
- uint8 *MAC)
- {
- uint8 i;
- uint8 M;
- uint8 *hashBuf;
- uint16 bufLen;
- // Assumption for M(U) and M(V) is: M(U) = 0x02, M(V) = 0x03
- if( ifMACu == TRUE )
- {
- M = 0x02; // Assumption
- }
- else
- {
- M = 0x03; // Assumption
- }
- // At this point, it is assumed the device has already
- // obtained the IEEE address of the partner device.
- for ( i = 0; i < Z_EXTADDR_LEN; i++ )
- {
- if ( keyEstablishRec[recIndex].partnerExtAddr[i] != 0 )
- {
- break;
- }
- }
- if ( i == Z_EXTADDR_LEN )
- {
- return ZFailure; // Partner IEEE address not available, return failure.
- }
- // MAC(U) = MAC(MacKey) { M(U) || ID(U) || ID(V) || E(U) || E(V) }
- bufLen = (1 + (Z_EXTADDR_LEN * 2) + (ZCL_KE_CA_PUBLIC_KEY_LEN * 2));
- if( ( hashBuf = osal_mem_alloc( (bufLen) )) == NULL )
- {
- return ZMemError; // Memory allocation error
- }
- // Fill in the buffer
- hashBuf[0] = M; // M(U)
- bufLen = bufLen * 8; // Convert to bitlength
- if ( (keyEstablishRec[recIndex].role == KEY_ESTABLISHMENT_INITIATOR && ifMACu == TRUE) ||
- (keyEstablishRec[recIndex].role == KEY_ESTABLISHMENT_RESPONDER && ifMACu == FALSE))
- {
- // MAC = MAC(MacKey) { M() || ID(L) || ID(R) || E(L) || E(R) }
- // L - Local, R - Remote
- SSP_MemCpyReverse( &(hashBuf[1]), NLME_GetExtAddr(), Z_EXTADDR_LEN); // ID(U)
- SSP_MemCpyReverse( &(hashBuf[1+Z_EXTADDR_LEN]), keyEstablishRec[recIndex].partnerExtAddr,
- Z_EXTADDR_LEN); // ID(V)
- osal_memcpy( &(hashBuf[1 + (2 * Z_EXTADDR_LEN)]), // E(U)
- keyEstablishRec[recIndex].pLocalEPublicKey,
- ZCL_KE_CA_PUBLIC_KEY_LEN );
- osal_memcpy( &(hashBuf[1 + (2 * Z_EXTADDR_LEN) + ZCL_KE_CA_PUBLIC_KEY_LEN]), // E(V)
- keyEstablishRec[recIndex].pRemotePublicKey, ZCL_KE_CA_PUBLIC_KEY_LEN );
- SSP_KeyedHash (hashBuf, bufLen, keyEstablishRec[recIndex].pMacKey, MAC);
- }
- else
- {
- // MAC = MAC(MacKey) { M() || ID(R) || ID(L) || E(R) || E(L) }
- // L - Local, R - Remote
- SSP_MemCpyReverse( &(hashBuf[1]), keyEstablishRec[recIndex].partnerExtAddr,
- Z_EXTADDR_LEN); // ID(R)
- SSP_MemCpyReverse( &(hashBuf[1 + Z_EXTADDR_LEN]), NLME_GetExtAddr(), Z_EXTADDR_LEN); // ID(L)
- osal_memcpy( &(hashBuf[ 1 + (2 * Z_EXTADDR_LEN)]), // E(R)
- keyEstablishRec[recIndex].pRemotePublicKey,
- ZCL_KE_CA_PUBLIC_KEY_LEN );
- osal_memcpy( &(hashBuf[1 + (2 * Z_EXTADDR_LEN) + ZCL_KE_CA_PUBLIC_KEY_LEN]), // E(U)
- keyEstablishRec[recIndex].pLocalEPublicKey,
- ZCL_KE_CA_PUBLIC_KEY_LEN );
- SSP_KeyedHash (hashBuf, bufLen, keyEstablishRec[recIndex].pMacKey, MAC);
- }
- osal_mem_free(hashBuf);
- return ZSuccess;
- }
- /*********************************************************************
- * @fn zclGeneral_KeyEstablishment_ECDSASign
- *
- * @brief Creates an ECDSA signature of a message digest.
- *
- * @param input - input data buffer
- * inputLen - byte length of the input buffer
- * output - output buffer ( 21x2 bytes )
- *
- * @return ZStatus_t - success
- */
- ZStatus_t zclGeneral_KeyEstablishment_ECDSASign( uint8 *input, uint8 inputLen,
- uint8 *output)
- {
- uint8 msgDigest[KEY_ESTABLISH_AES_MMO_HASH_SIZE];
- uint16 bitLen = inputLen * 8;
- uint8 status;
- uint8 *devicePrivateKey;
- if ((devicePrivateKey = osal_mem_alloc(ZCL_KE_DEVICE_PRIVATE_KEY_LEN)) == NULL)
- {
- return ZCL_STATUS_SOFTWARE_FAILURE; // Memory allocation failure.
- }
- osal_nv_read(ZCD_NV_DEVICE_PRIVATE_KEY, 0, ZCL_KE_DEVICE_PRIVATE_KEY_LEN, devicePrivateKey);
- // First hash the input buffer
- sspMMOHash(NULL, 0, input, bitLen, msgDigest);
- status = ZSE_ECDSASign( (unsigned char*)devicePrivateKey, (unsigned char*)msgDigest,
- zclGeneral_KeyEstablishment_GetRandom,
- (unsigned char*)output, (unsigned char*)output + KEY_ESTABLISH_POINT_ORDER_SIZE,
- zclKeyEstablish_YieldFunc, zclKeyEstablish_YieldLevel );
- osal_mem_free(devicePrivateKey);
- if (status == MCE_SUCCESS )
- {
- return ZSuccess;
- }
- return ZFailure;
- }
- /*********************************************************************
- * @fn zclGeneral_KeyEstablishment_ECDSAVerify
- *
- * @brief Verify an ECDSA signature of a message digest.
- *
- * @param input - input data buffer
- * inputLen - byte length of the input buffer
- * signature - input signature ( 21x2 bytes )
- *
- * @return ZSuccess - success verify
- * ZFailure - fail to verify
- */
- ZStatus_t zclGeneral_KeyEstablishment_ECDSAVerify( uint8 *input, uint8 inputLen,
- uint8 *signature)
- {
- uint8 msgDigest[KEY_ESTABLISH_AES_MMO_HASH_SIZE];
- uint16 bitLen;
- uint8 ret;
- bitLen = inputLen * 8;
- // First hash the input buffer
- sspMMOHash(NULL, 0, input, bitLen, msgDigest);
- ret = ZSE_ECDSAVerify((unsigned char*)NULL, (unsigned char*)msgDigest,
- (unsigned char*)signature, (unsigned char*)signature + KEY_ESTABLISH_POINT_ORDER_SIZE,
- zclKeyEstablish_YieldFunc, zclKeyEstablish_YieldLevel );
- if ( ret == MCE_SUCCESS )
- {
- return ZSuccess;
- }
- return ZFailure;
- }
- #endif // ZCL_KEY_ESTABLISH
- /***************************************************************************
- ****************************************************************************/
|