mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-09-20 23:36:31 +08:00
Rework auth for client and device
This commit is contained in:
parent
b0af460a6e
commit
f76de40982
|
@ -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
1256
armsrc/desfire_crypto.c
Normal file
File diff suppressed because it is too large
Load diff
139
armsrc/desfire_crypto.h
Normal file
139
armsrc/desfire_crypto.h
Normal 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
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
Loading…
Reference in a new issue