This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2652R: Security: Joining procedure and key

Part Number: CC2652R
Other Parts Discussed in Thread: Z-STACK, SYSCONFIG

Hi, 

I am trying to get more familiar with the security aspect of Zigbee. 
If I have understood it correctly, the APS layer is encrypted with Trusted Center link Key and the NWK layer is encrypted with NWK key that is randomly generated by default.
Zigbee has 128-bit AES with CCM encryption. Is both APS layer and NWK layer keys encrypted using those algorithms? If so, where is the AES CCM algorithm located? 


Z-Stack user guide covers "unsecure join to centralized network" chapter.
In step 7 the joining device request "Unique Trust Center link key", where is that key generated and how can i configure it? By default is ZG_UNIQUE_LINK_KEY 0x00 set to False, that means that key is also random generated? 
Now that the joining device have the key, where does it do the hash function encryption?  
In step 9 the key received from the joining device is compared with the hashed key associated to the device (lets say coordinator), where is that hashed key located and how is the comparison procedure executed? 

What is considered as "secure" join to a centralized network, how will the procedure be? 

I am very new to network security and that's why I am trying to understand every step of the procedure correctly. Excuse me if i am not making any sense.

Best Regards,
Hamza

  • Hi Hamza,

    Yes, your understanding of the keys is correct.  In Zigbee 3.0 a new Trust Center Link Key is also generated randomly to replace the global TCLK after joining the network.  If you read the comments in zglobals.c you will see that to create specific unique link keys for each device you will have to set zgApsLinkKeyType to ZG_UNIQUE_LINK_KEY, zgUseDefaultTCLK to FALSE (for ZC, TRUE otherwise), then manually configure the link key between each device on the trust center with NV write commands. I recommend using install codes (BDB_DEFAULT_JOIN_USES_INSTALL_CODE_KEY) or pre-configured network keys (zgPreConfigKeys to TRUE and Default Network Key in SysConfig -> Z-Stack -> Network).  You can change the TC Link Key from the global default if you don't need to follow the Zigbee Spec or want interoperability with third-party devices.  These options would be the closest to a "secure join" method.  I can help further if you determine exactly what your application needs to achieve.

    The AES CCM algorithm and hash function encryption is handled in the pre-compiled Z-Stack libraries on the MAC High level, but you can look at the Stack/sec folder for involved APIs.

    Regards,
    Ryan

  • Hi Ryan! 

    What I am trying to understand/do is the following; 

    Assuming the joining device has access to TCLK which allows it to encrypt APS commands (TCLK is configured accordingly). The device gets network key through transport command, the device is then allowed to communicate in the network during that time (?) 
    The next step is then to request, transport and verify the key. The key transported is ran through hash function (Assuming MMO) on the joining device, and then received by the coordinator and compared with local hash key, the outcome is compared - Seems like this step is always verified and accepting of the joining device and not dependent on the key?

    To do a simple implementation such that the joining devices has to verify their key, some type of authentication to join the network. Similar to the verifying key steps. Is it possible to change the joining device procedure? Such that the transport key command of the network key is done after the authentication? 


    Is there an api available for access of TRNG? 

    Best regards,
    Hamza

  • Hi Hamza,

    The device is allowed to communicate on the network after receiving the NWK key, but may be asked to leave by the ZC if a TCLK update is required (BDB_DEFAULT_TC_REQUIRE_KEY_EXCHANGE).  If required then the joining device will attempt the TCLK exchange a maximum of BDB_DEFAULT_TC_LINK_KEY_EXCHANGE_ATTEMPS_MAX then perform a factory reset after BDBC_TC_LINK_KEY_EXANGE_TIMEOUT / BDB_TC_LINK_KEY_EXCHANGE_FAIL_LEAVE_TIMEOUT has expired.  Therefore, the TCLK update using the NWK key could be seen as a form of authentication.  Otherwise your understanding of the joining and key update process appears to be correct.

    Here is a link to the TI Driver TRNG API: http://dev.ti.com/tirex/content/simplelink_cc13x2_26x2_sdk_3_40_00_02/docs/tidrivers/doxygen/html/_t_r_n_g_c_c26_x_x_8h.html 

    Regards,
    Ryan

  • Hi Ryan,

    Cheers, I will try it! 

    Further, I have looked over this advanced security implementation and how the use the available drivers. Additionally, example aeskeyagreement shows an example of encrypting and decrypting messages. I wonder where the APS and NWK layer encryption and decryption occur in the code? In startup folder, the zstackstartup.c where most of the initialization occur, but I don't seem to find where we encrypt/decrypt APS & NWK layer. 

    Best Regards,

    Hamza

  • Hi Hamza,

    Key encryption/decryption occurs in the pre-compiled Zigbee libraries on the APSME layer and cannot be accessed by the user.  You can however reference the security drivers/examples and utilize them for your application purposes.

    Regards,
    Ryan

  • Hi again Ryan, 

    I have implemented such that we have preconfigured network keys on each device (trying to eliminate the transport nwk key command) but it don't seem to work. I have zgPreConfigKeys  = TRUE 

    Is it supposed to still transport nwk key or it shouldn't? A bit confused..

    Regards,
    Hamza 

  • Hi Hamza,

    It will not transport the NWK key but it will update the TC Link key.  You need to set the DEFAULT_KEY in SysConfig on each device to a value other than all 0x00.

    Regards,
    Ryan

  • Hi Ryan, 

    It is still transporting the nwk key, zgPreConfigKeys = TRUE and NWK key on Coordinator is changed accordingly

    Regards,
    Hamza

  • These changes have to apply to the joining ZR/ZEDs as well so that they are aware of the new network key.  You should not have to change zgPreConfigKeys as it will detect an initialized DEFAULT_KEY.

    Regards,
    Ryan

  • I applied those changes but the coordinator still transports the network key. 

    Regards,
    Hamza

  • Hi Hamza,

    I was mistaken and apologize for the confusion.  After further investigation I have determined that the network key is set over-the-air by default, the ZC's firmware will need to be modified such that the ZDSecMgrDeviceJoin function of zd_sec_mgr.c does not allow for ZDSecMgrSendNwkKey on DEV_SEC_INIT_STATUS devices.  You will then need to modify the ZED firmware to load and use the preconfigured NWK key without receiving a ZDO_TRANSPORT_KEY_IND message and servicing the ZDSecMgrTransportKeyInd function.  I would recommend that you look at modifying zgPreconfigKeyInit, ZBA_FALLBACK_NWKKEY, and ZDApp_SaveNwkKey.  Perhaps consider using a rejoin state for the ZED since it already has NWK & APS security.

    Regards,
    Ryan

  • Hi Ryan! 

    In transportkey ind the end device registers the TC address and other attributes of the coordinator, that's why if transport key is not received on ZED it will just wait and timeout. My approach would be to if we could move the TC address and other attributes once the device has received association response, is it possible? Or is there a better solution to that? 
    Another approach that I'm currently working one is one-way authentication, we use transprot key command to send over a public key and that the device uses to generate the symmetric key for communication - looks promising so far. 

    Looking at Fallback_NWKKEY, I think it is similar to what we are doing now, reading generated key from NV and setting it as NWK key. 

    Thank you for the help! 

    Best Regards,
    Hamza

  • You will need to update the TC address and key attributes in NV and can most likely accomplish this inside the ZDO_JoinConfirmCB or ZDApp_ProcessNetworkJoin.

    Regards,
    Ryan