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:
parent
87a04904bc
commit
356219e21b
4 changed files with 28 additions and 19 deletions
|
@ -116,7 +116,7 @@ typedef enum {
|
||||||
|
|
||||||
void *mifare_cryto_preprocess_data (MifareTag tag, void *data, size_t *nbytes, int communication_settings);
|
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_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 rol (uint8_t *data, const size_t len);
|
||||||
void *assert_crypto_buffer_size (MifareTag tag, size_t nbytes);
|
void *assert_crypto_buffer_size (MifareTag tag, size_t nbytes);
|
||||||
|
|
||||||
|
@ -183,6 +183,7 @@ struct mifare_desfire_tag {
|
||||||
char *last_pcd_error;
|
char *last_pcd_error;
|
||||||
MifareDESFireKey session_key;
|
MifareDESFireKey session_key;
|
||||||
uint8_t authenticated_key_no;
|
uint8_t authenticated_key_no;
|
||||||
|
uint8_t ivect[16];
|
||||||
uint8_t *crypto_buffer;
|
uint8_t *crypto_buffer;
|
||||||
size_t crypto_buffer_size;
|
size_t crypto_buffer_size;
|
||||||
uint8_t block_number;
|
uint8_t block_number;
|
||||||
|
|
|
@ -327,6 +327,8 @@ mifare_desfire_authenticate (MifareTag tag, uint8_t key_no, MifareDESFireKey key
|
||||||
ASSERT_ACTIVE (tag);
|
ASSERT_ACTIVE (tag);
|
||||||
ASSERT_MIFARE_DESFIRE (tag);
|
ASSERT_MIFARE_DESFIRE (tag);
|
||||||
|
|
||||||
|
bzero (MIFARE_DESFIRE (tag)->ivect, 16);
|
||||||
|
|
||||||
MIFARE_DESFIRE (tag)->last_picc_error = OPERATION_OK;
|
MIFARE_DESFIRE (tag)->last_picc_error = OPERATION_OK;
|
||||||
|
|
||||||
MIFARE_DESFIRE (tag)->authenticated_key_no = NOT_YET_AUTHENTICATED;
|
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];
|
uint8_t PICC_RndB[8];
|
||||||
memcpy (PICC_RndB, PICC_E_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];
|
uint8_t PCD_RndA[8];
|
||||||
DES_random_key ((DES_cblock*)&PCD_RndA);
|
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, PCD_RndA, 8);
|
||||||
memcpy (token+8, PCD_r_RndB, 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);
|
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];
|
uint8_t PICC_RndA_s[8];
|
||||||
memcpy (PICC_RndA_s, PICC_E_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];
|
uint8_t PCD_RndA_s[8];
|
||||||
memcpy (PCD_RndA_s, PCD_RndA, 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)->authenticated_key_no = key_no;
|
||||||
MIFARE_DESFIRE (tag)->session_key = mifare_desfire_session_key_new (PCD_RndA, PICC_RndB, key);
|
MIFARE_DESFIRE (tag)->session_key = mifare_desfire_session_key_new (PCD_RndA, PICC_RndB, key);
|
||||||
|
bzero (MIFARE_DESFIRE (tag)->ivect, 16);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -409,7 +412,7 @@ mifare_desfire_change_key_settings (MifareTag tag, uint8_t settings)
|
||||||
iso14443a_crc (data, 1, data + 1);
|
iso14443a_crc (data, 1, data + 1);
|
||||||
bzero (data+3, 5);
|
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);
|
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);
|
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));
|
memcpy (data + 1, &le_ar, sizeof (le_ar));
|
||||||
iso14443a_crc (data, 3, data+3);
|
iso14443a_crc (data, 3, data+3);
|
||||||
bzero (data + 5, 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);
|
BUFFER_APPEND_BYTES (cmd, data, 8);
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ mifare_cryto_preprocess_data (MifareTag tag, void *data, size_t *nbytes, int com
|
||||||
// ... and 0 padding
|
// ... and 0 padding
|
||||||
bzero ((uint8_t *)res + *nbytes, edl - *nbytes);
|
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);
|
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;
|
*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;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -179,9 +179,9 @@ mifare_cryto_postprocess_data (MifareTag tag, void *data, ssize_t *nbytes, int c
|
||||||
memcpy (edata, data, *nbytes);
|
memcpy (edata, data, *nbytes);
|
||||||
bzero ((uint8_t *)edata + *nbytes, edl - *nbytes);
|
bzero ((uint8_t *)edata + *nbytes, edl - *nbytes);
|
||||||
|
|
||||||
mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, edata, edl, MD_SEND, 1);
|
mifare_cbc_des (MIFARE_DESFIRE (tag)->session_key, MIFARE_DESFIRE (tag)->ivect, edata, edl, MD_SEND, 1);
|
||||||
/* ,^^^^^^^
|
/* ,^^^^^^^
|
||||||
* No! This is not a typo! ---------------------------------'
|
* No! This is not a typo! --------------------------------------------------------------'
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (0 != memcmp ((uint8_t *)data + *nbytes, (uint8_t *)edata + edl - 8, 4)) {
|
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;
|
break;
|
||||||
case 3:
|
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
|
* 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
|
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;
|
switch (key->type) {
|
||||||
uint8_t ivect[8];
|
case T_DES:
|
||||||
bzero (ivect, sizeof (ivect));
|
case T_3DES:
|
||||||
|
bzero (ivect, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t offset = 0;
|
||||||
while (offset < data_size) {
|
while (offset < data_size) {
|
||||||
mifare_des (key, data + offset, ivect, direction, mac);
|
mifare_des (key, data + offset, ivect, direction, mac);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include <freefare.h>
|
#include <freefare.h>
|
||||||
#include "freefare_internal.h"
|
#include "freefare_internal.h"
|
||||||
|
|
||||||
|
uint8_t null_ivect[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
void
|
void
|
||||||
test_mifare_rol (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_data[8] = { 0x73, 0x0d, 0xdf, 0xad, 0xa4, 0xd2, 0x07, 0x89 };
|
||||||
uint8_t expected_key[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
|
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_data, 8, &data, 8, cut_message ("Wrong data"));
|
||||||
cut_assert_equal_memory (&expected_key, 8, key->data, 8, cut_message ("Wrong key"));
|
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_data[8] = { 0xd6, 0x59, 0xe1, 0x70, 0x43, 0xa8, 0x40, 0x68 };
|
||||||
uint8_t expected_key[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
|
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_data, 8, &data, 8, cut_message ("Wrong data"));
|
||||||
cut_assert_equal_memory (&expected_key, 8, key->data, 8, cut_message ("Wrong key"));
|
cut_assert_equal_memory (&expected_key, 8, key->data, 8, cut_message ("Wrong key"));
|
||||||
|
|
Loading…
Add table
Reference in a new issue