From 79f6cb20e52082e3bb28b713f221a69f93cdb32e Mon Sep 17 00:00:00 2001 From: Romain Tartiere Date: Sat, 18 Dec 2010 01:45:38 +0000 Subject: [PATCH] Update CMAC code to handle 64 and 128 bit keys. --- libfreefare/freefare_internal.h | 4 +-- libfreefare/mifare_desfire_authenticate.c | 40 +++++++++++++---------- test/test_mifare_desfire_aes.c | 4 +-- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/libfreefare/freefare_internal.h b/libfreefare/freefare_internal.h index 0296c1d..b1b2f90 100644 --- a/libfreefare/freefare_internal.h +++ b/libfreefare/freefare_internal.h @@ -209,8 +209,8 @@ struct mifare_desfire_key { } type; DES_key_schedule ks1; DES_key_schedule ks2; - uint8_t aes_sk1[16]; - uint8_t aes_sk2[16]; + uint8_t cmac_sk1[16]; + uint8_t cmac_sk2[16]; uint8_t aes_version; }; diff --git a/libfreefare/mifare_desfire_authenticate.c b/libfreefare/mifare_desfire_authenticate.c index dc32790..271c1e3 100644 --- a/libfreefare/mifare_desfire_authenticate.c +++ b/libfreefare/mifare_desfire_authenticate.c @@ -105,54 +105,58 @@ lsl (uint8_t *data, size_t len) void cmac_generate_subkeys (MifareDESFireKey key) { - uint8_t l[16]; - bzero (l, 16); + int kbs = key_block_size (key); + uint8_t R = (kbs == 8) ? 0x1B : 0x87; - uint8_t ivect[16]; - bzero (ivect, 16); + uint8_t l[kbs]; + bzero (l, kbs); - mifare_cbc_des (key, ivect, l, 16, MD_RECEIVE, 1); + uint8_t ivect[kbs]; + bzero (ivect, kbs); + + mifare_cbc_des (key, ivect, l, kbs, MD_RECEIVE, 1); bool xor = false; // Used to compute CMAC on complete blocks - memcpy (key->aes_sk1, l, 16); + memcpy (key->cmac_sk1, l, kbs); xor = l[0] & 0x80; - lsl (key->aes_sk1, 16); + lsl (key->cmac_sk1, kbs); if (xor) - key->aes_sk1[15] ^= 0x87; + key->cmac_sk1[kbs-1] ^= R; // Used to compute CMAC on the last block if non-complete - memcpy (key->aes_sk2, key->aes_sk1, 16); - xor = key->aes_sk1[0] & 0x80; - lsl (key->aes_sk2, 16); + memcpy (key->cmac_sk2, key->cmac_sk1, kbs); + xor = key->cmac_sk1[0] & 0x80; + lsl (key->cmac_sk2, kbs); if (xor) - key->aes_sk2[15] ^= 0x87; + key->cmac_sk2[kbs-1] ^= R; } void cmac (const MifareDESFireKey key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac) { - uint8_t *buffer = malloc (padded_data_length (len, key_block_size (key))); + int kbs = key_block_size (key); + uint8_t *buffer = malloc (padded_data_length (len, kbs)); if (!buffer) abort(); memcpy (buffer, data, len); - if ((!len) || (len % 16)) { + if ((!len) || (len % kbs)) { buffer[len++] = 0x80; - while (len % 16) { + while (len % kbs) { buffer[len++] = 0x00; } - xor (key->aes_sk2, buffer + len - 16, 16); + xor (key->cmac_sk2, buffer + len - kbs, kbs); } else { - xor (key->aes_sk1, buffer + len - 16, 16); + xor (key->cmac_sk1, buffer + len - kbs, kbs); } mifare_cbc_des (key, ivect, buffer, len, MD_SEND, 1); - memcpy (cmac, ivect, 16); + memcpy (cmac, ivect, kbs); free (buffer); } diff --git a/test/test_mifare_desfire_aes.c b/test/test_mifare_desfire_aes.c index 90efda7..3fdcdcb 100644 --- a/test/test_mifare_desfire_aes.c +++ b/test/test_mifare_desfire_aes.c @@ -59,8 +59,8 @@ test_mifare_desfire_aes_generate_subkeys (void) MifareDESFireKey key = mifare_desfire_aes_key_new (key_data); cmac_generate_subkeys (key); - cut_assert_equal_memory (sk1, 16, key->aes_sk1, 16, cut_message ("Wrong sub-key 1")); - cut_assert_equal_memory (sk2, 16, key->aes_sk2, 16, cut_message ("Wrong sub-key 2")); + cut_assert_equal_memory (sk1, 16, key->cmac_sk1, 16, cut_message ("Wrong sub-key 1")); + cut_assert_equal_memory (sk2, 16, key->cmac_sk2, 16, cut_message ("Wrong sub-key 2")); mifare_desfire_key_free (key); }