Refactored MAC and IV calculations

This commit is contained in:
Daniel Karling 2023-10-27 06:52:30 +02:00
commit 011d1f6a44

View file

@ -251,6 +251,40 @@ static int ntag424_read_file_settings(uint8_t fileno, ntag424_file_settings_t *s
return PM3_SUCCESS; return PM3_SUCCESS;
} }
static void ntag424_calc_iv(ntag424_session_keys_t *session_keys, uint8_t *out_ivc) {
uint8_t iv_clear[] = { 0xa5, 0x5a,
session_keys->ti[0], session_keys->ti[1], session_keys->ti[2], session_keys->ti[3],
(uint8_t)(session_keys->command_counter), (uint8_t)(session_keys->command_counter >> 8),
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
uint8_t zero_iv[16] = {0};
aes_encode(zero_iv, session_keys->encryption, iv_clear, out_ivc, 16);
}
static void ntag424_calc_mac(ntag424_session_keys_t *session_keys, uint8_t command, uint8_t command_header, uint8_t *data, uint8_t datalen, uint8_t *out_mac) {
uint8_t mac_input_header[] = { command,
(uint8_t)session_keys->command_counter, (uint8_t)(session_keys->command_counter >> 8),
session_keys->ti[0], session_keys->ti[1], session_keys->ti[2], session_keys->ti[3],
command_header,
};
int mac_input_len = sizeof(mac_input_header) + datalen;
uint8_t *mac_input = (uint8_t*)malloc(mac_input_len);
memcpy(mac_input, mac_input_header, sizeof(mac_input_header));
memcpy(&mac_input[sizeof(mac_input_header)], data, datalen);
uint8_t mac[16] = {0};
mbedtls_aes_cmac_prf_128(session_keys->mac, 16, mac_input, sizeof(mac_input_header) + 32, mac);
for(int i = 0; i < 8; i++)
{
out_mac[i] = mac[i*2+1];
}
free(mac_input);
}
// Write file settings is done with full communication mode. This can probably be broken out // Write file settings is done with full communication mode. This can probably be broken out
// and used for read/write of file when full communication mode is needed. // and used for read/write of file when full communication mode is needed.
static int ntag424_write_file_settings(uint8_t fileno, ntag424_file_settings_t *settings, ntag424_session_keys_t *session_keys) { static int ntag424_write_file_settings(uint8_t fileno, ntag424_file_settings_t *settings, ntag424_session_keys_t *session_keys) {
@ -265,15 +299,8 @@ static int ntag424_write_file_settings(uint8_t fileno, ntag424_file_settings_t *
// ------- Calculate IV // ------- Calculate IV
uint8_t iv_clear[] = { 0xa5, 0x5a, uint8_t ivc[16];
session_keys->ti[0], session_keys->ti[1], session_keys->ti[2], session_keys->ti[3], ntag424_calc_iv(session_keys, ivc);
(uint8_t)(session_keys->command_counter), (uint8_t)(session_keys->command_counter >> 8),
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
uint8_t zero_iv[16] = {0};
uint8_t ivc[16] = {0};
aes_encode(zero_iv, session_keys->encryption, iv_clear, ivc, 16);
// ------- Encrypt file settings // ------- Encrypt file settings
uint8_t padded_cmddata_buffer[256] = {0}; uint8_t padded_cmddata_buffer[256] = {0};
@ -289,18 +316,8 @@ static int ntag424_write_file_settings(uint8_t fileno, ntag424_file_settings_t *
aes_encode(ivc, session_keys->encryption, padded_cmddata_buffer, encrypted_cmddata, total_size); aes_encode(ivc, session_keys->encryption, padded_cmddata_buffer, encrypted_cmddata, total_size);
// ------- Calculate MAC // ------- Calculate MAC
uint8_t mac_input_header[] = { 0x5f, uint8_t mact[8];
(uint8_t)session_keys->command_counter, (uint8_t)(session_keys->command_counter >> 8), ntag424_calc_mac(session_keys, 0x5f, fileno, encrypted_cmddata, total_size, mact);
session_keys->ti[0], session_keys->ti[1], session_keys->ti[2], session_keys->ti[3],
fileno // CmdHeader
};
uint8_t mac_input[256] = {0};
memcpy(mac_input, mac_input_header, sizeof(mac_input_header));
memcpy(&mac_input[sizeof(mac_input_header)], encrypted_cmddata, total_size);
uint8_t mac[16] = {0};
mbedtls_aes_cmac_prf_128(session_keys->mac, 16, mac_input, sizeof(mac_input_header) + total_size, mac);
uint8_t mact[8] = { mac[1], mac[3], mac[5], mac[7], mac[9], mac[11], mac[13], mac[15] };
// ------- Assemble the actual command // ------- Assemble the actual command
uint8_t lc = 1 + total_size + 8; // CmdHeader + size + mac*/ uint8_t lc = 1 + total_size + 8; // CmdHeader + size + mac*/
@ -675,15 +692,8 @@ static int ntag424_change_key(uint8_t keyno, uint8_t *new_key, uint8_t *old_key,
// ------- Calculate IV // ------- Calculate IV
uint8_t iv_clear[] = { 0xa5, 0x5a, uint8_t ive[16];
session_keys->ti[0], session_keys->ti[1], session_keys->ti[2], session_keys->ti[3], ntag424_calc_iv(session_keys, ive);
(uint8_t)(session_keys->command_counter), (uint8_t)(session_keys->command_counter >> 8),
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
uint8_t zero_iv[16] = {0};
uint8_t ive[16] = {0};
aes_encode(zero_iv, session_keys->encryption, iv_clear, ive, 16);
// ------- Calculate KeyData // ------- Calculate KeyData
uint8_t keydata[32] = {0}; uint8_t keydata[32] = {0};
@ -703,19 +713,8 @@ static int ntag424_change_key(uint8_t keyno, uint8_t *new_key, uint8_t *old_key,
aes_encode(ive, session_keys->encryption, keydata, enc_keydata, 32); aes_encode(ive, session_keys->encryption, keydata, enc_keydata, 32);
// -------- Calculate MAC // -------- Calculate MAC
uint8_t mac_input_header[] = { 0xC4, uint8_t mact[8];
(uint8_t)session_keys->command_counter, (uint8_t)(session_keys->command_counter >> 8), ntag424_calc_mac(session_keys, 0xC4, keyno, enc_keydata, 32, mact);
session_keys->ti[0], session_keys->ti[1], session_keys->ti[2], session_keys->ti[3],
keyno,
};
uint8_t mac_input[256] = {0};
memcpy(mac_input, mac_input_header, sizeof(mac_input_header));
memcpy(&mac_input[sizeof(mac_input_header)], enc_keydata, 32);
uint8_t mac[16] = {0};
mbedtls_aes_cmac_prf_128(session_keys->mac, 16, mac_input, sizeof(mac_input_header) + 32, mac);
uint8_t mact[8] = { mac[1], mac[3], mac[5], mac[7], mac[9], mac[11], mac[13], mac[15] };
// ------- Assemble APDU // ------- Assemble APDU
uint8_t cmd_header[] = { uint8_t cmd_header[] = {
@ -1290,7 +1289,8 @@ static int CmdHF_ntag424_changekey(const char *Cmd) {
CLIParserInit(&ctx, "hf ntag424 changekey", CLIParserInit(&ctx, "hf ntag424 changekey",
"Change a key.\n" "Change a key.\n"
"Authentication key must currently be different to the one we want to change.\n", "Authentication key must currently be different to the one we want to change.\n",
"hf ntag424 changekey -n 1 --oldkey 00000000000000000000000000000000 --newkey 11111111111111111111111111111111 --key0 00000000000000000000000000000000 -v 1" "hf ntag424 changekey -n 1 --oldkey 00000000000000000000000000000000 --newkey 11111111111111111111111111111111 --key0 00000000000000000000000000000000 -v 1\n"
"hf ntag424 changekey -n 0 --newkey 11111111111111111111111111111111 --key0 00000000000000000000000000000000 -v 1\n"
); );
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,