mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-26 03:39:58 -07:00
513 lines
19 KiB
C
513 lines
19 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <mbedtls/sha1.h>
|
|
#include <mbedtls/des.h>
|
|
|
|
#include "applications/main/nfc/test_bac_creds.h" //TODO: remove
|
|
|
|
#include "lib/nfc/protocols/mrtd_helpers.h"
|
|
|
|
// gcc -o test_mrtd_helpers -Wall -Ilib/mbedtls/include -Itoolchain/x86_64-linux/arm-none-eabi/include/ lib/nfc/protocols/mrtd_helpers.c lib/mbedtls/library/sha1.c lib/mbedtls/library/des.c lib/mbedtls/library/platform_util.c test_mrtd_helpers.c
|
|
|
|
#define COLOR_RED "\033[0;31m"
|
|
#define COLOR_GREEN "\033[0;32m"
|
|
#define COLOR_RESET "\033[0;0m"
|
|
|
|
void print_hex(const uint8_t* data, size_t length) {
|
|
for(uint8_t i=0; i<length; ++i) {
|
|
printf("%02X", data[i]);
|
|
}
|
|
}
|
|
|
|
void test_mrtd_bac_check_digit(const char* input, const uint8_t exp_output) {
|
|
uint8_t output = mrtd_bac_check_digit(input, strlen(input));
|
|
if(output != exp_output) {
|
|
printf(COLOR_RED "FAILED - mrtd_bac_check_digit for %s is not %d, but %d\n" COLOR_RESET,
|
|
input, exp_output, output);
|
|
return;
|
|
}
|
|
|
|
printf(COLOR_GREEN "SUCCESS - mrtd_bac_check_digit for %s is %d\n" COLOR_RESET,
|
|
input, output);
|
|
}
|
|
|
|
void test_bac_get_kmrz(MrtdAuthData* auth, const char* exp_output) {
|
|
bool result;
|
|
char buffer[255];
|
|
|
|
result = mrtd_bac_get_kmrz(auth, buffer, 255);
|
|
if(!result) {
|
|
printf(COLOR_RED "FAILED - mrtd_bac_get_kmrz returned FALSE for" COLOR_RESET);
|
|
return;
|
|
}
|
|
|
|
if(strcmp(exp_output, buffer)) {
|
|
printf(COLOR_RED "FAILED - mrtd_bac_get_kmrz expected:\n%s, result:\n%s\n" COLOR_RESET,
|
|
exp_output,
|
|
buffer);
|
|
}
|
|
|
|
printf(COLOR_GREEN "SUCCESS - mrtd_bac_get_kmrz is: %s\n" COLOR_RESET,
|
|
buffer);
|
|
}
|
|
|
|
void test_sha1(const uint8_t* data, const uint8_t* exp_output) {
|
|
uint8_t hash[20];
|
|
mbedtls_sha1(data, strlen((char*)data), hash);
|
|
|
|
if(memcmp(hash, exp_output, 20)) {
|
|
printf(COLOR_RED "FAILED - sha1 of %s, expected:\n", data);
|
|
print_hex(exp_output, 20);
|
|
printf(", result:\n");
|
|
} else {
|
|
printf(COLOR_GREEN "SUCCESS - sha1 of %s is: ", data);
|
|
}
|
|
|
|
print_hex(hash, 20);
|
|
printf("\n" COLOR_RESET);
|
|
}
|
|
|
|
void test_mrtd_bac_keys_from_seed(const uint8_t kseed[16], const uint8_t exp_ksenc[16], const uint8_t exp_ksmac[16]) {
|
|
uint8_t ksenc[16];
|
|
uint8_t ksmac[16];
|
|
if(!mrtd_bac_keys_from_seed(kseed, ksenc, ksmac)) {
|
|
printf(COLOR_RED "FAILED - mrtd_bac_keys_from_seed returned FALSE for ");
|
|
print_hex(kseed, 16);
|
|
printf(COLOR_RESET "\n");
|
|
return;
|
|
}
|
|
|
|
if(memcmp(exp_ksenc, ksenc, 16)) {
|
|
printf(COLOR_RED "FAILED - mrtd_bac_keys_from_seed of ");
|
|
print_hex(kseed, 16);
|
|
printf(", expected ksenc:\n");
|
|
print_hex(exp_ksenc, 16);
|
|
printf(" is:\n");
|
|
print_hex(ksenc, 16);
|
|
return;
|
|
} else if(memcmp(exp_ksmac, ksmac, 16)) {
|
|
printf(COLOR_RED "FAILED - mrtd_bac_keys_from_seed of ");
|
|
print_hex(kseed, 16);
|
|
printf(", expected ksmac:\n");
|
|
print_hex(exp_ksmac, 16);
|
|
printf(" is:\n");
|
|
print_hex(ksmac, 16);
|
|
return;
|
|
} else {
|
|
printf(COLOR_GREEN "SUCCESS - mrtd_bac_keys_from_seed of ");
|
|
print_hex(kseed, 16);
|
|
printf(" ksenc: ");
|
|
print_hex(ksenc, 16);
|
|
printf(" ksmac: ");
|
|
print_hex(ksmac, 16);
|
|
printf(COLOR_RESET "\n");
|
|
}
|
|
}
|
|
|
|
void test_mrtd_bac_keys(MrtdAuthData* auth, const uint8_t exp_ksenc[16], const uint8_t exp_ksmac[16]) {
|
|
uint8_t ksenc[16];
|
|
uint8_t ksmac[16];
|
|
if(!mrtd_bac_keys(auth, ksenc, ksmac)) {
|
|
printf(COLOR_RED "FAILED - mrtd_bac_keys returned FALSE\n" COLOR_RESET);
|
|
return;
|
|
}
|
|
|
|
if(memcmp(exp_ksenc, ksenc, 16)) {
|
|
printf(COLOR_RED "FAILED - mrtd_bac_keys, expected ksenc:\n");
|
|
print_hex(exp_ksenc, 16);
|
|
printf(" is:\n");
|
|
print_hex(ksenc, 16);
|
|
return;
|
|
} else if(memcmp(exp_ksmac, ksmac, 16)) {
|
|
printf(COLOR_RED "FAILED - mrtd_bac_keys, expected ksmac:\n");
|
|
print_hex(exp_ksmac, 16);
|
|
printf(" is:\n");
|
|
print_hex(ksmac, 16);
|
|
return;
|
|
} else {
|
|
printf(COLOR_GREEN "SUCCESS - mrtd_bac_keys ksenc: ");
|
|
print_hex(ksenc, 16);
|
|
printf(" ksmac: ");
|
|
print_hex(ksmac, 16);
|
|
printf(COLOR_RESET "\n");
|
|
}
|
|
}
|
|
|
|
void test_mrtd_bac_encrypt(uint8_t* data, size_t data_length, uint8_t* key, uint8_t* exp_output, size_t exp_output_length) {
|
|
uint8_t buffer[256];
|
|
|
|
// buffer size must be at least ((data_length+8)/8)*8
|
|
mrtd_bac_encrypt(data, data_length, key, buffer);
|
|
|
|
if(memcmp(exp_output, buffer, exp_output_length)) {
|
|
printf(COLOR_RED "FAILED - mrtd_bac_encrypt, expected output:\n");
|
|
print_hex(exp_output, exp_output_length);
|
|
printf(" is:\n");
|
|
print_hex(buffer, exp_output_length);
|
|
return;
|
|
} else {
|
|
printf(COLOR_GREEN "SUCCESS - mrtd_bac_encrypt output: ");
|
|
print_hex(buffer, exp_output_length);
|
|
printf(COLOR_RESET "\n");
|
|
}
|
|
}
|
|
|
|
void test_mrtd_bac_padded_mac(uint8_t* data, size_t data_length, uint8_t* key, uint8_t* exp_output, size_t exp_output_length) {
|
|
uint8_t mac[8];
|
|
if(!mrtd_bac_padded_mac(data, data_length, key, mac)) {
|
|
printf("ERROR BAC MAC\n");
|
|
return;
|
|
}
|
|
|
|
if(memcmp(exp_output, mac, exp_output_length)) {
|
|
printf(COLOR_RED "FAILED - mrtd_bac_padded_mac, expected output:\n");
|
|
print_hex(exp_output, exp_output_length);
|
|
printf(" is:\n");
|
|
print_hex(mac, 8);
|
|
printf(COLOR_RESET "\n");
|
|
return;
|
|
} else {
|
|
printf(COLOR_GREEN "SUCCESS - mrtd_bac_padded_mac output: ");
|
|
print_hex(mac, 8);
|
|
printf(COLOR_RESET "\n");
|
|
}
|
|
}
|
|
|
|
void test_mrtd_bac_mac_calls(uint8_t* data, size_t data_length, uint8_t* key, uint8_t* exp_output, size_t exp_output_length) {
|
|
mrtd_bac_mac_ctx ctx;
|
|
|
|
for(int break_at=0; break_at<data_length; break_at += 3) {
|
|
if(!mrtd_bac_mac_init(&ctx, key)) {
|
|
printf("ERROR mrtd_bac_mac_init (break_at: %d)\n", break_at);
|
|
return;
|
|
}
|
|
|
|
uint8_t mac[8];
|
|
|
|
if(!mrtd_bac_mac_update(&ctx, data, break_at)) {
|
|
printf("ERROR mrtd_bac_mac_update 1 (break_at: %d)\n", break_at);
|
|
}
|
|
|
|
if(!mrtd_bac_mac_update(&ctx, data + break_at, data_length - break_at)) {
|
|
printf("ERROR mrtd_bac_mac_update 2 (break_at: %d)\n", break_at);
|
|
}
|
|
|
|
if(!mrtd_bac_mac_finalize(&ctx, mac)) {
|
|
printf("ERROR mrtd_bac_mac_finalize (break_at: %d)\n", break_at);
|
|
return;
|
|
}
|
|
|
|
if(memcmp(exp_output, mac, exp_output_length)) {
|
|
printf(COLOR_RED "FAILED - mrtd_bac_mac calls (break_at: %d), expected output:\n", break_at);
|
|
print_hex(exp_output, exp_output_length);
|
|
printf(" is:\n");
|
|
print_hex(mac, 8);
|
|
printf(COLOR_RESET "\n");
|
|
return;
|
|
} else {
|
|
printf(COLOR_GREEN "SUCCESS - mrtd_bac_mac calls (break_at: %d) output: ", break_at);
|
|
print_hex(mac, 8);
|
|
printf(COLOR_RESET "\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
void test_mrtd_bac_mac_steps(uint8_t* data, size_t data_length, uint8_t* key, uint8_t* exp_output, size_t exp_output_length) {
|
|
mrtd_bac_mac_ctx ctx;
|
|
|
|
printf("A\n");
|
|
|
|
if(!mrtd_bac_mac_init(&ctx, key)) {
|
|
printf("ERROR mrtd_bac_mac_init (steps)\n");
|
|
return;
|
|
}
|
|
|
|
if(!mrtd_bac_mac_update(&ctx, data, 8)) {
|
|
printf("ERROR mrtd_bac_mac_update 1 (steps)\n");
|
|
}
|
|
|
|
if(!mrtd_bac_mac_update(&ctx, data + 8, 4)) {
|
|
printf("ERROR mrtd_bac_mac_update 2 (steps)\n");
|
|
}
|
|
|
|
if(!mrtd_bac_mac_pad(&ctx)) {
|
|
printf("ERROR mrtd_bac_mac_pad (steps)\n");
|
|
}
|
|
|
|
if(!mrtd_bac_mac_update(&ctx, data + 16, 11)) {
|
|
printf("ERROR mrtd_bac_mac_update 3 (steps)\n");
|
|
}
|
|
|
|
uint8_t mac[8];
|
|
if(!mrtd_bac_mac_finalize(&ctx, mac)) {
|
|
printf("ERROR mrtd_bac_mac_finalize (steps)\n");
|
|
return;
|
|
}
|
|
|
|
if(memcmp(exp_output, mac, exp_output_length)) {
|
|
printf(COLOR_RED "FAILED - mrtd_bac_mac (steps), expected output:\n");
|
|
print_hex(exp_output, exp_output_length);
|
|
printf(" is:\n");
|
|
print_hex(mac, 8);
|
|
printf(COLOR_RESET "\n");
|
|
return;
|
|
} else {
|
|
printf(COLOR_GREEN "SUCCESS - mrtd_bac_mac (steps) output: ");
|
|
print_hex(mac, 8);
|
|
printf(COLOR_RESET "\n");
|
|
}
|
|
}
|
|
|
|
void test_mrtd_bac_decrypt_verify(const uint8_t* data, size_t data_length, uint8_t* key_enc, uint8_t* key_mac, uint8_t* exp_output, size_t exp_output_length, bool should_verify) {
|
|
uint8_t buffer[256];
|
|
|
|
bool result = mrtd_bac_decrypt_verify(data, data_length, key_enc, key_mac, buffer);
|
|
if(result != should_verify) {
|
|
printf(COLOR_RED "FAILED - mrtd_bac_decrypt_verify, expected verify: %d, but is: %d\n" COLOR_RESET, should_verify, result);
|
|
return;
|
|
}
|
|
|
|
if(memcmp(exp_output, buffer, exp_output_length)) {
|
|
printf(COLOR_RED "FAILED - mrtd_bac_decrypt_verify, expected output:\n");
|
|
print_hex(exp_output, exp_output_length);
|
|
printf(" is:\n");
|
|
print_hex(buffer, 32);
|
|
printf(COLOR_RESET "\n");
|
|
return;
|
|
}
|
|
|
|
printf(COLOR_GREEN "SUCCESS - mrtd_bac_decrypt_verify output: ");
|
|
print_hex(buffer, exp_output_length);
|
|
printf(COLOR_RESET "\n");
|
|
}
|
|
|
|
void test_mrtd_bac_decrypt_verify_sm(const uint8_t* data, size_t data_length, uint8_t* key_enc, uint8_t* key_mac, uint64_t ssc, uint8_t* exp_output, size_t exp_output_length, bool should_verify) {
|
|
uint8_t buffer[256];
|
|
uint16_t ret_code;
|
|
|
|
bool result = mrtd_bac_decrypt_verify_sm(data, data_length, key_enc, key_mac, ssc, buffer, &ret_code);
|
|
if(result != should_verify) {
|
|
printf(COLOR_RED "FAILED - mrtd_bac_decrypt_verify_sm, expected verify: %d, but is: %d\n" COLOR_RESET, should_verify, result);
|
|
return;
|
|
}
|
|
|
|
if(ret_code != 0x9000) {
|
|
printf(COLOR_RED "FAILED - mrtd_bac_decrypt_verify_sm, expected ret_code: %04X, but is: %04X\n" COLOR_RESET, 0x9000, ret_code);
|
|
return;
|
|
}
|
|
|
|
if(memcmp(exp_output, buffer, exp_output_length)) {
|
|
printf(COLOR_RED "FAILED - mrtd_bac_decrypt_verify_sm, expected output:\n");
|
|
print_hex(exp_output, exp_output_length);
|
|
printf(" is:\n");
|
|
print_hex(buffer, 32);
|
|
printf(COLOR_RESET "\n");
|
|
return;
|
|
}
|
|
|
|
printf(COLOR_GREEN "SUCCESS - mrtd_bac_decrypt_verify_sm output: ");
|
|
print_hex(buffer, exp_output_length);
|
|
printf(COLOR_RESET "\n");
|
|
}
|
|
|
|
void test_mrtd_ssc_from_data(const uint8_t* rnd_ic, const uint8_t* rnd_ifd, uint64_t exp_ssc) {
|
|
uint64_t ssc_long = mrtd_ssc_from_data(rnd_ic, rnd_ifd);
|
|
|
|
if(ssc_long != exp_ssc) {
|
|
printf(COLOR_RED "FAILED - mrtd_ssc_from_data, expected ssc: %016lx, but is: %016lx\n" COLOR_RESET, exp_ssc, ssc_long);
|
|
return;
|
|
}
|
|
|
|
printf(COLOR_GREEN "SUCCESS - mrtd_ssc_from_data output: %016lx\n" COLOR_RESET, ssc_long);
|
|
}
|
|
|
|
void test_mrtd_protect_apdu(uint8_t cla, uint8_t ins, uint8_t p1, uint8_t p2, uint8_t lc, const void* data, int16_t le, uint8_t* ks_enc, uint8_t* ks_mac, uint64_t ssc, uint8_t* exp_output, size_t exp_output_length) {
|
|
uint8_t buffer[4096];
|
|
|
|
size_t ret = mrtd_protect_apdu(cla, ins, p1, p2, lc, data, le, ks_enc, ks_mac, ssc, buffer);
|
|
|
|
if(!ret) {
|
|
printf(COLOR_RED "FAILED - mrtd_protect_apdu returned an error\n" COLOR_RESET);
|
|
return;
|
|
}
|
|
|
|
if(memcmp(buffer, exp_output, ret)) {
|
|
printf(COLOR_RED "FAILED - mrtd_protect_apdu, expected output:\n");
|
|
print_hex(exp_output, exp_output_length);
|
|
printf(" is:\n");
|
|
print_hex(buffer, ret);
|
|
printf("\n" COLOR_RESET);
|
|
return;
|
|
}
|
|
|
|
printf(COLOR_GREEN "SUCCESS - mrtd_protect_apdu output: ");
|
|
print_hex(buffer, ret);
|
|
printf("\n" COLOR_RESET);
|
|
//TODO: hexdump
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
test_mrtd_bac_check_digit("D23145890734", 9);
|
|
test_mrtd_bac_check_digit("340712", 7);
|
|
test_mrtd_bac_check_digit("950712", 2);
|
|
|
|
test_bac_get_kmrz(&(MrtdAuthData){
|
|
.doc_number = "D23145890734",
|
|
.birth_date = {34, 7, 12},
|
|
.expiry_date = {95, 7, 12},
|
|
}, "D23145890734934071279507122"
|
|
);
|
|
test_bac_get_kmrz(&(MrtdAuthData){
|
|
.doc_number = "L898902C",
|
|
.birth_date = {69, 8, 6},
|
|
.expiry_date = {94, 6, 23},
|
|
}, "L898902C<369080619406236"
|
|
);
|
|
|
|
test_sha1((uint8_t*)"L898902C<369080619406236", (uint8_t*)"\x23\x9a\xb9\xcb\x28\x2d\xaf\x66\x23\x1d\xc5\xa4\xdf\x6b\xfb\xae\xdf\x47\x75\x65");
|
|
|
|
test_mrtd_bac_keys_from_seed(
|
|
(uint8_t*)"\x23\x9a\xb9\xcb\x28\x2d\xaf\x66\x23\x1d\xc5\xa4\xdf\x6b\xfb\xae",
|
|
(uint8_t*)"\xab\x94\xfd\xec\xf2\x67\x4f\xdf\xb9\xb3\x91\xf8\x5d\x7f\x76\xf2",
|
|
(uint8_t*)"\x79\x62\xd9\xec\xe0\x3d\x1a\xcd\x4c\x76\x08\x9d\xce\x13\x15\x43"
|
|
);
|
|
|
|
test_mrtd_bac_keys(&(MrtdAuthData){
|
|
.doc_number = "L898902C",
|
|
.birth_date = {69, 8, 6},
|
|
.expiry_date = {94, 6, 23},
|
|
},
|
|
(uint8_t*)"\xab\x94\xfd\xec\xf2\x67\x4f\xdf\xb9\xb3\x91\xf8\x5d\x7f\x76\xf2",
|
|
(uint8_t*)"\x79\x62\xd9\xec\xe0\x3d\x1a\xcd\x4c\x76\x08\x9d\xce\x13\x15\x43"
|
|
);
|
|
|
|
test_mrtd_bac_encrypt(
|
|
/*input*/ (uint8_t*)"\x78\x17\x23\x86\x0C\x06\xC2\x26\x46\x08\xF9\x19\x88\x70\x22\x12\x0B\x79\x52\x40\xCB\x70\x49\xB0\x1C\x19\xB3\x3E\x32\x80\x4F\x0B",
|
|
/*size*/ 32,
|
|
/*key*/ (uint8_t*)"\xAB\x94\xFD\xEC\xF2\x67\x4F\xDF\xB9\xB3\x91\xF8\x5D\x7F\x76\xF2",
|
|
/*exp output*/ (uint8_t*)"\x72\xC2\x9C\x23\x71\xCC\x9B\xDB\x65\xB7\x79\xB8\xE8\xD3\x7B\x29\xEC\xC1\x54\xAA\x56\xA8\x79\x9F\xAE\x2F\x49\x8F\x76\xED\x92\xF2",
|
|
/*exp_output_size*/ 32
|
|
);
|
|
|
|
test_mrtd_bac_padded_mac(
|
|
/*input*/ (uint8_t*)"\x72\xC2\x9C\x23\x71\xCC\x9B\xDB\x65\xB7\x79\xB8\xE8\xD3\x7B\x29\xEC\xC1\x54\xAA\x56\xA8\x79\x9F\xAE\x2F\x49\x8F\x76\xED\x92\xF2",
|
|
/*size*/ 32,
|
|
/*key*/ (uint8_t*)"\x79\x62\xD9\xEC\xE0\x3D\x1A\xCD\x4C\x76\x08\x9D\xCE\x13\x15\x43",
|
|
/*exp output*/ (uint8_t*)"\x5F\x14\x48\xEE\xA8\xAD\x90\xA7",
|
|
/*exp_output_size*/ 8
|
|
);
|
|
|
|
test_mrtd_bac_mac_calls(
|
|
/*input*/ (uint8_t*)"\x72\xC2\x9C\x23\x71\xCC\x9B\xDB\x65\xB7\x79\xB8\xE8\xD3\x7B\x29\xEC\xC1\x54\xAA\x56\xA8\x79\x9F\xAE\x2F\x49\x8F\x76\xED\x92\xF2",
|
|
/*size*/ 32,
|
|
/*key*/ (uint8_t*)"\x79\x62\xD9\xEC\xE0\x3D\x1A\xCD\x4C\x76\x08\x9D\xCE\x13\x15\x43",
|
|
/*exp output*/ (uint8_t*)"\x5F\x14\x48\xEE\xA8\xAD\x90\xA7",
|
|
/*exp_output_size*/ 8
|
|
);
|
|
|
|
test_mrtd_bac_decrypt_verify(
|
|
/*input*/ (uint8_t*)"\x46\xB9\x34\x2A\x41\x39\x6C\xD7\x38\x6B\xF5\x80\x31\x04\xD7\xCE\xDC\x12\x2B\x91\x32\x13\x9B\xAF\x2E\xED\xC9\x4E\xE1\x78\x53\x4F\x2F\x2D\x23\x5D\x07\x4D\x74\x49",
|
|
/*size*/ 40,
|
|
/*key_enc*/ (uint8_t*)"\xAB\x94\xFD\xEC\xF2\x67\x4F\xDF\xB9\xB3\x91\xF8\x5D\x7F\x76\xF2",
|
|
/*key_mac*/ (uint8_t*)"\x79\x62\xD9\xEC\xE0\x3D\x1A\xCD\x4C\x76\x08\x9D\xCE\x13\x15\x43",
|
|
/*exp output*/ (uint8_t*)"\x46\x08\xF9\x19\x88\x70\x22\x12\x78\x17\x23\x86\x0C\x06\xC2\x26\x0B\x4F\x80\x32\x3E\xB3\x19\x1C\xB0\x49\x70\xCB\x40\x52\x79\x0B",
|
|
/*exp_output_size*/ 32,
|
|
/*should_verify*/ 1
|
|
);
|
|
|
|
//TODO: test that does not verify
|
|
|
|
uint8_t* ks_enc = (uint8_t*)"\x97\x9E\xC1\x3B\x1C\xBF\xE9\xDC\xD0\x1A\xB0\xFE\xD3\x07\xEA\xE5";
|
|
uint8_t* ks_mac = (uint8_t*)"\xF1\xCB\x1F\x1F\xB5\xAD\xF2\x08\x80\x6B\x89\xDC\x57\x9D\xC1\xF8";
|
|
|
|
test_mrtd_bac_keys_from_seed(
|
|
(uint8_t*)"\x00\x36\xD2\x72\xF5\xC3\x50\xAC\xAC\x50\xC3\xF5\x72\xD2\x36\x00",
|
|
ks_enc,
|
|
ks_mac
|
|
);
|
|
|
|
uint8_t* rnd_ic = (uint8_t*)"\x46\x08\xF9\x19\x88\x70\x22\x12";
|
|
uint8_t* rnd_ifd = (uint8_t*)"\x78\x17\x23\x86\x0C\x06\xC2\x26";
|
|
|
|
uint64_t ssc = 0x887022120C06C226;
|
|
test_mrtd_ssc_from_data(rnd_ic, rnd_ifd, ssc);
|
|
|
|
ssc++;
|
|
|
|
test_mrtd_protect_apdu(0x00, 0xA4, 0x02, 0x0C, 0x02, "\x01\x1e", -1, ks_enc, ks_mac, ssc, (uint8_t*)"\x0C\xA4\x02\x0C\x15\x87\x09\x01\x63\x75\x43\x29\x08\xC0\x44\xF6\x8E\x08\xBF\x8B\x92\xD6\x35\xFF\x24\xF8\x00", 27);
|
|
|
|
ssc++; // Increment for decrypt, verify
|
|
|
|
test_mrtd_bac_decrypt_verify_sm((uint8_t*)"\x99\x02\x90\x00\x8E\x08\xFA\x85\x5A\x5D\x4C\x50\xA8\xED", 14, ks_enc, ks_mac, ssc, NULL, 0, 1);
|
|
|
|
ssc++; // Increment for encrypt, sign
|
|
|
|
test_mrtd_protect_apdu(0x00, 0xB0, 0x00, 0x00, 0x00, NULL, 0x04, ks_enc, ks_mac, ssc, (uint8_t*)"\x0C\xB0\x00\x00\x0D\x97\x01\x04\x8E\x08\xED\x67\x05\x41\x7E\x96\xBA\x55\x00", 19);
|
|
|
|
ssc++; // Increment for decrypt, verify
|
|
|
|
test_mrtd_bac_decrypt_verify_sm((uint8_t*)"\x87\x09\x01\x9F\xF0\xEC\x34\xF9\x92\x26\x51\x99\x02\x90\x00\x8E\x08\xAD\x55\xCC\x17\x14\x0B\x2D\xED", 25, ks_enc, ks_mac, ssc, (uint8_t*)"\x60\x14\x5F\x01", 4, 1);
|
|
|
|
ssc++; // Increment for encrypt, sign
|
|
|
|
test_mrtd_protect_apdu(0x00, 0xB0, 0x00, 0x04, 0x00, NULL, 0x12, ks_enc, ks_mac, ssc, (uint8_t*)"\x0C\xB0\x00\x04\x0D\x97\x01\x12\x8E\x08\x2E\xA2\x8A\x70\xF3\xC7\xB5\x35\x00", 19);
|
|
|
|
// Verify working against mrtdreader
|
|
|
|
/*
|
|
printf("=====================================\n\n");
|
|
|
|
//TODO: set auth data
|
|
MrtdAuthData auth;
|
|
auth.birth_date = TODO_REMOVE_ID_DOB;
|
|
auth.expiry_date = TODO_REMOVE_ID_DOE;
|
|
memcpy(auth.doc_number, TODO_REMOVE_ID_DOC, 9);
|
|
uint8_t kenc[16];
|
|
uint8_t kmac[16];
|
|
mrtd_bac_keys(&auth, kenc, kmac);
|
|
|
|
printf("kenc: "); print_hex(kenc, 16); printf("\n");
|
|
printf("kmac: "); print_hex(kmac, 16); printf("\n");
|
|
|
|
uint8_t buffer[32]; // RND.IC || RND.IFD || KIC
|
|
|
|
//TODO: set challenge rx
|
|
mrtd_bac_decrypt_verify((uint8_t*)"\x3F\xD4\x6B\xA9\xFF\x29\x4B\xF6\x77\x4E\x8F\x1E\xEC\xAE\x2E\x67\xDB\xE7\x70\x53\xB3\xAD\x9C\xDC\xED\x6E\xED\xD6\x04\x2E\xB7\x6B\x74\xDE\x2A\xFB\x4B\xC0\xF7\x24", 40, kenc, kmac, buffer);
|
|
//TODO: set kifd
|
|
uint8_t *kifd = "\x9F\x10\x40\xEA\x7F\xAE\xF8\xC3\x09\x6E\xAE\x07\x66\x95\x3F\xDC";
|
|
|
|
printf("buffer: "); print_hex(buffer, 32); printf("\n");
|
|
// 8F763C0B1CDF9F9D|0983F7C136155248|7A705FD193C6A6328C42264A3804002C
|
|
rnd_ic = buffer;
|
|
rnd_ifd = buffer+8;
|
|
uint8_t *kic = buffer+16;
|
|
printf("kifd: "); print_hex(kifd, 16); printf("\n");
|
|
printf("kicc: "); print_hex(kic, 16); printf("\n");
|
|
uint8_t kseed[16];
|
|
for(uint8_t i=0; i<16; ++i) {
|
|
kseed[i] = kifd[i] ^ kic[i];
|
|
printf("seed %2d = %02X ^ %02X = %02X\r\n", i, kifd[i], kic[i], kseed[i]);
|
|
}
|
|
printf("kseed: "); print_hex(kseed, 16); printf("\n");
|
|
|
|
ks_enc = malloc(16);
|
|
ks_mac = malloc(16);
|
|
mrtd_bac_keys_from_seed(kseed, ks_enc, ks_mac);
|
|
printf("ks_enc: "); print_hex(ks_enc, 16); printf("\n");
|
|
printf("ks_mac: "); print_hex(ks_mac, 16); printf("\n");
|
|
|
|
printf("rnd_ic: "); print_hex(rnd_ic, 16); printf("\n");
|
|
printf("rnd_ifd: "); print_hex(rnd_ifd, 16); printf("\n");
|
|
uint64_t ssc = mrtd_ssc_from_data(rnd_ic, rnd_ifd);
|
|
printf("ssc: %016lx", ssc);
|
|
|
|
ssc++;
|
|
|
|
//TODO: set challenge TX for verification
|
|
test_mrtd_protect_apdu(0x00, 0xA4, 0x02, 0x0C, 0x02, "\x01\x1e", -1, ks_enc, ks_mac, ssc,
|
|
(uint8_t*)"\x0C\xA4\x02\x0C\x15\x87\x09\x01\xC5\x4E\x76\x3A\xD1\x89\xF0\xFA\x8E\x08\x1F\x03\xC2\xB6\xCE\x8A\xE1\x53\x00", 27);
|
|
*/
|
|
|
|
return 0;
|
|
}
|