From ebd98b32e094073c764865da39e9a2d90554ee05 Mon Sep 17 00:00:00 2001 From: Romain Tartiere Date: Sat, 18 Dec 2010 03:07:16 +0000 Subject: [PATCH] Switch from obscure 'int mac' argument to 'MifareCryptoOperation operation'. --- libfreefare/freefare_internal.h | 7 +++- libfreefare/mifare_desfire.c | 6 ++-- libfreefare/mifare_desfire_crypto.c | 55 +++++++++++++++++------------ test/test_mifare_desfire_des.c | 4 +-- 4 files changed, 44 insertions(+), 28 deletions(-) diff --git a/libfreefare/freefare_internal.h b/libfreefare/freefare_internal.h index 139d476..8dc626c 100644 --- a/libfreefare/freefare_internal.h +++ b/libfreefare/freefare_internal.h @@ -119,6 +119,11 @@ typedef enum { MD_RECEIVE } MifareDirection; +typedef enum { + MCO_ENCYPHER, + MCO_DECYPHER +} MifareCryptoOperation; + #define MDCM_MASK 0x000F #define CMAC_NONE 0 @@ -141,7 +146,7 @@ typedef enum { void *mifare_cryto_preprocess_data (MifareTag tag, void *data, size_t *nbytes, off_t offset, int communication_settings); void *mifare_cryto_postprocess_data (MifareTag tag, void *data, ssize_t *nbytes, int communication_settings); -void mifare_cbc_des (MifareDESFireKey key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareDirection direction, int mac); +void mifare_cbc_des (MifareDESFireKey key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareDirection direction, MifareCryptoOperation operation); void rol (uint8_t *data, const size_t len); void desfire_crc32 (const uint8_t *data, const size_t len, uint8_t *crc); void desfire_crc32_append (uint8_t *data, const size_t len); diff --git a/libfreefare/mifare_desfire.c b/libfreefare/mifare_desfire.c index 477a24d..0731c3c 100644 --- a/libfreefare/mifare_desfire.c +++ b/libfreefare/mifare_desfire.c @@ -349,7 +349,7 @@ authenticate (MifareTag tag, uint8_t cmd, uint8_t key_no, MifareDESFireKey key) uint8_t PICC_RndB[16]; memcpy (PICC_RndB, PICC_E_RndB, key_length); - mifare_cbc_des (key, MIFARE_DESFIRE (tag)->ivect, PICC_RndB, key_length, MD_RECEIVE, 0); + mifare_cbc_des (key, MIFARE_DESFIRE (tag)->ivect, PICC_RndB, key_length, MD_RECEIVE, MCO_DECYPHER); uint8_t PCD_RndA[16]; RAND_bytes (PCD_RndA, 16); @@ -362,7 +362,7 @@ authenticate (MifareTag tag, uint8_t cmd, uint8_t key_no, MifareDESFireKey key) memcpy (token, PCD_RndA, key_length); memcpy (token+key_length, PCD_r_RndB, key_length); - mifare_cbc_des (key, MIFARE_DESFIRE (tag)->ivect, token, 2 * key_length, MD_SEND, (0x0A == cmd) ? 0 : 1); + mifare_cbc_des (key, MIFARE_DESFIRE (tag)->ivect, token, 2 * key_length, MD_SEND, (0x0A == cmd) ? MCO_DECYPHER : MCO_ENCYPHER); BUFFER_INIT (cmd2, 33); @@ -376,7 +376,7 @@ authenticate (MifareTag tag, uint8_t cmd, uint8_t key_no, MifareDESFireKey key) uint8_t PICC_RndA_s[16]; memcpy (PICC_RndA_s, PICC_E_RndA_s, key_length); - mifare_cbc_des (key, MIFARE_DESFIRE (tag)->ivect, PICC_RndA_s, key_length, MD_RECEIVE, 0); + mifare_cbc_des (key, MIFARE_DESFIRE (tag)->ivect, PICC_RndA_s, key_length, MD_RECEIVE, MCO_DECYPHER); uint8_t PCD_RndA_s[key_length]; memcpy (PCD_RndA_s, PCD_RndA, key_length); diff --git a/libfreefare/mifare_desfire_crypto.c b/libfreefare/mifare_desfire_crypto.c index 4b72485..c35e61e 100644 --- a/libfreefare/mifare_desfire_crypto.c +++ b/libfreefare/mifare_desfire_crypto.c @@ -71,7 +71,7 @@ #define CMAC_LENGTH 8 static void xor (const uint8_t *ivect, uint8_t *data, const size_t len); -static void mifare_des (MifareDESFireKey key, uint8_t *data, uint8_t *ivect, MifareDirection direction, int mac, size_t block_size); +static void mifare_des (MifareDESFireKey key, uint8_t *data, uint8_t *ivect, MifareDirection direction, MifareCryptoOperation operation, size_t block_size); static void desfire_crc32_byte (uint32_t *crc, const uint8_t value); static size_t key_macing_length (MifareDESFireKey key); @@ -114,7 +114,7 @@ cmac_generate_subkeys (MifareDESFireKey key) uint8_t ivect[kbs]; bzero (ivect, kbs); - mifare_cbc_des (key, ivect, l, kbs, MD_RECEIVE, 1); + mifare_cbc_des (key, ivect, l, kbs, MD_RECEIVE, MCO_ENCYPHER); bool xor = false; @@ -154,7 +154,7 @@ cmac (const MifareDESFireKey key, uint8_t *ivect, const uint8_t *data, size_t le xor (key->cmac_sk1, buffer + len - kbs, kbs); } - mifare_cbc_des (key, ivect, buffer, len, MD_SEND, 1); + mifare_cbc_des (key, ivect, buffer, len, MD_SEND, MCO_ENCYPHER); memcpy (cmac, ivect, kbs); @@ -345,7 +345,7 @@ mifare_cryto_preprocess_data (MifareTag tag, void *data, size_t *nbytes, off_t o // ... and 0 padding memset ((uint8_t *)res + *nbytes, 0, edl - *nbytes); - mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, MIFARE_DESFIRE (tag)->ivect, (uint8_t *) res + offset, edl - offset, MD_SEND, 1); + mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, MIFARE_DESFIRE (tag)->ivect, (uint8_t *) res + offset, edl - offset, MD_SEND, MCO_ENCYPHER); memcpy (mac, (uint8_t *)res + edl - 8, 4); @@ -433,7 +433,7 @@ mifare_cryto_preprocess_data (MifareTag tag, void *data, size_t *nbytes, off_t o *nbytes = edl; - mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, MIFARE_DESFIRE (tag)->ivect, (uint8_t *) res + offset, *nbytes - offset, MD_SEND, (key->type == T_3K3DES) ? 1 : 0); + mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, MIFARE_DESFIRE (tag)->ivect, (uint8_t *) res + offset, *nbytes - offset, MD_SEND, (key->type == T_3K3DES) ? MCO_ENCYPHER : MCO_DECYPHER); break; case T_AES: @@ -452,7 +452,7 @@ mifare_cryto_preprocess_data (MifareTag tag, void *data, size_t *nbytes, off_t o pdl = padded_data_length (*nbytes - offset, key_block_size (MIFARE_DESFIRE (tag)->session_key)); bzero ((uint8_t *)res + *nbytes, (offset + pdl) - (*nbytes)); } - mifare_cbc_des (key, MIFARE_DESFIRE (tag)->ivect, (uint8_t *)res + offset, pdl, MD_SEND, 1); + mifare_cbc_des (key, MIFARE_DESFIRE (tag)->ivect, (uint8_t *)res + offset, pdl, MD_SEND, MCO_ENCYPHER); *nbytes = offset + pdl; break; @@ -509,7 +509,7 @@ mifare_cryto_postprocess_data (MifareTag tag, void *data, ssize_t *nbytes, int c memcpy (edata, data, *nbytes - 1); memset ((uint8_t *)edata + *nbytes - 1, 0, edl - *nbytes + 1); - mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, MIFARE_DESFIRE (tag)->ivect, edata, edl, MD_SEND, 1); + mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, MIFARE_DESFIRE (tag)->ivect, edata, edl, MD_SEND, MCO_ENCYPHER); /* ,^^^^^^^ * No! This is not a typo! --------------------------------------------------------------' */ @@ -569,7 +569,7 @@ mifare_cryto_postprocess_data (MifareTag tag, void *data, ssize_t *nbytes, int c case T_DES: case T_3DES: (*nbytes)--; - mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, MIFARE_DESFIRE (tag)->ivect, res, *nbytes, MD_RECEIVE, 0); + mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, MIFARE_DESFIRE (tag)->ivect, res, *nbytes, MD_RECEIVE, MCO_DECYPHER); /* * Look for the CRC and ensure it is followed by NULL padding. We @@ -611,7 +611,7 @@ mifare_cryto_postprocess_data (MifareTag tag, void *data, ssize_t *nbytes, int c case T_3K3DES: case T_AES: (*nbytes)--; - mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, MIFARE_DESFIRE (tag)->ivect, res, *nbytes, MD_RECEIVE, 0); + mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, MIFARE_DESFIRE (tag)->ivect, res, *nbytes, MD_RECEIVE, MCO_DECYPHER); uint8_t *p = ((uint8_t *)res) + *nbytes - 1; while (!*p) { p--; @@ -654,8 +654,9 @@ mifare_cryto_postprocess_data (MifareTag tag, void *data, ssize_t *nbytes, int c } static void -mifare_des (MifareDESFireKey key, uint8_t *data, uint8_t *ivect, MifareDirection direction, int mac, size_t block_size) +mifare_des (MifareDESFireKey key, uint8_t *data, uint8_t *ivect, MifareDirection direction, MifareCryptoOperation operation, size_t block_size) { + AES_KEY k; uint8_t ovect[MAX_CRYPTO_BLOCK_SIZE]; if (direction == MD_SEND) { @@ -668,43 +669,53 @@ mifare_des (MifareDESFireKey key, uint8_t *data, uint8_t *ivect, MifareDirection switch (key->type) { case T_DES: - if (mac) { + switch (operation) { + case MCO_ENCYPHER: DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT); - } else { + break; + case MCO_DECYPHER: DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT); + break; } break; case T_3DES: - if (mac) { + switch (operation) { + case MCO_ENCYPHER: DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT); DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT); DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT); - } else { + break; + case MCO_DECYPHER: DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT); DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT); DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT); + break; } break; case T_3K3DES: - if (mac) { + switch (operation) { + case MCO_ENCYPHER: DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT); DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT); DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_ENCRYPT); - } else { + break; + case MCO_DECYPHER: DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_DECRYPT); DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT); DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT); + break; } break; case T_AES: - if (mac) { - AES_KEY k; + switch (operation) { + case MCO_ENCYPHER: AES_set_encrypt_key (key->data, 8*16, &k); AES_encrypt (data, edata, &k); - } else { - AES_KEY k; + break; + case MCO_DECYPHER: AES_set_decrypt_key (key->data, 8*16, &k); AES_decrypt (data, edata, &k); + break; } break; } @@ -720,7 +731,7 @@ mifare_des (MifareDESFireKey key, uint8_t *data, uint8_t *ivect, MifareDirection } void -mifare_cbc_des (MifareDESFireKey key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareDirection direction, int mac) +mifare_cbc_des (MifareDESFireKey key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareDirection direction, MifareCryptoOperation operation) { size_t block_size; @@ -739,7 +750,7 @@ mifare_cbc_des (MifareDESFireKey key, uint8_t *ivect, uint8_t *data, size_t data size_t offset = 0; while (offset < data_size) { - mifare_des (key, data + offset, ivect, direction, mac, block_size); + mifare_des (key, data + offset, ivect, direction, operation, block_size); offset += block_size; } } diff --git a/test/test_mifare_desfire_des.c b/test/test_mifare_desfire_des.c index a4b9404..aad0131 100644 --- a/test/test_mifare_desfire_des.c +++ b/test/test_mifare_desfire_des.c @@ -45,7 +45,7 @@ test_mifare_desfire_des_receive (void) uint8_t expected_data[8] = { 0x73, 0x0d, 0xdf, 0xad, 0xa4, 0xd2, 0x07, 0x89 }; uint8_t expected_key[8] = { 1, 1, 1, 1, 1, 1, 1, 1 }; - mifare_cbc_des (key, null_ivect, data, 8, MD_RECEIVE, 0); + mifare_cbc_des (key, null_ivect, data, 8, MD_RECEIVE, MCO_DECYPHER); cut_assert_equal_memory (&expected_data, 8, &data, 8, cut_message ("Wrong data")); cut_assert_equal_memory (&expected_key, 8, key->data, 8, cut_message ("Wrong key")); @@ -64,7 +64,7 @@ test_mifare_desfire_des_send (void) uint8_t expected_data[8] = { 0xd6, 0x59, 0xe1, 0x70, 0x43, 0xa8, 0x40, 0x68 }; uint8_t expected_key[8] = { 1, 1, 1, 1, 1, 1, 1, 1 }; - mifare_cbc_des (key, null_ivect, data, 8, MD_SEND, 0); + mifare_cbc_des (key, null_ivect, data, 8, MD_SEND, MCO_DECYPHER); cut_assert_equal_memory (&expected_data, 8, &data, 8, cut_message ("Wrong data")); cut_assert_equal_memory (&expected_key, 8, key->data, 8, cut_message ("Wrong key"));