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).
This commit is contained in:
Romain Tartiere 2010-10-29 12:22:47 +00:00
parent 87a04904bc
commit 356219e21b
4 changed files with 28 additions and 19 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -21,6 +21,8 @@
#include <freefare.h>
#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"));