From 356219e21b0f29a09af188c20ba2af062d3b1672 Mon Sep 17 00:00:00 2001 From: Romain Tartiere Date: Fri, 29 Oct 2010 12:22:47 +0000 Subject: [PATCH] Require the ivect to be provided to mifare_cbc_des(). - Store ivect in the struct mifare_desfire_tag; - Reset it before and after authentication; - Reset before each crypto operation (for now). --- libfreefare/freefare_internal.h | 3 ++- libfreefare/mifare_desfire.c | 15 +++++++++------ libfreefare/mifare_desfire_authenticate.c | 23 +++++++++++++---------- test/test_mifare_desfire_des.c | 6 ++++-- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/libfreefare/freefare_internal.h b/libfreefare/freefare_internal.h index 08d81cd..059f282 100644 --- a/libfreefare/freefare_internal.h +++ b/libfreefare/freefare_internal.h @@ -116,7 +116,7 @@ typedef enum { void *mifare_cryto_preprocess_data (MifareTag tag, void *data, size_t *nbytes, 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 *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, int mac); void rol (uint8_t *data, const size_t len); void *assert_crypto_buffer_size (MifareTag tag, size_t nbytes); @@ -183,6 +183,7 @@ struct mifare_desfire_tag { char *last_pcd_error; MifareDESFireKey session_key; uint8_t authenticated_key_no; + uint8_t ivect[16]; uint8_t *crypto_buffer; size_t crypto_buffer_size; uint8_t block_number; diff --git a/libfreefare/mifare_desfire.c b/libfreefare/mifare_desfire.c index faf8099..4f03f4b 100644 --- a/libfreefare/mifare_desfire.c +++ b/libfreefare/mifare_desfire.c @@ -327,6 +327,8 @@ mifare_desfire_authenticate (MifareTag tag, uint8_t key_no, MifareDESFireKey key ASSERT_ACTIVE (tag); ASSERT_MIFARE_DESFIRE (tag); + bzero (MIFARE_DESFIRE (tag)->ivect, 16); + MIFARE_DESFIRE (tag)->last_picc_error = OPERATION_OK; MIFARE_DESFIRE (tag)->authenticated_key_no = NOT_YET_AUTHENTICATED; @@ -347,7 +349,7 @@ mifare_desfire_authenticate (MifareTag tag, uint8_t key_no, MifareDESFireKey key uint8_t PICC_RndB[8]; memcpy (PICC_RndB, PICC_E_RndB, 8); - mifare_cbc_des (key, PICC_RndB, 8, MD_RECEIVE, 0); + mifare_cbc_des (key, MIFARE_DESFIRE (tag)->ivect, PICC_RndB, 8, MD_RECEIVE, 0); uint8_t PCD_RndA[8]; DES_random_key ((DES_cblock*)&PCD_RndA); @@ -360,7 +362,7 @@ mifare_desfire_authenticate (MifareTag tag, uint8_t key_no, MifareDESFireKey key memcpy (token, PCD_RndA, 8); memcpy (token+8, PCD_r_RndB, 8); - mifare_cbc_des (key, token, 16, MD_SEND, 0); + mifare_cbc_des (key, MIFARE_DESFIRE (tag)->ivect, token, 16, MD_SEND, 0); BUFFER_INIT (cmd2, 17); @@ -374,7 +376,7 @@ mifare_desfire_authenticate (MifareTag tag, uint8_t key_no, MifareDESFireKey key uint8_t PICC_RndA_s[8]; memcpy (PICC_RndA_s, PICC_E_RndA_s, 8); - mifare_cbc_des (key, PICC_RndA_s, 8, MD_RECEIVE, 0); + mifare_cbc_des (key, MIFARE_DESFIRE (tag)->ivect, PICC_RndA_s, 8, MD_RECEIVE, 0); uint8_t PCD_RndA_s[8]; memcpy (PCD_RndA_s, PCD_RndA, 8); @@ -387,6 +389,7 @@ mifare_desfire_authenticate (MifareTag tag, uint8_t key_no, MifareDESFireKey key MIFARE_DESFIRE (tag)->authenticated_key_no = key_no; MIFARE_DESFIRE (tag)->session_key = mifare_desfire_session_key_new (PCD_RndA, PICC_RndB, key); + bzero (MIFARE_DESFIRE (tag)->ivect, 16); return 0; } @@ -409,7 +412,7 @@ mifare_desfire_change_key_settings (MifareTag tag, uint8_t settings) iso14443a_crc (data, 1, data + 1); bzero (data+3, 5); - mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, data, 8, MD_SEND, 0); + mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, MIFARE_DESFIRE (tag)->ivect, data, 8, MD_SEND, 0); BUFFER_APPEND_BYTES (cmd, data, 8); @@ -482,7 +485,7 @@ mifare_desfire_change_key (MifareTag tag, uint8_t key_no, MifareDESFireKey new_k } } - mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, data, 24, MD_SEND, 0); + mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, MIFARE_DESFIRE (tag)->ivect, data, 24, MD_SEND, 0); BUFFER_APPEND_BYTES (cmd, data, 24); @@ -791,7 +794,7 @@ mifare_desfire_change_file_settings (MifareTag tag, uint8_t file_no, uint8_t com memcpy (data + 1, &le_ar, sizeof (le_ar)); iso14443a_crc (data, 3, data+3); bzero (data + 5, 3); - mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, data, 8, MD_SEND, 0); + mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, MIFARE_DESFIRE (tag)->ivect, data, 8, MD_SEND, 0); BUFFER_APPEND_BYTES (cmd, data, 8); diff --git a/libfreefare/mifare_desfire_authenticate.c b/libfreefare/mifare_desfire_authenticate.c index ce98516..a731ce6 100644 --- a/libfreefare/mifare_desfire_authenticate.c +++ b/libfreefare/mifare_desfire_authenticate.c @@ -120,7 +120,7 @@ mifare_cryto_preprocess_data (MifareTag tag, void *data, size_t *nbytes, int com // ... and 0 padding bzero ((uint8_t *)res + *nbytes, edl - *nbytes); - mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, res, edl, MD_SEND, 1); + mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, MIFARE_DESFIRE (tag)->ivect, res, edl, MD_SEND, 1); memcpy (mac, (uint8_t *)res + edl - 8, 4); @@ -148,7 +148,7 @@ mifare_cryto_preprocess_data (MifareTag tag, void *data, size_t *nbytes, int com *nbytes = edl; - mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, res, *nbytes, MD_SEND, 0); + mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, MIFARE_DESFIRE (tag)->ivect, res, *nbytes, MD_SEND, 0); break; default: @@ -179,9 +179,9 @@ mifare_cryto_postprocess_data (MifareTag tag, void *data, ssize_t *nbytes, int c memcpy (edata, data, *nbytes); bzero ((uint8_t *)edata + *nbytes, edl - *nbytes); - mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, edata, edl, MD_SEND, 1); - /* ,^^^^^^^ - * No! This is not a typo! ---------------------------------' + mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, MIFARE_DESFIRE (tag)->ivect, edata, edl, MD_SEND, 1); + /* ,^^^^^^^ + * No! This is not a typo! --------------------------------------------------------------' */ if (0 != memcmp ((uint8_t *)data + *nbytes, (uint8_t *)edata + edl - 8, 4)) { @@ -194,7 +194,7 @@ mifare_cryto_postprocess_data (MifareTag tag, void *data, ssize_t *nbytes, int c break; case 3: - mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, res, *nbytes, MD_RECEIVE, 0); + mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, MIFARE_DESFIRE (tag)->ivect, res, *nbytes, MD_RECEIVE, 0); /* * Look for the CRC and ensure it is following by NULL padding. We @@ -283,12 +283,15 @@ mifare_des (MifareDESFireKey key, uint8_t *data, uint8_t *ivect, MifareDirection } void -mifare_cbc_des (MifareDESFireKey key, 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, int mac) { - size_t offset = 0; - uint8_t ivect[8]; - bzero (ivect, sizeof (ivect)); + switch (key->type) { + case T_DES: + case T_3DES: + bzero (ivect, 8); + } + size_t offset = 0; while (offset < data_size) { mifare_des (key, data + offset, ivect, direction, mac); offset += 8; diff --git a/test/test_mifare_desfire_des.c b/test/test_mifare_desfire_des.c index dac47a8..ae355f1 100644 --- a/test/test_mifare_desfire_des.c +++ b/test/test_mifare_desfire_des.c @@ -21,6 +21,8 @@ #include #include "freefare_internal.h" +uint8_t null_ivect[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + void test_mifare_rol (void) { @@ -39,7 +41,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, data, 8, MD_RECEIVE, 0); + mifare_cbc_des (key, null_ivect, data, 8, MD_RECEIVE, 0); 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")); @@ -58,7 +60,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, data, 8, MD_SEND, 0); + mifare_cbc_des (key, null_ivect, data, 8, MD_SEND, 0); 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"));