Hi,
I have a ATSHA204a configured to roll the key in slot 4 when the derivedKey command is executed. In the below example, I am able to reset the key to its original value, then I use the deriveKey command to "roll" the key. My problem is calculating the new key to run the checkMac command. I am either not calculating the rolled key correctly and/or I am not calculating the mac correctly. Any help is appreciated. If anyone has a working example and willing to share, that would be great.
In the below example, the slot is configured as follows:
Encrypted Read & Write are allowed
MAC required for running the derviedKey command
Parent Key = Key 2
Read Key = Key 9
uint8_t sha204_validate_key_roll(uint8_t *rootkey){ status = ATCA_SUCCESS; atca_nonce_in_out_t nonce_params; atca_temp_key_t temp_key; atca_check_mac_in_out_t checkmac_params; struct atca_derive_key_mac_in_out derivekey_mac_params; uint16_t target_key_id = 4; uint8_t parent_key[ATCA_KEY_SIZE] = {0}; uint8_t key_04[ATCA_KEY_SIZE] = {0}; uint8_t other_data[13] = {0}; uint8_t mac[ATCA_SHA_DIGEST_SIZE] = { '\0'}; uint8_t calc_derived_key_input[96] = { '\0'}; uint8_t num_in[NONCE_NUMIN_SIZE] = { '\0'}; uint8_t rand_out[RANDOM_NUM_SIZE] = { '\0'}; uint8_t sn[9] = { '\0'}; uint8_t response[CHECKMAC_CLIENT_RESPONSE_SIZE] = { '\0'}; uint8_t derived_key[ATCA_KEY_SIZE] = { '\0'}; uint8_t challenge[CHECKMAC_CLIENT_CHALLENGE_SIZE] = {0}; memset(&derived_key, 0, ATCA_KEY_SIZE); // get a random number for the challenge status = atcab_random(challenge); if(status != ATCA_SUCCESS){ sha204_parser_rc(status);return status;} // calculate the parent key (0x02 - used for the encrypting the key status = sha204_create_diverse_key(rootkey, 0x02, parent_key, 0x77); if (status != ATCA_SUCCESS) { return status; } // calculate the known original key 4 - this key is derived from the root status = sha204_create_diverse_key(rootkey, target_key_id, key_04, 0x77); if (status != ATCA_SUCCESS) {return status;} // get the devices serial number status = atcab_read_serial_number(sn); if (status != ATCA_SUCCESS){sha204_parser_rc(status);return status; } // Initialize the slot with a known key. key 2 is used for encryption. Key 4 is derived from the root key status = atcab_write_enc(target_key_id, 0, key_04, parent_key, 0x02); if (status != ATCA_SUCCESS) {sha204_parser_rc(status);return status;} // create the mac required for derive key SlotConfig<TargetKey>.Bit15 == 1 derivekey_mac_params.mode = DERIVE_KEY_MODE; derivekey_mac_params.target_key_id = target_key_id; derivekey_mac_params.sn = sn; derivekey_mac_params.parent_key = parent_key; derivekey_mac_params.mac = mac; status = atcah_derive_key_mac(&derivekey_mac_params); if (status != ATCA_SUCCESS) {sha204_parser_rc(status); return status; } //create the key with the deriveKey command status=sha204_diverse_key_example(target_key_id, mac, 0x77); if (status != ATCA_SUCCESS){printf("Unable to run derivedKey Command: ");sha204_parser_rc(status); return status; } // Perform random nonce memset(&temp_key, 0, sizeof(temp_key)); memset(num_in, 0, sizeof(num_in)); memset(&nonce_params, 0, sizeof(nonce_params)); nonce_params.mode = NONCE_MODE_SEED_UPDATE; nonce_params.zero = 0; nonce_params.num_in = num_in; nonce_params.rand_out = rand_out; nonce_params.temp_key = &temp_key; status = atcab_nonce_rand(nonce_params.num_in, rand_out); if (status != ATCA_SUCCESS) {printf("Unable to atcab_nonce_rand:\n\r"); sha204_parser_rc(status);return status; } // Calculate nonce value status = atcah_nonce(&nonce_params); if (status != ATCA_SUCCESS) {printf("Unable to atcah_nonce:\n\r"); sha204_parser_rc(status);return status; } uint8_t i; for (i = 0; i < sizeof(other_data); i++) { other_data[i] = (uint8_t)(i + 0xF0); } // calculate the new derived key memset(&calc_derived_key_input, 0, sizeof(calc_derived_key_input)); memcpy(&calc_derived_key_input[0], key_04, sizeof(key_04)); calc_derived_key_input[32] = ATCA_DERIVE_KEY; calc_derived_key_input[33] = CHECKMAC_MODE_BLOCK2_TEMPKEY; // param 1 calc_derived_key_input[34] = (uint8_t)target_key_id; // param 2 calc_derived_key_input[35] = 0x00; calc_derived_key_input[36] = sn[8]; calc_derived_key_input[37] = sn[0]; calc_derived_key_input[38] = sn[1]; memcpy(&calc_derived_key_input[64], &temp_key.value[0], 32); status = atcac_sw_sha2_256(calc_derived_key_input, sizeof(calc_derived_key_input), derived_key); if (status != ATCA_SUCCESS) {sha204_parser_rc(status); return status;} // Calculate response checkmac_params.mode = CHECKMAC_MODE_BLOCK2_TEMPKEY; checkmac_params.key_id = target_key_id; checkmac_params.client_chal = NULL; checkmac_params.client_resp = response; checkmac_params.other_data = other_data; checkmac_params.sn = sn; checkmac_params.otp = NULL; checkmac_params.slot_key = derived_key; checkmac_params.target_key = derived_key; checkmac_params.temp_key = &temp_key; status = atcah_check_mac(&checkmac_params); // software if (status != ATCA_SUCCESS){printf("Unable to atcah_check_mac for key %d:\n\r", target_key_id); sha204_parser_rc(status); return status; } // Perform CheckMac on Hardware status = atcab_checkmac(checkmac_params.mode,checkmac_params.key_id,checkmac_params.client_chal, checkmac_params.client_resp,checkmac_params.other_data); if (status != ATCA_SUCCESS) {printf("Unable to atcab_checkmac for key %d: ", target_key_id);sha204_parser_rc(status);} return status; }