Rework auth for client and device

This commit is contained in:
Bjoern Kerler 2020-04-12 17:39:11 +02:00
parent b0af460a6e
commit f76de40982
7 changed files with 1454 additions and 260 deletions

View file

@ -26,10 +26,10 @@ APP_CFLAGS = $(PLATFORM_DEFS) \
SRC_LF = lfops.c lfsampling.c pcf7931.c lfdemod.c lfadc.c SRC_LF = lfops.c lfsampling.c pcf7931.c lfdemod.c lfadc.c
SRC_ISO15693 = iso15693.c iso15693tools.c SRC_ISO15693 = iso15693.c iso15693tools.c
SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c
#UNUSED: mifaresniff.c desfire_crypto.c #UNUSED: mifaresniff.c
SRC_ISO14443b = iso14443b.c SRC_ISO14443b = iso14443b.c
SRC_FELICA = felica.c SRC_FELICA = felica.c
SRC_CRAPTO1 = crypto1.c des.c desfire_key.c mifaredesfire.c aes.c platform_util.c SRC_CRAPTO1 = crypto1.c des.c desfire_crypto.c mifaredesfire.c aes.c platform_util.c
SRC_CRC = crc.c crc16.c crc32.c SRC_CRC = crc.c crc16.c crc32.c
SRC_ICLASS = iclass.c optimized_cipher.c SRC_ICLASS = iclass.c optimized_cipher.c
SRC_LEGIC = legicrf.c legicrfsim.c legic_prng.c SRC_LEGIC = legicrf.c legicrfsim.c legic_prng.c

1256
armsrc/desfire_crypto.c Normal file

File diff suppressed because it is too large Load diff

139
armsrc/desfire_crypto.h Normal file
View file

@ -0,0 +1,139 @@
#ifndef __DESFIRE_CRYPTO_H
#define __DESFIRE_CRYPTO_H
#include "common.h"
#include "mifare.h" // structs
//#include "../../armsrc/printf.h"
//#include "../../armsrc/desfire.h"
//#include "../../armsrc/iso14443a.h"
#define MAX_CRYPTO_BLOCK_SIZE 16
/* Mifare DESFire EV1 Application crypto operations */
#define APPLICATION_CRYPTO_DES 0x00
#define APPLICATION_CRYPTO_3K3DES 0x40
#define APPLICATION_CRYPTO_AES 0x80
#define MAC_LENGTH 4
#define CMAC_LENGTH 8
typedef enum {
MCD_SEND,
MCD_RECEIVE
} MifareCryptoDirection;
typedef enum {
MCO_ENCYPHER,
MCO_DECYPHER
} MifareCryptoOperation;
#define MDCM_MASK 0x000F
#define CMAC_NONE 0
// Data send to the PICC is used to update the CMAC
#define CMAC_COMMAND 0x010
// Data received from the PICC is used to update the CMAC
#define CMAC_VERIFY 0x020
// MAC the command (when MDCM_MACED)
#define MAC_COMMAND 0x100
// The command returns a MAC to verify (when MDCM_MACED)
#define MAC_VERIFY 0x200
#define ENC_COMMAND 0x1000
#define NO_CRC 0x2000
#define MAC_MASK 0x0F0
#define CMAC_MACK 0xF00
/* Communication mode */
#define MDCM_PLAIN 0x00
#define MDCM_MACED 0x01
#define MDCM_ENCIPHERED 0x03
/* Error code managed by the library */
#define CRYPTO_ERROR 0x01
enum DESFIRE_CRYPTOALGO {
T_DES = 0x00,
T_3DES = 0x01, //aka 2K3DES
T_3K3DES = 0x02,
T_AES = 0x03
};
enum DESFIRE_AUTH_SCHEME {
AS_LEGACY,
AS_NEW
};
#define DESFIRE_KEY(key) ((struct desfire_key *) key)
struct desfire_key {
enum DESFIRE_CRYPTOALGO type;
uint8_t data[24];
uint8_t cmac_sk1[24];
uint8_t cmac_sk2[24];
uint8_t aes_version;
};
typedef struct desfire_key *desfirekey_t;
#define DESFIRE(tag) ((struct desfire_tag *) tag)
struct desfire_tag {
iso14a_card_select_t info;
int active;
uint8_t last_picc_error;
uint8_t last_internal_error;
uint8_t last_pcd_error;
desfirekey_t session_key;
enum DESFIRE_AUTH_SCHEME authentication_scheme;
uint8_t authenticated_key_no;
uint8_t ivect[MAX_CRYPTO_BLOCK_SIZE];
uint8_t cmac[16];
uint8_t *crypto_buffer;
size_t crypto_buffer_size;
uint32_t selected_application;
};
typedef struct desfire_tag *desfiretag_t;
typedef unsigned long DES_KS[16][2]; /* Single-key DES key schedule */
typedef unsigned long DES3_KS[48][2]; /* Triple-DES key schedule */
extern int Asmversion; /* 1 if we're linked with an asm version, 0 if C */
void crc32_ex(const uint8_t *data, const size_t len, uint8_t *crc);
void crc32_append(uint8_t *data, const size_t len);
void des_enc(void *out, const void *in, const void *key);
void des_dec(void *out, const void *in, const void *key);
void tdes_enc(void *out, void *in, const void *key);
void tdes_dec(void *out, void *in, const uint8_t *key);
void tdes_nxp_receive(const void *in, void *out, size_t length, const void *key, unsigned char iv[8], int keymode);
void tdes_nxp_send(const void *in, void *out, size_t length, const void *key, unsigned char iv[8], int keymode);
void Desfire_des_key_new(const uint8_t value[8], desfirekey_t key);
void Desfire_3des_key_new(const uint8_t value[16], desfirekey_t key);
void Desfire_des_key_new_with_version(const uint8_t value[8], desfirekey_t key);
void Desfire_3des_key_new_with_version(const uint8_t value[16], desfirekey_t key);
void Desfire_3k3des_key_new(const uint8_t value[24], desfirekey_t key);
void Desfire_3k3des_key_new_with_version(const uint8_t value[24], desfirekey_t key);
void Desfire_2k3des_key_new_with_version(const uint8_t value[16], desfirekey_t key);
void Desfire_aes_key_new(const uint8_t value[16], desfirekey_t key);
void Desfire_aes_key_new_with_version(const uint8_t value[16], uint8_t version, desfirekey_t key);
uint8_t Desfire_key_get_version(desfirekey_t key);
void Desfire_key_set_version(desfirekey_t key, uint8_t version);
void Desfire_session_key_new(const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key);
void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes, size_t offset, int communication_settings);
void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes, int communication_settings);
void mifare_cypher_single_block(desfirekey_t key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size);
void mifare_cypher_blocks_chained(desfiretag_t tag, desfirekey_t key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation);
size_t key_block_size(const desfirekey_t key);
size_t padded_data_length(const size_t nbytes, const size_t block_size);
size_t maced_data_length(const desfirekey_t key, const size_t nbytes);
size_t enciphered_data_length(const desfiretag_t tag, const size_t nbytes, int communication_settings);
void cmac_generate_subkeys(desfirekey_t key);
void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac);
#endif

View file

@ -1,172 +0,0 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
* $Id$
*/
#include "desfire_key.h"
#include "string.h"
#include "dbprint.h"
static inline void update_key_schedules(desfirekey_t key);
static inline void update_key_schedules(desfirekey_t key) {
// DES_set_key ((DES_cblock *)key->data, &(key->ks1));
// DES_set_key ((DES_cblock *)(key->data + 8), &(key->ks2));
// if (T_3K3DES == key->type) {
// DES_set_key ((DES_cblock *)(key->data + 16), &(key->ks3));
// }
}
void Desfire_des_key_new(const uint8_t value[8], desfirekey_t key) {
uint8_t data[8];
memcpy(data, value, 8);
for (int n = 0; n < 8; n++)
data[n] &= 0xfe;
Desfire_des_key_new_with_version(data, key);
}
void Desfire_des_key_new_with_version(const uint8_t value[8], desfirekey_t key) {
if (key != NULL) {
key->type = T_DES;
memcpy(key->data, value, 8);
memcpy(key->data + 8, value, 8);
update_key_schedules(key);
}
}
void Desfire_3des_key_new(const uint8_t value[16], desfirekey_t key) {
uint8_t data[16];
memcpy(data, value, 16);
for (int n = 0; n < 8; n++)
data[n] &= 0xfe;
for (int n = 8; n < 16; n++)
data[n] |= 0x01;
Desfire_3des_key_new_with_version(data, key);
}
void Desfire_3des_key_new_with_version(const uint8_t value[16], desfirekey_t key) {
if (key != NULL) {
key->type = T_3DES;
memcpy(key->data, value, 16);
memcpy(key->data + 16, value, 8);
update_key_schedules(key);
}
}
void Desfire_3k3des_key_new(const uint8_t value[24], desfirekey_t key) {
uint8_t data[24];
memcpy(data, value, 24);
for (int n = 0; n < 8; n++)
data[n] &= 0xfe;
Desfire_3k3des_key_new_with_version(data, key);
}
void Desfire_2k3des_key_new_with_version(const uint8_t value[16], desfirekey_t key) {
if (key != NULL) {
key->type = T_2K3DES;
memcpy(key->data, value, 16);
update_key_schedules(key);
}
}
void Desfire_3k3des_key_new_with_version(const uint8_t value[24], desfirekey_t key) {
if (key != NULL) {
key->type = T_3K3DES;
memcpy(key->data, value, 24);
update_key_schedules(key);
}
}
void Desfire_aes_key_new(const uint8_t value[16], desfirekey_t key) {
Desfire_aes_key_new_with_version(value, 0, key);
}
void Desfire_aes_key_new_with_version(const uint8_t value[16], uint8_t version, desfirekey_t key) {
if (key != NULL) {
memcpy(key->data, value, 16);
key->type = T_AES;
key->aes_version = version;
}
}
uint8_t Desfire_key_get_version(desfirekey_t key) {
uint8_t version = 0;
for (int n = 0; n < 8; n++) {
version |= ((key->data[n] & 1) << (7 - n));
}
return version;
}
void Desfire_key_set_version(desfirekey_t key, uint8_t version) {
for (int n = 0; n < 8; n++) {
uint8_t version_bit = ((version & (1 << (7 - n))) >> (7 - n));
key->data[n] &= 0xfe;
key->data[n] |= version_bit;
if (key->type == T_DES) {
key->data[n + 8] = key->data[n];
} else {
// Write ~version to avoid turning a 3DES key into a DES key
key->data[n + 8] &= 0xfe;
key->data[n + 8] |= ~version_bit;
}
}
}
void Desfire_session_key_new(const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key) {
uint8_t buffer[24];
switch (authkey->type) {
case T_DES:
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
Desfire_des_key_new_with_version(buffer, key);
break;
case T_3DES:
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
memcpy(buffer + 8, rnda + 4, 4);
memcpy(buffer + 12, rndb + 4, 4);
Desfire_3des_key_new_with_version(buffer, key);
break;
case T_2K3DES:
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
memcpy(buffer + 8, rnda + 4, 4);
memcpy(buffer + 12, rndb + 4, 4);
Desfire_2k3des_key_new_with_version(buffer, key);
break;
case T_3K3DES:
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
memcpy(buffer + 8, rnda + 6, 4);
memcpy(buffer + 12, rndb + 6, 4);
memcpy(buffer + 16, rnda + 12, 4);
memcpy(buffer + 20, rndb + 12, 4);
Desfire_3k3des_key_new(buffer, key);
break;
case T_AES:
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
memcpy(buffer + 8, rnda + 12, 4);
memcpy(buffer + 12, rndb + 12, 4);
Desfire_aes_key_new(buffer, key);
break;
}
}

View file

@ -1,19 +0,0 @@
#ifndef __DESFIRE_KEY_INCLUDED
#define __DESFIRE_KEY_INCLUDED
#include "common.h"
#include "desfire.h"
void Desfire_des_key_new(const uint8_t value[8], desfirekey_t key);
void Desfire_3des_key_new(const uint8_t value[16], desfirekey_t key);
void Desfire_des_key_new_with_version(const uint8_t value[8], desfirekey_t key);
void Desfire_3des_key_new_with_version(const uint8_t value[16], desfirekey_t key);
void Desfire_3k3des_key_new(const uint8_t value[24], desfirekey_t key);
void Desfire_3k3des_key_new_with_version(const uint8_t value[24], desfirekey_t key);
void Desfire_2k3des_key_new_with_version(const uint8_t value[16], desfirekey_t key);
void Desfire_aes_key_new(const uint8_t value[16], desfirekey_t key);
void Desfire_aes_key_new_with_version(const uint8_t value[16], uint8_t version, desfirekey_t key);
uint8_t Desfire_key_get_version(desfirekey_t key);
void Desfire_key_set_version(desfirekey_t key, uint8_t version);
void Desfire_session_key_new(const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key);
#endif

View file

@ -4,9 +4,8 @@
#include "proxmark3_arm.h" #include "proxmark3_arm.h"
#include "string.h" #include "string.h"
#include "BigBuf.h" #include "BigBuf.h"
#include "desfire_key.h"
#include "mifareutil.h" #include "mifareutil.h"
#include "des.h" #include "desfire_crypto.h"
#include "cmd.h" #include "cmd.h"
#include "dbprint.h" #include "dbprint.h"
#include "fpgaloader.h" #include "fpgaloader.h"
@ -34,6 +33,8 @@ static uint8_t deselect_cmd[] = {0xc2, 0xe0, 0xb4};
/* PCB CID CMD PAYLOAD */ /* PCB CID CMD PAYLOAD */
//static uint8_t __res[MAX_FRAME_SIZE]; //static uint8_t __res[MAX_FRAME_SIZE];
struct desfire_key defaultkey = {0};
static desfirekey_t sessionkey = &defaultkey;
bool InitDesfireCard() { bool InitDesfireCard() {
@ -250,9 +251,11 @@ void MifareDES_Auth1(uint8_t *datain) {
num_to_bytes(value, 4, &RndA[12]); num_to_bytes(value, 4, &RndA[12]);
// Default Keys // Default Keys
uint8_t PICC_MASTER_KEY8[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t PICC_MASTER_KEY8[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t PICC_MASTER_KEY16[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t PICC_MASTER_KEY16[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
uint8_t PICC_MASTER_KEY24[24] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 0x00, 0x00};
uint8_t PICC_MASTER_KEY24[24] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
//uint8_t null_key_data16[16] = {0x00}; //uint8_t null_key_data16[16] = {0x00};
//uint8_t new_key_data8[8] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77}; //uint8_t new_key_data8[8] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
//uint8_t new_key_data16[16] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF}; //uint8_t new_key_data16[16] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};
@ -266,9 +269,10 @@ void MifareDES_Auth1(uint8_t *datain) {
LED_C_OFF(); LED_C_OFF();
if (payload->key == NULL) { if (payload->key == NULL) {
if (payload->algo == MFDES_AUTH_DES) { if (payload->algo == MFDES_AUTH_DES) {
memcpy(keybytes, PICC_MASTER_KEY8, 8); memcpy(keybytes, PICC_MASTER_KEY8, 8);
} else if (payload->algo == MFDES_ALGO_AES || payload->algo == MFDES_ALGO_3DES || payload->algo == MFDES_ALGO_2K3DES) { } else if (payload->algo == MFDES_ALGO_AES || payload->algo == MFDES_ALGO_3DES ||
payload->algo == MFDES_ALGO_2K3DES) {
memcpy(keybytes, PICC_MASTER_KEY16, 16); memcpy(keybytes, PICC_MASTER_KEY16, 16);
} else if (payload->algo == MFDES_ALGO_3DES) { } else if (payload->algo == MFDES_ALGO_3DES) {
memcpy(keybytes, PICC_MASTER_KEY24, 24); memcpy(keybytes, PICC_MASTER_KEY24, 24);
@ -287,8 +291,6 @@ void MifareDES_Auth1(uint8_t *datain) {
Desfire_3des_key_new_with_version(keybytes, key); Desfire_3des_key_new_with_version(keybytes, key);
} else if (payload->algo == MFDES_ALGO_DES) { } else if (payload->algo == MFDES_ALGO_DES) {
Desfire_des_key_new(keybytes, key); Desfire_des_key_new(keybytes, key);
} else if (payload->algo == MFDES_ALGO_2K3DES) {
Desfire_2k3des_key_new_with_version(keybytes, key);
} else if (payload->algo == MFDES_ALGO_3K3DES) { } else if (payload->algo == MFDES_ALGO_3K3DES) {
Desfire_3k3des_key_new_with_version(keybytes, key); Desfire_3k3des_key_new_with_version(keybytes, key);
} }
@ -324,7 +326,7 @@ void MifareDES_Auth1(uint8_t *datain) {
return; return;
} }
if (resp[2] == (uint8_t)0xaf) { if (resp[2] == (uint8_t)MFDES_ADDITIONAL_FRAME) {
DbpString("Authentication failed. Invalid key number."); DbpString("Authentication failed. Invalid key number.");
OnErrorNG(CMD_HF_DESFIRE_AUTH1, 3); OnErrorNG(CMD_HF_DESFIRE_AUTH1, 3);
return; return;
@ -335,6 +337,8 @@ void MifareDES_Auth1(uint8_t *datain) {
expectedlen = 1 + 16 + 2 + 2; expectedlen = 1 + 16 + 2 + 2;
} }
int rndlen = recv_len - 1 - 2 - 2;
if (len != expectedlen) { if (len != expectedlen) {
if (DBGLEVEL >= DBG_ERROR) { if (DBGLEVEL >= DBG_ERROR) {
DbpString("Authentication failed. Length of answer doesn't match algo."); DbpString("Authentication failed. Length of answer doesn't match algo.");
@ -346,9 +350,9 @@ void MifareDES_Auth1(uint8_t *datain) {
// Part 2 // Part 2
if (payload->mode != MFDES_AUTH_PICC) { if (payload->mode != MFDES_AUTH_PICC) {
memcpy(encRndB, resp + 1, payload->keylen); memcpy(encRndB, resp + 1, rndlen);
} else { } else {
memcpy(encRndB, resp + 2, payload->keylen); memcpy(encRndB, resp + 2, rndlen);
} }
// Part 3 // Part 3
@ -361,60 +365,47 @@ void MifareDES_Auth1(uint8_t *datain) {
return; return;
} }
mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, 16, IV, encRndB, RndB); mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, 16, IV, encRndB, RndB);
} else if (payload->algo == MFDES_ALGO_3DES) } else if (payload->algo == MFDES_ALGO_DES)
tdes_dec(RndB, encRndB, key->data);
else if (payload->algo == MFDES_ALGO_DES)
des_dec(RndB, encRndB, key->data); des_dec(RndB, encRndB, key->data);
else if (payload->algo == MFDES_ALGO_2K3DES) else if (payload->algo == MFDES_ALGO_3DES)
tdes_2key_dec(RndB, encRndB, 8, key->data, IV); tdes_nxp_receive(encRndB, RndB, rndlen, key->data, IV, 2);
else if (payload->algo == MFDES_ALGO_3K3DES) else if (payload->algo == MFDES_ALGO_3K3DES)
tdes_3key_dec(RndB, encRndB, 16, key->data, IV); tdes_nxp_receive(encRndB, RndB, rndlen, key->data, IV, 3);
// - Rotate RndB by 8 bits // - Rotate RndB by 8 bits
memcpy(rotRndB, RndB, payload->keylen); memcpy(rotRndB, RndB, rndlen);
rol(rotRndB, payload->keylen); rol(rotRndB, rndlen);
uint8_t encRndA[16] = {0x00}; uint8_t encRndA[16] = {0x00};
// - Encrypt our response // - Encrypt our response
if (payload->mode == MFDES_AUTH_DES || payload->mode == MFDES_AUTH_ISO || payload->mode == MFDES_AUTH_PICC) { if (payload->mode == MFDES_AUTH_DES || payload->mode == MFDES_AUTH_PICC) {
if (payload->algo == MFDES_ALGO_3DES) { des_dec(encRndA, RndA, key->data);
tdes_dec(encRndA, RndA, key->data); memcpy(both, encRndA, rndlen);
memcpy(both, encRndA, 8);
} else if (payload->algo == MFDES_ALGO_DES) {
des_dec(encRndA, RndA, key->data);
memcpy(both, encRndA, 8);
} else if (payload->algo == MFDES_ALGO_2K3DES) {
tdes_2key_dec(encRndA, RndA, 8, key->data, IV);
memcpy(both, encRndA, 8);
} else if (payload->algo == MFDES_ALGO_3K3DES) {
tdes_3key_dec(encRndA, RndA, 16, key->data, IV);
memcpy(both, encRndA, 16);
}
for (int x = 0; x < rndlen; x++) {
for (int x = 0; x < 8; x++) {
rotRndB[x] = rotRndB[x] ^ encRndA[x]; rotRndB[x] = rotRndB[x] ^ encRndA[x];
} }
des_dec(encRndB, rotRndB, key->data);
memcpy(both + 8, encRndB, rndlen);
}
else if (payload->mode == MFDES_AUTH_ISO) {
if (payload->algo == MFDES_ALGO_3DES) { if (payload->algo == MFDES_ALGO_3DES) {
tdes_dec(encRndB, rotRndB, key->data); uint8_t tmp[16] = {0x00};
memcpy(both + 8, encRndB, 8); memcpy(tmp, RndA, rndlen);
} else if (payload->algo == MFDES_ALGO_DES) { memcpy(tmp + rndlen, rotRndB, rndlen);
des_dec(encRndB, rotRndB, key->data); tdes_nxp_send(tmp, both, 16, key->data, IV,2);
memcpy(both + 8, encRndB, 8);
} else if (payload->algo == MFDES_ALGO_2K3DES) {
tdes_2key_dec(encRndB, rotRndB, 8, key->data, IV);
memcpy(both + 8, encRndB, 8);
} else if (payload->algo == MFDES_ALGO_3K3DES) { } else if (payload->algo == MFDES_ALGO_3K3DES) {
tdes_3key_dec(encRndB, rotRndB, 16, key->data, IV); uint8_t tmp[32] = {0x00};
memcpy(both + 16, encRndB, 16); memcpy(tmp, RndA, rndlen);
memcpy(tmp + rndlen, rotRndB, rndlen);
tdes_nxp_send(tmp, both, 32, key->data, IV,3);
} }
} else if (payload->mode == MFDES_AUTH_AES) { } else if (payload->mode == MFDES_AUTH_AES) {
uint8_t tmp[32] = {0x00}; uint8_t tmp[32] = {0x00};
memcpy(tmp, RndA, 16); memcpy(tmp, RndA, rndlen);
memcpy(tmp + 16, rotRndB, 16); memcpy(tmp + 16, rotRndB, rndlen);
if (payload->algo == MFDES_ALGO_AES) { if (payload->algo == MFDES_ALGO_AES) {
if (mbedtls_aes_setkey_enc(&ctx, key->data, 128) != 0) { if (mbedtls_aes_setkey_enc(&ctx, key->data, 128) != 0) {
if (DBGLEVEL >= DBG_EXTENDED) { if (DBGLEVEL >= DBG_EXTENDED) {
@ -442,8 +433,8 @@ void MifareDES_Auth1(uint8_t *datain) {
len = DesfireAPDU(cmd, 5 + bothlen + 1, resp); len = DesfireAPDU(cmd, 5 + bothlen + 1, resp);
} else { } else {
cmd[0] = ADDITIONAL_FRAME; cmd[0] = ADDITIONAL_FRAME;
memcpy(cmd + 1, both, 16); memcpy(cmd + 1, both, bothlen);
len = DesfireAPDU(cmd, 1 + 16, resp); len = DesfireAPDU(cmd, 1 + bothlen, resp);
} }
if (!len) { if (!len) {
@ -469,27 +460,25 @@ void MifareDES_Auth1(uint8_t *datain) {
} }
// Part 4 // Part 4
struct desfire_key sessionKey = {0};
desfirekey_t skey = &sessionKey; Desfire_session_key_new(RndA, RndB, key, sessionkey);
Desfire_session_key_new(RndA, RndB, key, skey);
if (DBGLEVEL >= DBG_EXTENDED) if (DBGLEVEL >= DBG_EXTENDED)
print_result("SESSIONKEY : ", sessionKey.data, payload->keylen); print_result("SESSIONKEY : ", sessionKey.data, payload->keylen);
if (payload->mode != MFDES_AUTH_PICC) { if (payload->mode != MFDES_AUTH_PICC) {
memcpy(encRndA, resp + 1, payload->keylen); memcpy(encRndA, resp + 1, rndlen);
} else { } else {
memcpy(encRndA, resp + 2, payload->keylen); memcpy(encRndA, resp + 2, rndlen);
} }
if (payload->mode == MFDES_AUTH_DES || payload->mode == MFDES_AUTH_PICC) { if (payload->mode == MFDES_AUTH_DES || payload->mode == MFDES_AUTH_PICC) {
if (payload->algo == MFDES_ALGO_3DES) if (payload->algo == MFDES_ALGO_DES)
tdes_dec(encRndA, encRndA, key->data);
else if (payload->algo == MFDES_ALGO_DES)
des_dec(encRndA, encRndA, key->data); des_dec(encRndA, encRndA, key->data);
else if (payload->algo == MFDES_ALGO_2K3DES) else if (payload->algo == MFDES_ALGO_3DES)
tdes_2key_dec(encRndA, encRndA, 8, key->data, IV); tdes_nxp_receive(encRndA, encRndA, rndlen, key->data, IV,2);
else if (payload->algo == MFDES_ALGO_3K3DES) else if (payload->algo == MFDES_ALGO_3K3DES)
tdes_3key_dec(encRndA, encRndA, 16, key->data, IV); tdes_nxp_receive(encRndA, encRndA, rndlen, key->data, IV,3);
} else if (payload->mode == MFDES_AUTH_AES) { } else if (payload->mode == MFDES_AUTH_AES) {
if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) { if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) {
if (DBGLEVEL >= DBG_EXTENDED) { if (DBGLEVEL >= DBG_EXTENDED) {
@ -501,13 +490,13 @@ void MifareDES_Auth1(uint8_t *datain) {
mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, 16, IV, encRndA, encRndA); mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, 16, IV, encRndA, encRndA);
} }
rol(RndA, payload->keylen); rol(RndA, rndlen);
if (DBGLEVEL >= DBG_EXTENDED) { if (DBGLEVEL >= DBG_EXTENDED) {
print_result("RndA : ", RndA, payload->keylen); print_result("RndA : ", RndA, rndlen);
print_result("RndB: ", RndB, payload->keylen); print_result("RndB: ", RndB, rndlen);
print_result("encRndA : ", encRndA, payload->keylen); print_result("encRndA : ", encRndA, rndlen);
} }
for (int x = 0; x < payload->keylen; x++) { for (int x = 0; x < rndlen; x++) {
if (RndA[x] != encRndA[x]) { if (RndA[x] != encRndA[x]) {
DbpString("Authentication failed. Cannot verify Session Key."); DbpString("Authentication failed. Cannot verify Session Key.");
OnErrorNG(CMD_HF_DESFIRE_AUTH1, 4); OnErrorNG(CMD_HF_DESFIRE_AUTH1, 4);

View file

@ -185,6 +185,7 @@ CMDSRCS = crapto1/crapto1.c \
mifare/mifare4.c \ mifare/mifare4.c \
mifare/mad.c \ mifare/mad.c \
mifare/ndef.c \ mifare/ndef.c \
mifare/desfire_crypto.c \
cmdanalyse.c \ cmdanalyse.c \
cmdhf.c \ cmdhf.c \
cmdhflist.c \ cmdhflist.c \