I am trying to enable security over HMI. As a starting point I am using the code from the SetSecurity command of the HMI demo application (over QCLI). I am able to successfully set all parameters (enable security, default key source, MAC keytable, key rotation sequence and key rotation. However, anytime I send a payload of data between two devices with the same security information, I always get back a MLME Comm Status Indication of 0xF3 (QAPI_HMI_STATUS_CODE_UNAVAILABLE_KEY). Any help would be appreciated.
Here is the code I am using as a starting point:
#define DEFAULT_KEY_SOURCE (0xFF00000000000000ULL) const static qapi_HMI_KeyDescriptor_t KeyDescriptorList[] = { { DEFAULT_KEY_SOURCE, QAPI_HMI_KEY_ID_MODE_8BYTE_SOURCE, 1, QAPI_HMI_KEY_USAGE_MASK_ALL, {0x71, 0x9F, 0xCC, 0xA9, 0x16, 0x6B, 0xB2, 0x2B, 0x6B, 0xBB, 0x70, 0xAA, 0xA9, 0xC, 0xD9, 0xE4}, }, { DEFAULT_KEY_SOURCE, QAPI_HMI_KEY_ID_MODE_8BYTE_SOURCE, 2, QAPI_HMI_KEY_USAGE_MASK_ALL, {0x4C, 0xC1, 0x4A, 0x35, 0x29, 0x84, 0xA0, 0x72, 0xA6, 0x95, 0x74, 0xB8, 0x4, 0xAC, 0x41, 0xD9}, }, { DEFAULT_KEY_SOURCE, QAPI_HMI_KEY_ID_MODE_8BYTE_SOURCE, 3, QAPI_HMI_KEY_USAGE_MASK_ALL, {0xA7, 0xF9, 0x53, 0x5F, 0xF, 0x93, 0xFE, 0xF5, 0x80, 0x96, 0xDA, 0x4A, 0x73, 0x4E, 0xFE, 0x7E}, } }; #define KEY_DESCRIPTOR_LIST_SIZE ( sizeof( KeyDescriptorList ) / sizeof( qapi_HMI_KeyDescriptor_t ) ) //============================================================================== /// Enable or disable security. /// /// \param[in] enabled Whether or not security should be enabled. /// /// \return QAPI status. /// static qapi_Status_t SetSecurity( bool_t enabled ) { qapi_Status_t result; uint8_t byte_pib; uint8_t key_index; uint8_t key_id_mode; uint64_t key_source_mask; uint8_t key_rotation_sequence[QAPI_HMI_KEY_ROTATION_SEQUENCE_LENGTH]; qapi_HMI_KeyDescriptor_t key_descriptor; uint64_t default_key_source; uint8_t status; uint8_t index; if ( s_mac_inst_id ) { key_index = 0; s_hmi_security.SecurityLevel = (uint8_t)QAPI_HMI_SECURITY_LEVEL_ENC; s_hmi_security.KeyIdMode = (uint8_t)QAPI_HMI_KEY_ID_MODE_8BYTE_SOURCE; s_hmi_security.KeyIndex = KeyDescriptorList[key_index].Index; s_hmi_security.KeySource = KeyDescriptorList[key_index].Source; /* Set security to be enabled. */ byte_pib = (uint8_t)enabled; /* Set the SecurityEnabled PIB. */ result = qapi_HMI_MLME_Set_Request( s_mac_inst_id, QAPI_HMI_PIB_MAC_SECURITY_ENABLED, 0, sizeof( byte_pib ), &byte_pib, &status ); if ( (result == QAPI_OK ) && ( status == QAPI_HMI_STATUS_CODE_SUCCESS ) ) { if ( byte_pib != 0 ) { /* Set the MAC DefaultKeySource. */ default_key_source = DEFAULT_KEY_SOURCE; result = qapi_HMI_MLME_Set_Request( s_mac_inst_id, QAPI_HMI_PIB_MAC_DEFAULT_KEY_SOURCE, 0, sizeof( key_descriptor.Source ), &default_key_source, &status ); if ( ( result == QAPI_OK ) && ( status == QAPI_HMI_STATUS_CODE_SUCCESS ) ) { memset( key_rotation_sequence, 0xFF, QAPI_HMI_KEY_ROTATION_SEQUENCE_LENGTH ); key_index = 0; key_id_mode = ( s_hmi_security.KeyIdMode == QAPI_HMI_KEY_ID_MODE_DEFAULT ) ? QAPI_HMI_KEY_ID_MODE_8BYTE_SOURCE : s_hmi_security.KeyIdMode; key_source_mask = ( key_id_mode == QAPI_HMI_KEY_ID_MODE_8BYTE_SOURCE ) ? 0xFFFFFFFFFFFFFFFFULL : 0xFFFFFFFFULL; // Set the MAC KeyTable. for ( index = 0; ( index < KEY_DESCRIPTOR_LIST_SIZE) && ( result == QAPI_OK ) && ( status == QAPI_HMI_STATUS_CODE_SUCCESS ); index++ ) { memscpy( &key_descriptor, sizeof( qapi_HMI_KeyDescriptor_t ), &(KeyDescriptorList[index]), sizeof( qapi_HMI_KeyDescriptor_t ) ); key_descriptor.IdMode = key_id_mode; key_descriptor.Source &= key_source_mask; result = qapi_HMI_MLME_Set_Request( s_mac_inst_id, QAPI_HMI_PIB_MAC_KEY_TABLE, index, sizeof( qapi_HMI_KeyDescriptor_t ), &key_descriptor, &status ); key_rotation_sequence[index] = index; } if ( ( result == QAPI_OK) && ( status == QAPI_HMI_STATUS_CODE_SUCCESS ) ) { // Set the key rotation sequence. result = qapi_HMI_MLME_Set_Request( s_mac_inst_id, QAPI_HMI_PIB_MAC_KEY_ROTATION_SEQUENCE, 0, sizeof( QAPI_HMI_KEY_ROTATION_SEQUENCE_LENGTH ), key_rotation_sequence, &status ); if ( ( result == QAPI_OK ) && ( status == QAPI_HMI_STATUS_CODE_SUCCESS ) ) { // Enable key rotation. byte_pib = 1; result = qapi_HMI_MLME_Set_Request( s_mac_inst_id, QAPI_HMI_PIB_MAC_ENABLE_KEY_ROTATION, 0, sizeof( byte_pib ), &byte_pib, &status ); if ( ( result == QAPI_OK ) && ( status == QAPI_HMI_STATUS_CODE_SUCCESS ) ) { LogDebug( "hmi: security set successfully.\n" ); } else { LogDebug( "hmi: failed to enable key rotation %d %d\n", result, status ); } } else { LogDebug( "hmi: failed to set the key rotation sequence %d %d\n", result, status ); } } else { LogDebug( "hmi: failed to set MAC KeyTable (index %d) %d %d\n", index - 1, result, status ); } } else { LogDebug( "hmi: failed to set MAC DefaultKeySource %d %d\n", result, status ); } } else { LogDebug( "hmi: security disabled successfully.\n" ); } } else { LogDebug( "hmi: failed to enable/disable security %d %d\n", result, status ); status = QAPI_ERROR; } } else { LogDebug( "hmi: HMI not initialized.\n" ); status = QAPI_ERROR; } return status; } #endif