mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 13:53:55 -07:00
style
This commit is contained in:
parent
560f0f106b
commit
c32ef83812
1 changed files with 184 additions and 192 deletions
|
@ -55,41 +55,41 @@ typedef struct {
|
||||||
keyset_t keys[] = {
|
keyset_t keys[] = {
|
||||||
{
|
{
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Nonce
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Nonce
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // privEncKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // privEncKey
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // privMacKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // privMacKey
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // readKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // readKey
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // writeKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // writeKey
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } // adminKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // adminKey
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Nonce
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Nonce
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // privEncKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // privEncKey
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // privMacKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // privMacKey
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // readKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // readKey
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // writeKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // writeKey
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } // adminKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // adminKey
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Nonce
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Nonce
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // privEncKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // privEncKey
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // privMacKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // privMacKey
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // readKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // readKey
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // writeKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // writeKey
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } // adminKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // adminKey
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Nonce
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Nonce
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // privEncKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // privEncKey
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // privMacKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // privMacKey
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // readKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // readKey
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // writeKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // writeKey
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } // adminKey
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // adminKey
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const int value;
|
const int value;
|
||||||
const char* name;
|
const char *name;
|
||||||
} known_algo_t;
|
} known_algo_t;
|
||||||
|
|
||||||
static const known_algo_t known_algorithm_map[] = {
|
static const known_algo_t known_algorithm_map[] = {
|
||||||
|
@ -111,18 +111,17 @@ static const sioMediaTypeName_t sioMediaTypeMapping[] = {
|
||||||
{ 0xFF, "INVALID VALUE"}
|
{ 0xFF, "INVALID VALUE"}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int create_cmac (uint8_t* key, uint8_t* input, uint8_t* out, int input_len, int encryption_algorithm) {
|
static int create_cmac(uint8_t *key, uint8_t *input, uint8_t *out, int input_len, int encryption_algorithm) {
|
||||||
uint8_t iv[16] = {0x00};
|
uint8_t iv[16] = {0x00};
|
||||||
|
|
||||||
if (encryption_algorithm == 0x09) {
|
if (encryption_algorithm == 0x09) {
|
||||||
// Working as expected
|
// Working as expected
|
||||||
aes_cmac(iv, key, input, out, input_len);
|
aes_cmac(iv, key, input, out, input_len);
|
||||||
}
|
} else if (encryption_algorithm == 0x02) {
|
||||||
else if (encryption_algorithm == 0x02) {
|
|
||||||
// CMAC Requires a 24 byte key, but the 2k3DES uses the 1st part for the 3rd part of the key
|
// CMAC Requires a 24 byte key, but the 2k3DES uses the 1st part for the 3rd part of the key
|
||||||
memcpy(&key[16], &key[0], 8);
|
memcpy(&key[16], &key[0], 8);
|
||||||
|
|
||||||
const mbedtls_cipher_info_t* ctx;
|
const mbedtls_cipher_info_t *ctx;
|
||||||
ctx = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_DES_EDE3_ECB);
|
ctx = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_DES_EDE3_ECB);
|
||||||
mbedtls_cipher_cmac(ctx, key, 192, input, input_len, out);
|
mbedtls_cipher_cmac(ctx, key, 192, input, input_len, out);
|
||||||
} else {
|
} else {
|
||||||
|
@ -132,7 +131,7 @@ static int create_cmac (uint8_t* key, uint8_t* input, uint8_t* out, int input_le
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int create_cryptogram (uint8_t* key, uint8_t* input, uint8_t* out, int input_len, int encryption_algorithm) {
|
static int create_cryptogram(uint8_t *key, uint8_t *input, uint8_t *out, int input_len, int encryption_algorithm) {
|
||||||
uint8_t iv[16] = {};
|
uint8_t iv[16] = {};
|
||||||
|
|
||||||
if (encryption_algorithm == 0x09) {
|
if (encryption_algorithm == 0x09) {
|
||||||
|
@ -150,7 +149,7 @@ static int create_cryptogram (uint8_t* key, uint8_t* input, uint8_t* out, int in
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decrypt_cryptogram (uint8_t* key, uint8_t* input, uint8_t* out, int input_len, int encryption_algorithm) {
|
static int decrypt_cryptogram(uint8_t *key, uint8_t *input, uint8_t *out, int input_len, int encryption_algorithm) {
|
||||||
uint8_t iv[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
uint8_t iv[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
if (encryption_algorithm == 0x09) {
|
if (encryption_algorithm == 0x09) {
|
||||||
|
@ -168,34 +167,32 @@ static int decrypt_cryptogram (uint8_t* key, uint8_t* input, uint8_t* out, int i
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void increment_command_wrapper(uint8_t* input, int input_len) {
|
static void increment_command_wrapper(uint8_t *input, int input_len) {
|
||||||
input[input_len-1]++; // Increment the last element of the header by 1
|
input[input_len - 1]++; // Increment the last element of the header by 1
|
||||||
}
|
}
|
||||||
|
|
||||||
static void padToBlockSize(const uint8_t* input, int inputSize, int blockSize, uint8_t* output) {
|
static void padToBlockSize(const uint8_t *input, int inputSize, int blockSize, uint8_t *output) {
|
||||||
int paddingSize = blockSize - (inputSize % blockSize);
|
int paddingSize = blockSize - (inputSize % blockSize);
|
||||||
memcpy(output, input, inputSize);
|
memcpy(output, input, inputSize);
|
||||||
memset(output + inputSize, 0x80, 1);
|
memset(output + inputSize, 0x80, 1);
|
||||||
memset(output + inputSize + 1, 0x00, paddingSize - 1);
|
memset(output + inputSize + 1, 0x00, paddingSize - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void generate_command_wrapping(uint8_t *command_Header, int command_header_len, uint8_t *unencrypted_Command, int unencrypted_command_len ,uint8_t *rndICC, uint8_t *rndIFD, uint8_t *diversified_enc_key, uint8_t *diversified_mac_key, int encryption_algorithm, uint8_t *command, int *command_len) {
|
static void generate_command_wrapping(uint8_t *command_Header, int command_header_len, uint8_t *unencrypted_Command, int unencrypted_command_len, uint8_t *rndICC, uint8_t *rndIFD, uint8_t *diversified_enc_key, uint8_t *diversified_mac_key, int encryption_algorithm, uint8_t *command, int *command_len) {
|
||||||
int block_size = 0;
|
int block_size = 0;
|
||||||
|
|
||||||
if (encryption_algorithm == 0x02) {
|
if (encryption_algorithm == 0x02) {
|
||||||
block_size = 8;
|
block_size = 8;
|
||||||
}
|
} else if (encryption_algorithm == 0x09) {
|
||||||
else if (encryption_algorithm == 0x09) {
|
|
||||||
block_size = 16;
|
block_size = 16;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
PrintAndLogEx(ERR, _RED_("Unknown Encryption Algorithm"));
|
PrintAndLogEx(ERR, _RED_("Unknown Encryption Algorithm"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t rndCounter[block_size];
|
uint8_t rndCounter[block_size];
|
||||||
memcpy (rndCounter, rndICC, block_size / 2);
|
memcpy(rndCounter, rndICC, block_size / 2);
|
||||||
memcpy (rndCounter + block_size / 2, rndIFD, block_size/2);
|
memcpy(rndCounter + block_size / 2, rndIFD, block_size / 2);
|
||||||
increment_command_wrapper(rndCounter, block_size);
|
increment_command_wrapper(rndCounter, block_size);
|
||||||
|
|
||||||
// Command Header is for the APDU Command to be sent
|
// Command Header is for the APDU Command to be sent
|
||||||
|
@ -209,9 +206,9 @@ static void generate_command_wrapping(uint8_t *command_Header, int command_heade
|
||||||
uint8_t padded_encrypted_Command[block_size];
|
uint8_t padded_encrypted_Command[block_size];
|
||||||
create_cryptogram(diversified_enc_key, padded_unencrypted_Command, padded_encrypted_Command, sizeof(padded_unencrypted_Command), encryption_algorithm);
|
create_cryptogram(diversified_enc_key, padded_unencrypted_Command, padded_encrypted_Command, sizeof(padded_unencrypted_Command), encryption_algorithm);
|
||||||
|
|
||||||
uint8_t asn1_tag_cryptograph[2] = {0x85,ARRAYLEN(padded_encrypted_Command)};
|
uint8_t asn1_tag_cryptograph[2] = {0x85, ARRAYLEN(padded_encrypted_Command)};
|
||||||
uint8_t asn1_tag_mac[2] = {0x8e,0x08};
|
uint8_t asn1_tag_mac[2] = {0x8e, 0x08};
|
||||||
uint8_t command_trailer[2] = {0x97,0x00};
|
uint8_t command_trailer[2] = {0x97, 0x00};
|
||||||
uint8_t padded_command_trailer[block_size - ARRAYLEN(command_trailer)];
|
uint8_t padded_command_trailer[block_size - ARRAYLEN(command_trailer)];
|
||||||
padToBlockSize(command_trailer, sizeof(command_trailer), block_size, padded_command_trailer);
|
padToBlockSize(command_trailer, sizeof(command_trailer), block_size, padded_command_trailer);
|
||||||
|
|
||||||
|
@ -236,10 +233,10 @@ static void generate_command_wrapping(uint8_t *command_Header, int command_heade
|
||||||
// PrintAndLogEx(SUCCESS, "toEncrypt........................ " _YELLOW_("%s"), sprint_hex_inrow(toEncrypt,sizeof(toEncrypt)));
|
// PrintAndLogEx(SUCCESS, "toEncrypt........................ " _YELLOW_("%s"), sprint_hex_inrow(toEncrypt,sizeof(toEncrypt)));
|
||||||
// PrintAndLogEx(SUCCESS, "MAC.............................. " _YELLOW_("%s"), sprint_hex_inrow(mac,sizeof(mac)));
|
// PrintAndLogEx(SUCCESS, "MAC.............................. " _YELLOW_("%s"), sprint_hex_inrow(mac,sizeof(mac)));
|
||||||
|
|
||||||
uint8_t sizeofcommand[1] = {ARRAYLEN(asn1_tag_cryptograph) + ARRAYLEN(padded_encrypted_Command) + ARRAYLEN(command_trailer) + ARRAYLEN(asn1_tag_mac)+ ARRAYLEN(mac)};
|
uint8_t sizeofcommand[1] = {ARRAYLEN(asn1_tag_cryptograph) + ARRAYLEN(padded_encrypted_Command) + ARRAYLEN(command_trailer) + ARRAYLEN(asn1_tag_mac) + ARRAYLEN(mac)};
|
||||||
uint8_t respondTo[1] = {0x00};
|
uint8_t respondTo[1] = {0x00};
|
||||||
|
|
||||||
uint8_t completedCommand[command_header_len + 1 + ARRAYLEN(asn1_tag_cryptograph) + ARRAYLEN(padded_encrypted_Command) + ARRAYLEN(command_trailer) + ARRAYLEN(asn1_tag_mac)+ ARRAYLEN(mac) + 1];
|
uint8_t completedCommand[command_header_len + 1 + ARRAYLEN(asn1_tag_cryptograph) + ARRAYLEN(padded_encrypted_Command) + ARRAYLEN(command_trailer) + ARRAYLEN(asn1_tag_mac) + ARRAYLEN(mac) + 1];
|
||||||
memcpy(completedCommand, command_Header, command_header_len);
|
memcpy(completedCommand, command_Header, command_header_len);
|
||||||
memcpy(completedCommand + command_header_len, sizeofcommand, ARRAYLEN(sizeofcommand));
|
memcpy(completedCommand + command_header_len, sizeofcommand, ARRAYLEN(sizeofcommand));
|
||||||
memcpy(completedCommand + command_header_len + ARRAYLEN(sizeofcommand), asn1_tag_cryptograph, ARRAYLEN(asn1_tag_cryptograph));
|
memcpy(completedCommand + command_header_len + ARRAYLEN(sizeofcommand), asn1_tag_cryptograph, ARRAYLEN(asn1_tag_cryptograph));
|
||||||
|
@ -259,7 +256,7 @@ static void generate_command_wrapping(uint8_t *command_Header, int command_heade
|
||||||
//return;
|
//return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int seos_get_data(uint8_t *rndICC, uint8_t *rndIFD, uint8_t *diversified_enc_key, uint8_t *diversified_mac_key, uint8_t *sioOutput, int* sio_size, int encryption_algorithm, uint8_t* get_data_tlv, int get_data_tlv_len) {
|
static int seos_get_data(uint8_t *rndICC, uint8_t *rndIFD, uint8_t *diversified_enc_key, uint8_t *diversified_mac_key, uint8_t *sioOutput, int *sio_size, int encryption_algorithm, uint8_t *get_data_tlv, int get_data_tlv_len) {
|
||||||
// Intergrating our command generation with the GetData request to make my life easier in the future
|
// Intergrating our command generation with the GetData request to make my life easier in the future
|
||||||
|
|
||||||
// Command Header is for the Get Data Command using
|
// Command Header is for the Get Data Command using
|
||||||
|
@ -338,7 +335,7 @@ static int seos_get_data(uint8_t *rndICC, uint8_t *rndIFD, uint8_t *diversified_
|
||||||
|
|
||||||
uint8_t cryptogram[64];
|
uint8_t cryptogram[64];
|
||||||
uint8_t responseCode[2];
|
uint8_t responseCode[2];
|
||||||
uint8_t tag[2] = {0x00,0x00};
|
uint8_t tag[2] = {0x00, 0x00};
|
||||||
int getDataSize = 0;
|
int getDataSize = 0;
|
||||||
|
|
||||||
// ------------------- Cryptogram Response -------------------
|
// ------------------- Cryptogram Response -------------------
|
||||||
|
@ -368,8 +365,7 @@ static int seos_get_data(uint8_t *rndICC, uint8_t *rndIFD, uint8_t *diversified_
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "Response Code.................... " _YELLOW_("%s"), sprint_hex_inrow(responseCode, (ARRAYLEN(responseCode))));
|
PrintAndLogEx(SUCCESS, "Response Code.................... " _YELLOW_("%s"), sprint_hex_inrow(responseCode, (ARRAYLEN(responseCode))));
|
||||||
PrintAndLogEx(SUCCESS, "Output........................... " _YELLOW_("%s"), sprint_hex_inrow(sioOutput, getDataSize));
|
PrintAndLogEx(SUCCESS, "Output........................... " _YELLOW_("%s"), sprint_hex_inrow(sioOutput, getDataSize));
|
||||||
}
|
} else if (resplen >= 2 && response[0] == 0x99) {
|
||||||
else if (resplen >= 2 && response[0] == 0x99) {
|
|
||||||
memcpy(responseCode, response + 2, 2);
|
memcpy(responseCode, response + 2, 2);
|
||||||
// PrintAndLogEx(SUCCESS, "Raw Response..................... " _YELLOW_("%s"), sprint_hex_inrow(response, (resplen - 2)));
|
// PrintAndLogEx(SUCCESS, "Raw Response..................... " _YELLOW_("%s"), sprint_hex_inrow(response, (resplen - 2)));
|
||||||
PrintAndLogEx(SUCCESS, "Response Code.................... " _YELLOW_("%s"), sprint_hex_inrow(responseCode, (ARRAYLEN(responseCode))));
|
PrintAndLogEx(SUCCESS, "Response Code.................... " _YELLOW_("%s"), sprint_hex_inrow(responseCode, (ARRAYLEN(responseCode))));
|
||||||
|
@ -385,7 +381,7 @@ static void set_counter_big_endian(uint8_t *buffer, uint32_t counter) {
|
||||||
buffer[3] = counter & 0xFF;
|
buffer[3] = counter & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_mutual_auth_key(uint8_t* KEYIFD, uint8_t* KEYICC, uint8_t* RNDICC, uint8_t* RNDIFD, uint8_t* EncryptionKey, uint8_t* MACKey, int encryptionAlgorithm ,int HashingAlgorithm) {
|
static void create_mutual_auth_key(uint8_t *KEYIFD, uint8_t *KEYICC, uint8_t *RNDICC, uint8_t *RNDIFD, uint8_t *EncryptionKey, uint8_t *MACKey, int encryptionAlgorithm, int HashingAlgorithm) {
|
||||||
// Creating Mutual Authentication Keys
|
// Creating Mutual Authentication Keys
|
||||||
// Structure
|
// Structure
|
||||||
// Prefix = 00000000
|
// Prefix = 00000000
|
||||||
|
@ -398,8 +394,8 @@ static void create_mutual_auth_key(uint8_t* KEYIFD, uint8_t* KEYICC, uint8_t* RN
|
||||||
//
|
//
|
||||||
// 00000000 E0EC1F2D7B000000 F0EC1F2D7B000000 09 09 B0EC1F2D7B000000B8EC1F2D7B000000
|
// 00000000 E0EC1F2D7B000000 F0EC1F2D7B000000 09 09 B0EC1F2D7B000000B8EC1F2D7B000000
|
||||||
|
|
||||||
uint8_t prefix[4] = {0x00,0x00,0x00,0x00};
|
uint8_t prefix[4] = {0x00, 0x00, 0x00, 0x00};
|
||||||
uint8_t aHashingAlgorithm[2] = {encryptionAlgorithm,encryptionAlgorithm};
|
uint8_t aHashingAlgorithm[2] = {encryptionAlgorithm, encryptionAlgorithm};
|
||||||
uint8_t hash_in[38];
|
uint8_t hash_in[38];
|
||||||
|
|
||||||
memcpy(hash_in, prefix, 4);
|
memcpy(hash_in, prefix, 4);
|
||||||
|
@ -435,12 +431,10 @@ static void create_mutual_auth_key(uint8_t* KEYIFD, uint8_t* KEYICC, uint8_t* RN
|
||||||
sha1hash(hash_in, sizeof(hash_in), hashedOutput);
|
sha1hash(hash_in, sizeof(hash_in), hashedOutput);
|
||||||
memcpy(output + 20, hashedOutput, 20);
|
memcpy(output + 20, hashedOutput, 20);
|
||||||
//PrintAndLogEx(SUCCESS, "key_out_temp..................... " _YELLOW_("%s"), sprint_hex_inrow(hash_in,ARRAYLEN(hash_in)));
|
//PrintAndLogEx(SUCCESS, "key_out_temp..................... " _YELLOW_("%s"), sprint_hex_inrow(hash_in,ARRAYLEN(hash_in)));
|
||||||
}
|
} else if (HashingAlgorithm == 0x07) {
|
||||||
else if (HashingAlgorithm == 0x07) {
|
|
||||||
sha256hash(hash_in, sizeof(hash_in), hashedOutput);
|
sha256hash(hash_in, sizeof(hash_in), hashedOutput);
|
||||||
memcpy(output, hashedOutput, 32);
|
memcpy(output, hashedOutput, 32);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// Yes they generate their encryption keys and mac keys in a weird way for no fucking reason, the 2nd cycle isn't required.
|
// Yes they generate their encryption keys and mac keys in a weird way for no fucking reason, the 2nd cycle isn't required.
|
||||||
PrintAndLogEx(ERR, _RED_("Unknown Hashing Algorithm"));
|
PrintAndLogEx(ERR, _RED_("Unknown Hashing Algorithm"));
|
||||||
return;
|
return;
|
||||||
|
@ -457,7 +451,7 @@ static void create_mutual_auth_key(uint8_t* KEYIFD, uint8_t* KEYICC, uint8_t* RN
|
||||||
// PrintAndLogEx(SUCCESS, "MAC Key.......................... " _YELLOW_("%s"), sprint_hex_inrow(MACKey, 16));
|
// PrintAndLogEx(SUCCESS, "MAC Key.......................... " _YELLOW_("%s"), sprint_hex_inrow(MACKey, 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int seos_challenge_get(uint8_t* RNDICC, uint8_t RNDICC_len) {
|
static int seos_challenge_get(uint8_t *RNDICC, uint8_t RNDICC_len) {
|
||||||
uint8_t response[PM3_CMD_DATA_SIZE];
|
uint8_t response[PM3_CMD_DATA_SIZE];
|
||||||
int resplen = 0;
|
int resplen = 0;
|
||||||
|
|
||||||
|
@ -500,7 +494,7 @@ static int seos_challenge_get(uint8_t* RNDICC, uint8_t RNDICC_len) {
|
||||||
// 7C 0A 81 08 18 1E 43 80 10 10 20 11
|
// 7C 0A 81 08 18 1E 43 80 10 10 20 11
|
||||||
// 81 is the ASN.1 tag
|
// 81 is the ASN.1 tag
|
||||||
|
|
||||||
uint8_t staticResponse[8] = {0x01,0x81,0xE4,0x38,0x01,0x01,0x02,0x01};
|
uint8_t staticResponse[8] = {0x01, 0x81, 0xE4, 0x38, 0x01, 0x01, 0x02, 0x01};
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("Get Challenge") " ---------------------------");
|
PrintAndLogEx(INFO, "--- " _CYAN_("Get Challenge") " ---------------------------");
|
||||||
//PrintAndLogEx(SUCCESS, "Challenge Input: " _YELLOW_("%s"), getChallengePre);
|
//PrintAndLogEx(SUCCESS, "Challenge Input: " _YELLOW_("%s"), getChallengePre);
|
||||||
|
@ -513,8 +507,8 @@ static int seos_challenge_get(uint8_t* RNDICC, uint8_t RNDICC_len) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
};
|
};
|
||||||
|
|
||||||
int seos_kdf(bool encryption, uint8_t* masterKey, uint8_t keyslot,
|
int seos_kdf(bool encryption, uint8_t *masterKey, uint8_t keyslot,
|
||||||
uint8_t* adfOid, size_t adfoid_len, uint8_t* diversifier, uint8_t diversifier_len, uint8_t* out, int encryption_algorithm, int hash_algorithm) {
|
uint8_t *adfOid, size_t adfoid_len, uint8_t *diversifier, uint8_t diversifier_len, uint8_t *out, int encryption_algorithm, int hash_algorithm) {
|
||||||
|
|
||||||
// Encryption key = 04
|
// Encryption key = 04
|
||||||
// KEK Encryption key = 05
|
// KEK Encryption key = 05
|
||||||
|
@ -557,7 +551,7 @@ int seos_kdf(bool encryption, uint8_t* masterKey, uint8_t keyslot,
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int select_DF_verify(uint8_t* response, uint8_t response_length, uint8_t* MAC_value, size_t MAC_value_len, int encryption_algorithm, int key_index) {
|
static int select_DF_verify(uint8_t *response, uint8_t response_length, uint8_t *MAC_value, size_t MAC_value_len, int encryption_algorithm, int key_index) {
|
||||||
uint8_t input[response_length - 10];
|
uint8_t input[response_length - 10];
|
||||||
// Response is an ASN.1 encoded structure
|
// Response is an ASN.1 encoded structure
|
||||||
// Extract everything before the 8E tag
|
// Extract everything before the 8E tag
|
||||||
|
@ -592,7 +586,7 @@ static int select_DF_verify(uint8_t* response, uint8_t response_length, uint8_t*
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int select_df_decode(uint8_t* response, uint8_t response_length, int* ALGORITHM_INFO_value1, int* ALGORITHM_INFO_value2, uint8_t* CRYPTOGRAM_encrypted_data, uint8_t* MAC_value) {
|
static int select_df_decode(uint8_t *response, uint8_t response_length, int *ALGORITHM_INFO_value1, int *ALGORITHM_INFO_value2, uint8_t *CRYPTOGRAM_encrypted_data, uint8_t *MAC_value) {
|
||||||
// Response is an ASN.1 encoded structure
|
// Response is an ASN.1 encoded structure
|
||||||
// ASN.1 Information
|
// ASN.1 Information
|
||||||
// CF = Diversifier
|
// CF = Diversifier
|
||||||
|
@ -652,7 +646,7 @@ static int select_df_decode(uint8_t* response, uint8_t response_length, int* ALG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* algorithm_name1 = NULL;
|
const char *algorithm_name1 = NULL;
|
||||||
for (int i = 0; i < ARRAYLEN(known_algorithm_map); i++) {
|
for (int i = 0; i < ARRAYLEN(known_algorithm_map); i++) {
|
||||||
if ((known_algorithm_map[i].value) == ALGORITHM_INFO_value1_n) {
|
if ((known_algorithm_map[i].value) == ALGORITHM_INFO_value1_n) {
|
||||||
algorithm_name1 = known_algorithm_map[i].name;
|
algorithm_name1 = known_algorithm_map[i].name;
|
||||||
|
@ -660,7 +654,7 @@ static int select_df_decode(uint8_t* response, uint8_t response_length, int* ALG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* algorithm_name2 = NULL;
|
const char *algorithm_name2 = NULL;
|
||||||
for (int i = 0; i < ARRAYLEN(known_algorithm_map); i++) {
|
for (int i = 0; i < ARRAYLEN(known_algorithm_map); i++) {
|
||||||
if (known_algorithm_map[i].value == ALGORITHM_INFO_value2_n) {
|
if (known_algorithm_map[i].value == ALGORITHM_INFO_value2_n) {
|
||||||
algorithm_name2 = known_algorithm_map[i].name;
|
algorithm_name2 = known_algorithm_map[i].name;
|
||||||
|
@ -676,7 +670,7 @@ static int select_df_decode(uint8_t* response, uint8_t response_length, int* ALG
|
||||||
}
|
}
|
||||||
|
|
||||||
if (algorithm_name2 != NULL) {
|
if (algorithm_name2 != NULL) {
|
||||||
PrintAndLogEx(SUCCESS, "algoIdHash (MAC)................. "_YELLOW_("%i (%s)"),ALGORITHM_INFO_value2_n, algorithm_name2);
|
PrintAndLogEx(SUCCESS, "algoIdHash (MAC)................. "_YELLOW_("%i (%s)"), ALGORITHM_INFO_value2_n, algorithm_name2);
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(ERR, "algoIdHash (MAC)............... %d (Unknown)", ALGORITHM_INFO_value2_n);
|
PrintAndLogEx(ERR, "algoIdHash (MAC)............... %d (Unknown)", ALGORITHM_INFO_value2_n);
|
||||||
}
|
}
|
||||||
|
@ -688,7 +682,7 @@ static int select_df_decode(uint8_t* response, uint8_t response_length, int* ALG
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int select_ADF_decrypt(const char* selectADFOID, uint8_t* CRYPTOGRAM_encrypted_data_raw, uint8_t* CRYPTOGRAM_Diversifier, int encryption_algorithm, int key_index) {
|
static int select_ADF_decrypt(const char *selectADFOID, uint8_t *CRYPTOGRAM_encrypted_data_raw, uint8_t *CRYPTOGRAM_Diversifier, int encryption_algorithm, int key_index) {
|
||||||
// --------------- Decrypt ----------------
|
// --------------- Decrypt ----------------
|
||||||
|
|
||||||
// 1. MAC Verify - AES/CBC-decrypt (IV || cryptogram || 16 bytes after 8e 08) with the MAC key & keep the last block
|
// 1. MAC Verify - AES/CBC-decrypt (IV || cryptogram || 16 bytes after 8e 08) with the MAC key & keep the last block
|
||||||
|
@ -724,15 +718,15 @@ static int select_ADF_decrypt(const char* selectADFOID, uint8_t* CRYPTOGRAM_encr
|
||||||
adf_length = ((CRYPTOGRAM_decrypted_data[i + 1]));
|
adf_length = ((CRYPTOGRAM_decrypted_data[i + 1]));
|
||||||
diversifier_length = CRYPTOGRAM_decrypted_data[i + adf_length + 3];
|
diversifier_length = CRYPTOGRAM_decrypted_data[i + adf_length + 3];
|
||||||
|
|
||||||
uint8_t CRYPTOGRAM_ADF[strlen(selectADFOID)/2];
|
uint8_t CRYPTOGRAM_ADF[strlen(selectADFOID) / 2];
|
||||||
|
|
||||||
memcpy(CRYPTOGRAM_ADF, &CRYPTOGRAM_decrypted_data[i], strlen(selectADFOID)/2);
|
memcpy(CRYPTOGRAM_ADF, &CRYPTOGRAM_decrypted_data[i], strlen(selectADFOID) / 2);
|
||||||
memcpy(CRYPTOGRAM_Diversifier, &CRYPTOGRAM_decrypted_data[i + adf_length + 4], diversifier_length);
|
memcpy(CRYPTOGRAM_Diversifier, &CRYPTOGRAM_decrypted_data[i + adf_length + 4], diversifier_length);
|
||||||
|
|
||||||
const char* CRYPTOGRAM_ADF_CMP = (sprint_hex_inrow(CRYPTOGRAM_ADF,ARRAYLEN(CRYPTOGRAM_ADF)));
|
const char *CRYPTOGRAM_ADF_CMP = (sprint_hex_inrow(CRYPTOGRAM_ADF, ARRAYLEN(CRYPTOGRAM_ADF)));
|
||||||
|
|
||||||
char* CRYPTOGRAM_ADF_UPPER = strdup(CRYPTOGRAM_ADF_CMP);
|
char *CRYPTOGRAM_ADF_UPPER = strdup(CRYPTOGRAM_ADF_CMP);
|
||||||
char* selectADFOID_UPPER = strdup(selectADFOID);
|
char *selectADFOID_UPPER = strdup(selectADFOID);
|
||||||
|
|
||||||
// Convert both strings to uppercase
|
// Convert both strings to uppercase
|
||||||
for (int x = 0; CRYPTOGRAM_ADF_UPPER[x]; x++) {
|
for (int x = 0; CRYPTOGRAM_ADF_UPPER[x]; x++) {
|
||||||
|
@ -763,7 +757,7 @@ static int select_ADF_decrypt(const char* selectADFOID, uint8_t* CRYPTOGRAM_encr
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int seos_mutual_auth(uint8_t* randomICC, uint8_t* CRYPTOGRAM_Diversifier, uint8_t diversifier_len, uint8_t* mutual_auth_randomIFD, uint8_t* mutual_auth_keyICC, uint8_t* randomIFD, uint8_t randomIFD_len, uint8_t* keyIFD, uint8_t keyIFD_len, int encryption_algorithm, int hash_algorithm, int key_index) {
|
static int seos_mutual_auth(uint8_t *randomICC, uint8_t *CRYPTOGRAM_Diversifier, uint8_t diversifier_len, uint8_t *mutual_auth_randomIFD, uint8_t *mutual_auth_keyICC, uint8_t *randomIFD, uint8_t randomIFD_len, uint8_t *keyIFD, uint8_t keyIFD_len, int encryption_algorithm, int hash_algorithm, int key_index) {
|
||||||
uint8_t response[PM3_CMD_DATA_SIZE];
|
uint8_t response[PM3_CMD_DATA_SIZE];
|
||||||
|
|
||||||
// ---------------- Diversify Keys ----------------
|
// ---------------- Diversify Keys ----------------
|
||||||
|
@ -773,10 +767,10 @@ static int seos_mutual_auth(uint8_t* randomICC, uint8_t* CRYPTOGRAM_Diversifier,
|
||||||
uint8_t keyslot = 0x01; // up to 0x0F
|
uint8_t keyslot = 0x01; // up to 0x0F
|
||||||
uint8_t AES_key[24] = {0x00};
|
uint8_t AES_key[24] = {0x00};
|
||||||
uint8_t MAC_key[24] = {0x00};
|
uint8_t MAC_key[24] = {0x00};
|
||||||
uint8_t adfOID[17] = {0x2b,0x06,0x01,0x04,0x01,0x81,0xe4,0x38,0x01,0x01,0x02,0x01,0x18,0x01,0x01,0x02,0x02};
|
uint8_t adfOID[17] = {0x2b, 0x06, 0x01, 0x04, 0x01, 0x81, 0xe4, 0x38, 0x01, 0x01, 0x02, 0x01, 0x18, 0x01, 0x01, 0x02, 0x02};
|
||||||
|
|
||||||
// Null AES IV
|
// Null AES IV
|
||||||
uint8_t nullDiversifier[7] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
uint8_t nullDiversifier[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
if (memcmp(CRYPTOGRAM_Diversifier, nullDiversifier, sizeof(nullDiversifier)) == 0) {
|
if (memcmp(CRYPTOGRAM_Diversifier, nullDiversifier, sizeof(nullDiversifier)) == 0) {
|
||||||
PrintAndLogEx(ERR, "No Diversifier found");
|
PrintAndLogEx(ERR, "No Diversifier found");
|
||||||
|
@ -824,22 +818,22 @@ static int seos_mutual_auth(uint8_t* randomICC, uint8_t* CRYPTOGRAM_Diversifier,
|
||||||
|
|
||||||
// ----------------- Command Generation -----------------
|
// ----------------- Command Generation -----------------
|
||||||
|
|
||||||
const char* prefixLenHex = "2c";
|
const char *prefixLenHex = "2c";
|
||||||
const char* ASN1_tagAboveLenHex = "2a";
|
const char *ASN1_tagAboveLenHex = "2a";
|
||||||
const char* ASN1_auth_encryptedLenHex = "28";
|
const char *ASN1_auth_encryptedLenHex = "28";
|
||||||
|
|
||||||
const char* mutual_auth_message = sprint_hex_inrow(message_authenticated, sizeof(message_authenticated));
|
const char *mutual_auth_message = sprint_hex_inrow(message_authenticated, sizeof(message_authenticated));
|
||||||
|
|
||||||
char keyslot_str[3];
|
char keyslot_str[3];
|
||||||
snprintf(keyslot_str, sizeof(keyslot_str), "%02X", keyslot);
|
snprintf(keyslot_str, sizeof(keyslot_str), "%02X", keyslot);
|
||||||
|
|
||||||
const char* prefix = "008700";
|
const char *prefix = "008700";
|
||||||
const char* ASN1_tagAbove = "7c";
|
const char *ASN1_tagAbove = "7c";
|
||||||
const char* ASN1_auth_encrypted = "82";
|
const char *ASN1_auth_encrypted = "82";
|
||||||
const char* suffix = "00";
|
const char *suffix = "00";
|
||||||
|
|
||||||
char mutual_auth[102];
|
char mutual_auth[102];
|
||||||
snprintf(mutual_auth, sizeof(mutual_auth), "%s%s%s%s%s%s%s%s%s", prefix, keyslot_str, prefixLenHex, ASN1_tagAbove, ASN1_tagAboveLenHex,ASN1_auth_encrypted, ASN1_auth_encryptedLenHex, mutual_auth_message, suffix);
|
snprintf(mutual_auth, sizeof(mutual_auth), "%s%s%s%s%s%s%s%s%s", prefix, keyslot_str, prefixLenHex, ASN1_tagAbove, ASN1_tagAboveLenHex, ASN1_auth_encrypted, ASN1_auth_encryptedLenHex, mutual_auth_message, suffix);
|
||||||
// PrintAndLogEx(SUCCESS, "Mutual Auth Encrypted Request.... " _YELLOW_("%s"), mutual_auth);
|
// PrintAndLogEx(SUCCESS, "Mutual Auth Encrypted Request.... " _YELLOW_("%s"), mutual_auth);
|
||||||
|
|
||||||
// BLOCKS MUTUAL AUTH BEFORE REQUIRED
|
// BLOCKS MUTUAL AUTH BEFORE REQUIRED
|
||||||
|
@ -928,8 +922,8 @@ static int seos_aid_select(void) {
|
||||||
|
|
||||||
// --------------- Select AID for SEOS Card ----------------
|
// --------------- Select AID for SEOS Card ----------------
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char* name;
|
const char *name;
|
||||||
const char* value;
|
const char *value;
|
||||||
} seos_aid_t;
|
} seos_aid_t;
|
||||||
|
|
||||||
static const seos_aid_t known_AID_map[] = {
|
static const seos_aid_t known_AID_map[] = {
|
||||||
|
@ -942,16 +936,16 @@ static int seos_aid_select(void) {
|
||||||
//PrintAndLogEx(INFO, "--- " _CYAN_("AID Selection") " ---------------------------");
|
//PrintAndLogEx(INFO, "--- " _CYAN_("AID Selection") " ---------------------------");
|
||||||
for (i = 0; i < ARRAYLEN(known_AID_map); i++) {
|
for (i = 0; i < ARRAYLEN(known_AID_map); i++) {
|
||||||
|
|
||||||
const char* selectedAID = known_AID_map[i].value;
|
const char *selectedAID = known_AID_map[i].value;
|
||||||
|
|
||||||
// Select command prefixed with a 00
|
// Select command prefixed with a 00
|
||||||
const char* prefix = "00A404";
|
const char *prefix = "00A404";
|
||||||
uint16_t aidlen = strlen(selectedAID) >> 1;
|
uint16_t aidlen = strlen(selectedAID) >> 1;
|
||||||
|
|
||||||
char aidlenHex[5];
|
char aidlenHex[5];
|
||||||
snprintf(aidlenHex, sizeof(aidlenHex), "%04X", aidlen);
|
snprintf(aidlenHex, sizeof(aidlenHex), "%04X", aidlen);
|
||||||
|
|
||||||
const char* suffix = "0";
|
const char *suffix = "0";
|
||||||
char combinedString[100];
|
char combinedString[100];
|
||||||
|
|
||||||
snprintf(combinedString, sizeof(combinedString), "%s%s%s%s", prefix, aidlenHex, selectedAID, suffix);
|
snprintf(combinedString, sizeof(combinedString), "%s%s%s%s", prefix, aidlenHex, selectedAID, suffix);
|
||||||
|
@ -987,7 +981,7 @@ static int seos_aid_select(void) {
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int seos_pacs_adf_select(char* oid, int oid_len, uint8_t* get_data, int get_data_len, int key_index) {
|
static int seos_pacs_adf_select(char *oid, int oid_len, uint8_t *get_data, int get_data_len, int key_index) {
|
||||||
int resplen = 0;
|
int resplen = 0;
|
||||||
uint8_t response[PM3_CMD_DATA_SIZE];
|
uint8_t response[PM3_CMD_DATA_SIZE];
|
||||||
bool activate_field = false;
|
bool activate_field = false;
|
||||||
|
@ -1001,22 +995,22 @@ static int seos_pacs_adf_select(char* oid, int oid_len, uint8_t* get_data, int g
|
||||||
// 2b0601040181e438010102011801010202 = ADF-OID
|
// 2b0601040181e438010102011801010202 = ADF-OID
|
||||||
|
|
||||||
// --------------- OID Selection ----------------
|
// --------------- OID Selection ----------------
|
||||||
const char* ADFprefix = "06";
|
const char *ADFprefix = "06";
|
||||||
char selectedOID[100];
|
char selectedOID[100];
|
||||||
snprintf(selectedOID, sizeof(selectedOID), "%s", oid);
|
snprintf(selectedOID, sizeof(selectedOID), "%s", oid);
|
||||||
|
|
||||||
uint16_t selectedOIDLen = strlen(selectedOID);
|
uint16_t selectedOIDLen = strlen(selectedOID);
|
||||||
char selectedOIDLenHex[3];
|
char selectedOIDLenHex[3];
|
||||||
snprintf(selectedOIDLenHex, sizeof(selectedOIDLenHex), "%02X", (selectedOIDLen)/2);
|
snprintf(selectedOIDLenHex, sizeof(selectedOIDLenHex), "%02X", (selectedOIDLen) / 2);
|
||||||
|
|
||||||
char selectedADF[strlen(ADFprefix) + strlen(selectedOIDLenHex) + selectedOIDLen + 1];
|
char selectedADF[strlen(ADFprefix) + strlen(selectedOIDLenHex) + selectedOIDLen + 1];
|
||||||
snprintf(selectedADF, sizeof(selectedADF), "%s%s%s", ADFprefix, selectedOIDLenHex, selectedOID);
|
snprintf(selectedADF, sizeof(selectedADF), "%s%s%s", ADFprefix, selectedOIDLenHex, selectedOID);
|
||||||
|
|
||||||
// --------------- Command Builder Selection ----------------
|
// --------------- Command Builder Selection ----------------
|
||||||
// prefix is the APDU command we are sending
|
// prefix is the APDU command we are sending
|
||||||
const char* prefix = "80A504";
|
const char *prefix = "80A504";
|
||||||
const char* suffix = "00";
|
const char *suffix = "00";
|
||||||
const char* keyReference = "00";
|
const char *keyReference = "00";
|
||||||
|
|
||||||
uint16_t selectedADFLen = strlen(selectedADF);
|
uint16_t selectedADFLen = strlen(selectedADF);
|
||||||
|
|
||||||
|
@ -1058,11 +1052,11 @@ static int seos_pacs_adf_select(char* oid, int oid_len, uint8_t* get_data, int g
|
||||||
uint8_t CRYPTOGRAM_encrypted_data[64]; // Encrypted Data
|
uint8_t CRYPTOGRAM_encrypted_data[64]; // Encrypted Data
|
||||||
uint8_t MAC_value[8] = {0}; // MAC Value
|
uint8_t MAC_value[8] = {0}; // MAC Value
|
||||||
|
|
||||||
uint8_t diversifier[7] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
uint8_t diversifier[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
uint8_t RNDICC[8] = {0};
|
uint8_t RNDICC[8] = {0};
|
||||||
uint8_t KeyICC[16] = {0};
|
uint8_t KeyICC[16] = {0};
|
||||||
uint8_t RNDIFD[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
uint8_t RNDIFD[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
uint8_t KeyIFD[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
uint8_t KeyIFD[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
uint8_t Diversified_New_EncryptionKey[24] = {0};
|
uint8_t Diversified_New_EncryptionKey[24] = {0};
|
||||||
uint8_t Diversified_New_MACKey[24] = {0};
|
uint8_t Diversified_New_MACKey[24] = {0};
|
||||||
|
@ -1098,7 +1092,7 @@ static int seos_pacs_adf_select(char* oid, int oid_len, uint8_t* get_data, int g
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("Key Data") " ---------------------------");
|
PrintAndLogEx(INFO, "--- " _CYAN_("Key Data") " ---------------------------");
|
||||||
PrintAndLogEx(SUCCESS, "SIO.............................. "_YELLOW_("%s"), sprint_hex_inrow(sioOutput, sizeof(sioOutput))); // SIO
|
PrintAndLogEx(SUCCESS, "SIO.............................. "_YELLOW_("%s"), sprint_hex_inrow(sioOutput, sizeof(sioOutput))); // SIO
|
||||||
PrintAndLogEx(SUCCESS, "SIO Size......................... "_YELLOW_("%i"), sio_size); // SIO Size
|
PrintAndLogEx(SUCCESS, "SIO Size......................... "_YELLOW_("%i"), sio_size); // SIO Size
|
||||||
PrintAndLogEx(SUCCESS, "Diversifier...................... "_YELLOW_("%s"), sprint_hex_inrow(diversifier,ARRAYLEN(diversifier))); // Diversifier
|
PrintAndLogEx(SUCCESS, "Diversifier...................... "_YELLOW_("%s"), sprint_hex_inrow(diversifier, ARRAYLEN(diversifier))); // Diversifier
|
||||||
};
|
};
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -1109,29 +1103,29 @@ static int seos_pacs_adf_select(char* oid, int oid_len, uint8_t* get_data, int g
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int seos_adf_select(char* oid, int oid_len, int key_index) {
|
static int seos_adf_select(char *oid, int oid_len, int key_index) {
|
||||||
int resplen = 0;
|
int resplen = 0;
|
||||||
uint8_t response[PM3_CMD_DATA_SIZE];
|
uint8_t response[PM3_CMD_DATA_SIZE];
|
||||||
bool activate_field = false;
|
bool activate_field = false;
|
||||||
bool keep_field_on = true;
|
bool keep_field_on = true;
|
||||||
|
|
||||||
// --------------- OID Selection ----------------
|
// --------------- OID Selection ----------------
|
||||||
const char* ADFprefix = "06";
|
const char *ADFprefix = "06";
|
||||||
char selectedOID[100];
|
char selectedOID[100];
|
||||||
snprintf(selectedOID, sizeof(selectedOID), "%s", oid);
|
snprintf(selectedOID, sizeof(selectedOID), "%s", oid);
|
||||||
|
|
||||||
uint16_t selectedOIDLen = strlen(selectedOID);
|
uint16_t selectedOIDLen = strlen(selectedOID);
|
||||||
char selectedOIDLenHex[3];
|
char selectedOIDLenHex[3];
|
||||||
snprintf(selectedOIDLenHex, sizeof(selectedOIDLenHex), "%02X", (selectedOIDLen)/2);
|
snprintf(selectedOIDLenHex, sizeof(selectedOIDLenHex), "%02X", (selectedOIDLen) / 2);
|
||||||
|
|
||||||
char selectedADF[strlen(ADFprefix) + strlen(selectedOIDLenHex) + selectedOIDLen + 1];
|
char selectedADF[strlen(ADFprefix) + strlen(selectedOIDLenHex) + selectedOIDLen + 1];
|
||||||
snprintf(selectedADF, sizeof(selectedADF), "%s%s%s", ADFprefix, selectedOIDLenHex, selectedOID);
|
snprintf(selectedADF, sizeof(selectedADF), "%s%s%s", ADFprefix, selectedOIDLenHex, selectedOID);
|
||||||
|
|
||||||
// --------------- Command Builder Selection ----------------
|
// --------------- Command Builder Selection ----------------
|
||||||
// prefix is the APDU command we are sending
|
// prefix is the APDU command we are sending
|
||||||
const char* prefix = "80A504";
|
const char *prefix = "80A504";
|
||||||
const char* suffix = "00";
|
const char *suffix = "00";
|
||||||
const char* keyReference = "00";
|
const char *keyReference = "00";
|
||||||
|
|
||||||
uint16_t selectedADFLen = strlen(selectedADF);
|
uint16_t selectedADFLen = strlen(selectedADF);
|
||||||
char adflenHex[3];
|
char adflenHex[3];
|
||||||
|
@ -1190,7 +1184,7 @@ static int seos_gdf_select(int key_index) {
|
||||||
// 00A5070600
|
// 00A5070600
|
||||||
// SelectGlobalDF = 00A50000
|
// SelectGlobalDF = 00A50000
|
||||||
|
|
||||||
const char* getGDF = "00A5070600";
|
const char *getGDF = "00A5070600";
|
||||||
|
|
||||||
uint8_t agetGDF[10];
|
uint8_t agetGDF[10];
|
||||||
int agetGDF_n = 0;
|
int agetGDF_n = 0;
|
||||||
|
@ -1230,14 +1224,14 @@ static int seos_select(void) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* oid = "2B0601040181E438010102011801010202";
|
const char *oid = "2B0601040181E438010102011801010202";
|
||||||
int oid_len = strlen(oid);
|
int oid_len = strlen(oid);
|
||||||
res = seos_adf_select((char*)oid, oid_len, 0);
|
res = seos_adf_select((char *)oid, oid_len, 0);
|
||||||
DropField();
|
DropField();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int seos_pacs(char* oid, int oid_len, uint8_t* get_data, int get_data_len, int key_index) {
|
static int seos_pacs(char *oid, int oid_len, uint8_t *get_data, int get_data_len, int key_index) {
|
||||||
int res = seos_aid_select();
|
int res = seos_aid_select();
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
DropField();
|
DropField();
|
||||||
|
@ -1271,8 +1265,7 @@ static int seos_print_keys(bool verbose) {
|
||||||
PrintAndLogEx(INFO, "Admin Key........................ " _YELLOW_("%s"), sprint_hex(keys[i].adminKey, 16));
|
PrintAndLogEx(INFO, "Admin Key........................ " _YELLOW_("%s"), sprint_hex(keys[i].adminKey, 16));
|
||||||
PrintAndLogEx(INFO, "----------------------------");
|
PrintAndLogEx(INFO, "----------------------------");
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
PrintAndLogEx(INFO, "idx| key");
|
PrintAndLogEx(INFO, "idx| key");
|
||||||
PrintAndLogEx(INFO, "---+------------------------");
|
PrintAndLogEx(INFO, "---+------------------------");
|
||||||
for (uint8_t i = 0; i < ARRAYLEN(keys); i++) {
|
for (uint8_t i = 0; i < ARRAYLEN(keys); i++) {
|
||||||
|
@ -1386,10 +1379,10 @@ static int CmdHfSeosPACS(const char *Cmd) {
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
int get_data_len = 4;
|
int get_data_len = 4;
|
||||||
uint8_t get_data[] = {0x5c,0x02,0xff,0x00};
|
uint8_t get_data[] = {0x5c, 0x02, 0xff, 0x00};
|
||||||
|
|
||||||
int oid_len = 0;
|
int oid_len = 0;
|
||||||
uint8_t oid_hex[256] = {0x2B,0x06,0x01,0x04,0x01,0x81,0xE4,0x38,0x01,0x01,0x02,0x01,0x18,0x01,0x01,0x02};
|
uint8_t oid_hex[256] = {0x2B, 0x06, 0x01, 0x04, 0x01, 0x81, 0xE4, 0x38, 0x01, 0x01, 0x02, 0x01, 0x18, 0x01, 0x01, 0x02};
|
||||||
CLIGetHexWithReturn(ctx, 1, oid_hex, &oid_len);
|
CLIGetHexWithReturn(ctx, 1, oid_hex, &oid_len);
|
||||||
|
|
||||||
int key_index = arg_get_int_def(ctx, 2, 0);
|
int key_index = arg_get_int_def(ctx, 2, 0);
|
||||||
|
@ -1408,14 +1401,14 @@ static int CmdHfSeosPACS(const char *Cmd) {
|
||||||
sprintf(oid_buffer + (i * 2), "%02X", oid_hex[i]);
|
sprintf(oid_buffer + (i * 2), "%02X", oid_hex[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* oid = oid_buffer;
|
const char *oid = oid_buffer;
|
||||||
|
|
||||||
if (oid_len == 0) {
|
if (oid_len == 0) {
|
||||||
PrintAndLogEx(ERR, "OID value must be supplied");
|
PrintAndLogEx(ERR, "OID value must be supplied");
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return seos_pacs((char*)oid, oid_len, get_data, get_data_len, key_index);
|
return seos_pacs((char *)oid, oid_len, get_data, get_data_len, key_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdHfSeosADF(const char *Cmd) {
|
static int CmdHfSeosADF(const char *Cmd) {
|
||||||
|
@ -1444,11 +1437,11 @@ static int CmdHfSeosADF(const char *Cmd) {
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
int get_data_len = 0;
|
int get_data_len = 0;
|
||||||
uint8_t get_data[256] = {0x5c,0x02,0xff,0x00};
|
uint8_t get_data[256] = {0x5c, 0x02, 0xff, 0x00};
|
||||||
CLIGetHexWithReturn(ctx, 1, get_data, &get_data_len);
|
CLIGetHexWithReturn(ctx, 1, get_data, &get_data_len);
|
||||||
|
|
||||||
int oid_len = 0;
|
int oid_len = 0;
|
||||||
uint8_t oid_hex[256] = {0x2B,0x06,0x01,0x04,0x01,0x81,0xE4,0x38,0x01,0x01,0x02,0x01,0x18,0x01,0x01,0x02};
|
uint8_t oid_hex[256] = {0x2B, 0x06, 0x01, 0x04, 0x01, 0x81, 0xE4, 0x38, 0x01, 0x01, 0x02, 0x01, 0x18, 0x01, 0x01, 0x02};
|
||||||
CLIGetHexWithReturn(ctx, 2, oid_hex, &oid_len);
|
CLIGetHexWithReturn(ctx, 2, oid_hex, &oid_len);
|
||||||
|
|
||||||
int key_index = arg_get_int_def(ctx, 3, 0);
|
int key_index = arg_get_int_def(ctx, 3, 0);
|
||||||
|
@ -1470,14 +1463,14 @@ static int CmdHfSeosADF(const char *Cmd) {
|
||||||
sprintf(oid_buffer + (i * 2), "%02X", oid_hex[i]);
|
sprintf(oid_buffer + (i * 2), "%02X", oid_hex[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* oid = oid_buffer;
|
const char *oid = oid_buffer;
|
||||||
|
|
||||||
if (oid_len == 0) {
|
if (oid_len == 0) {
|
||||||
PrintAndLogEx(ERR, "OID value must be supplied");
|
PrintAndLogEx(ERR, "OID value must be supplied");
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return seos_pacs((char*)oid, oid_len, get_data, get_data_len, key_index);
|
return seos_pacs((char *)oid, oid_len, get_data, get_data_len, key_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdHfSeosManageKeys(const char *Cmd) {
|
static int CmdHfSeosManageKeys(const char *Cmd) {
|
||||||
|
@ -1560,8 +1553,7 @@ static int CmdHfSeosManageKeys(const char *Cmd) {
|
||||||
if (admin_len != 0) {
|
if (admin_len != 0) {
|
||||||
PrintAndLogEx(SUCCESS, "Current value for Admin Key[%d] " _GREEN_("%s"), key_index, sprint_hex_inrow(keys[key_index].adminKey, 16));
|
PrintAndLogEx(SUCCESS, "Current value for Admin Key[%d] " _GREEN_("%s"), key_index, sprint_hex_inrow(keys[key_index].adminKey, 16));
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
PrintAndLogEx(ERR, "Key index is out-of-range");
|
PrintAndLogEx(ERR, "Key index is out-of-range");
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue