ADD: UL-EV1 signature printing.

CHG: @marshmellows changes.
This commit is contained in:
iceman1001 2015-05-06 14:19:23 +02:00
parent 69a2953679
commit 2b03dea768

View file

@ -21,23 +21,22 @@
#define MAX_ULEV1b_BLOCKS 0x20
#define MAX_NTAG_213 0x2c
#define MAX_NTAG_215 0x86
#define MAX_NTAG_216 0xE6
#define MAX_NTAG_216 0xe6
typedef enum TAGTYPE_UL {
UNKNOWN = 0,
UL = 1,
UL_C = 2,
UL_EV1_48 = 4,
UL_EV1_128 = 8,
NTAG = 16,
NTAG_213 = 32,
NTAG_215 = 64,
NTAG_216 = 128,
MAGIC = 256,
UNKNOWN = 0x0000,
UL = 0x0001,
UL_C = 0x0002,
UL_EV1_48 = 0x0004,
UL_EV1_128 = 0x0008,
NTAG = 0x0010,
NTAG_213 = 0x0020,
NTAG_215 = 0x0040,
NTAG_216 = 0x0080,
MAGIC = 0x0100,
UL_MAGIC = UL | MAGIC,
UL_C_MAGIC = UL_C | MAGIC,
UL_ERROR = 0xFFFF,
} TagTypeUL_t;
uint8_t default_3des_keys[7][16] = {
@ -86,9 +85,9 @@ char* getUlev1CardSizeStr( uint8_t fsize ){
// is LSB set?
if ( fsize & 1 )
sprintf(retStr, "0x%02X (%d - %d bytes)",fsize, usize, lsize);
sprintf(retStr, "0x%02X (%u - %u bytes)",fsize, usize, lsize);
else
sprintf(retStr, "0x%02X (%d bytes)", fsize, lsize);
sprintf(retStr, "0x%02X (%u bytes)", fsize, lsize);
return buf;
}
@ -109,13 +108,14 @@ static int ul_send_cmd_raw( uint8_t *cmd, uint8_t cmdlen, uint8_t *response, uin
UsbCommand resp;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1;
if (resp.arg[0] > 0) {
uint16_t resplen = (resp.arg[0] < responseLength) ? resp.arg[0] : responseLength;
if (resp.arg[0] > 0)
memcpy(response, resp.d.asBytes, resplen);
return resplen;
}
return -1;
}
/*
static int ul_send_cmd_raw_crc( uint8_t *cmd, uint8_t cmdlen, uint8_t *response, uint16_t responseLength, bool append_crc ) {
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT , cmdlen, 0}};
@ -128,25 +128,22 @@ static int ul_send_cmd_raw_crc( uint8_t *cmd, uint8_t cmdlen, uint8_t *response,
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1;
uint16_t resplen = (resp.arg[0] < responseLength) ? resp.arg[0] : responseLength;
if (resp.arg[0] > 0)
if (resp.arg[0] > 0) {
memcpy(response, resp.d.asBytes, resplen );
return resplen;
} else return -1;
}
*/
static int ul_select( iso14a_card_select_t *card ){
ul_switch_on_field();
UsbCommand resp;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
ul_switch_off_field();
return -1;
}
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1;
if (resp.arg[0] < 0) return -1;
if (resp.arg[0] > 0) {
memcpy(card, resp.d.asBytes, sizeof(iso14a_card_select_t));
}
return resp.arg[0];
}
@ -292,11 +289,11 @@ static int ul_print_type(uint16_t tagtype){
if ( tagtype & UL )
PrintAndLog(" TYPE : MIFARE Ultralight (MF0ICU1) %s", (tagtype & MAGIC)?"<magic>":"");
else if ( tagtype & UL_C)
PrintAndLog(" TYPE : MIFARE Ultralight C (MF0ULC) %s", (tagtype & MAGIC)?"<magic>":"" );
PrintAndLog(" TYPE : MIFARE Ultralight C (MF0ULC) %s [%x]", (tagtype & MAGIC)?"<magic>":"", tagtype );
else if ( tagtype & UL_EV1_48)
PrintAndLog(" TYPE : MIFARE Ultralight EV1 48bytes (MF0UL1101)");
else if ( tagtype & UL_EV1_128)
PrintAndLog(" TYPE : MIFARE Ultralight EV1 128bytes (MF0UL2101");
PrintAndLog(" TYPE : MIFARE Ultralight EV1 128bytes (MF0UL2101)");
else if ( tagtype & NTAG_213 )
PrintAndLog(" TYPE : MIFARE NTAG 213 144bytes (NT2H1311G0DU)");
else if ( tagtype & NTAG_215 )
@ -376,6 +373,17 @@ static int ulev1_print_counters(){
return 0;
}
static int ulev1_print_signature( uint8_t *data, uint8_t len){
PrintAndLog("IC signature public key name : NXP NTAG21x 2013");
PrintAndLog("IC signature public key value : 04494e1a386d3d3cfe3dc10e5de68a499b1c202db5b132393e89ed19fe5be8bc61");
PrintAndLog(" Elliptic curve parameters : secp128r1");
PrintAndLog(" Tag ECC Signature : %s", sprint_hex(data, len));
//to do: verify if signature is valid
//PrintAndLog("IC signature status: %s valid", (iseccvalid() )?"":"not");
return 0;
}
uint16_t GetHF14AMfU_Type(void){
TagTypeUL_t tagtype = UNKNOWN;
@ -389,6 +397,7 @@ uint16_t GetHF14AMfU_Type(void){
status = ul_select(&card);
if ( status < 1 ){
PrintAndLog("Error: couldn't select");
ul_switch_off_field();
return UL_ERROR;
}
@ -399,6 +408,7 @@ uint16_t GetHF14AMfU_Type(void){
}
len = ulev1_getVersion(version, sizeof(version));
ul_switch_off_field();
switch (len) {
case -1:
@ -449,6 +459,7 @@ uint16_t GetHF14AMfU_Type(void){
} else {
tagtype = UL;
}
ul_switch_off_field();
}
//PrintAndLog("ICE %d", tagtype);
@ -459,7 +470,6 @@ uint16_t GetHF14AMfU_Type(void){
//return UL_MAGIC;
}
ul_switch_off_field();
return tagtype;
}
@ -488,33 +498,32 @@ int CmdHF14AMfUInfo(const char *Cmd){
// read pages 0,1,2,4 (should read 4pages)
status = ul_read(0, data, sizeof(data));
if ( status == -1 ){
PrintAndLog("Error: tag didn't answer to READ");
PrintAndLog("Error: tag didn't answer to READ A");
ul_switch_off_field();
return status;
}
ul_print_default(data);
if ((tagtype & UL_C)){
// lookup lockbits before?
// read pages 0x28, 0x29, 0x2A, 0x2B
// tag may be locked
uint8_t ulc_conf[16] = {0x00};
status = ul_read(0x28, ulc_conf, sizeof(ulc_conf));
if ( status == -1 ){
PrintAndLog("Error: tag didn't answer to READ");
ul_switch_off_field();
return status;
PrintAndLog("Error: tag didn't answer to READ - possibly locked");
} else {
ulc_print_configuration(ulc_conf);
}
ulc_print_configuration(ulc_conf);
if ((tagtype & UL_C_MAGIC)){
if ((tagtype & MAGIC)){
uint8_t ulc_deskey[16] = {0x00};
status = ul_read(0x2C, ulc_deskey, sizeof(ulc_deskey));
if ( status == -1 ){
PrintAndLog("Error: tag didn't answer to READ");
PrintAndLog("Error: tag didn't answer to READ B");
ul_switch_off_field();
return status;
}
@ -524,6 +533,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
}
else {
PrintAndLog("Trying some default 3des keys");
ul_switch_off_field();
for (uint8_t i = 0; i < 7; ++i ){
key = default_3des_keys[i];
if (try3DesAuthentication(key) == 1){
@ -542,11 +552,10 @@ int CmdHF14AMfUInfo(const char *Cmd){
uint8_t ulev1_conf[16] = {0x00};
status = ul_read(startconfigblock, ulev1_conf, sizeof(ulev1_conf));
if ( status == -1 ){
PrintAndLog("Error: tag didn't answer to READ");
PrintAndLog("Error: tag didn't answer to READ C");
ul_switch_off_field();
return status;
}
ulev1_print_configuration(ulev1_conf);
uint8_t ulev1_signature[32] = {0x00};
@ -556,10 +565,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
ul_switch_off_field();
return status;
}
PrintAndLog(" ECC Signature : %s", sprint_hex(ulev1_signature, sizeof(ulev1_signature)));
PrintAndLog(" Verify it with the following 'secp128r1' for Elliptic curve cryptograghy in OpenSSL");
ulev1_print_signature( ulev1_signature, sizeof(ulev1_signature));
}
if ((tagtype & (UL_EV1_48 | UL_EV1_128 | NTAG_213 | NTAG_215 | NTAG_216))) {
@ -595,7 +601,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
uint8_t cc[16] = {0x00};
status = ul_read(2, cc, sizeof(cc));
if ( status == -1 ){
PrintAndLog("Error: tag didn't answer to READ");
PrintAndLog("Error: tag didn't answer to READ D");
ul_switch_off_field();
return status;
}
@ -723,6 +729,11 @@ int usage_hf_mfu_dump(void)
PrintAndLog("and saves binary dump into the file `filename.bin` or `cardUID.bin`");
PrintAndLog("It autodetects card type.\n");
PrintAndLog("Usage: hf mfu dump k <key> n <filename w/o .bin>");
PrintAndLog(" Options : ");
PrintAndLog(" k <key> : Enter key for authentication");
PrintAndLog(" n <FN > : Enter filename w/o .bin to save the dump as");
PrintAndLog(" s : Swap entered key's endianness for auth");
PrintAndLog("");
PrintAndLog(" sample : hf mfu dump");
PrintAndLog(" : hf mfu dump n myfile");
return 0;
@ -751,10 +762,11 @@ int CmdHF14AMfUDump(const char *Cmd){
bool tmplockbit = false;
uint8_t dataLen=0;
uint8_t cmdp =0;
//uint8_t key[16]= {0x00};
uint8_t *key = NULL;
uint8_t key[16] = {0x00};
uint8_t *keyPtr = key;
size_t fileNlen = 0;
bool errors = FALSE;
bool errors = false;
bool swapEndian = false;
while(param_getchar(Cmd, cmdp) != 0x00)
{
@ -769,9 +781,7 @@ int CmdHF14AMfUDump(const char *Cmd){
if (dataLen) {
errors = true;
} else {
//memcpy(key, data, 16);
key = SwapEndian64(data, 16);
PrintAndLog("3des key: %s",sprint_hex(key, 16));
memcpy(key, data, 16);
}
cmdp += 2;
hasPwd = true;
@ -783,6 +793,9 @@ int CmdHF14AMfUDump(const char *Cmd){
if (fileNlen > FILE_PATH_SIZE-5) fileNlen = FILE_PATH_SIZE-5;
cmdp += 2;
break;
case 's':
swapEndian = true;
cmdp++;
default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
@ -794,6 +807,9 @@ int CmdHF14AMfUDump(const char *Cmd){
//Validations
if(errors) return usage_hf_mfu_dump();
if (swapEndian)
keyPtr = SwapEndian64(data, 16);
TagTypeUL_t tagtype = GetHF14AMfU_Type();
if (tagtype == UL_ERROR) return -1;
@ -828,7 +844,7 @@ int CmdHF14AMfUDump(const char *Cmd){
PrintAndLog("Command execute time-out");
return 1;
}
PrintAndLog ("%u,%u",resp.arg[0],resp.arg[1]);
uint8_t isOK = resp.arg[0] & 0xff;
if (isOK) {
memcpy(data, resp.d.asBytes, resp.arg[1]);
@ -1159,11 +1175,11 @@ int CmdHF14AMfUCRdBl(const char *Cmd)
UsbCommand resp;
bool hasPwd = FALSE;
uint8_t blockNo = -1;
unsigned char key[16];
uint8_t key[16];
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: hf mfu crdbl <block number> <password>");
PrintAndLog("Usage: hf mfu crdbl <block number> <key>");
PrintAndLog("");
PrintAndLog("sample: hf mfu crdbl 0");
PrintAndLog(" hf mfu crdbl 0 00112233445566778899AABBCCDDEEFF");
@ -1255,6 +1271,7 @@ int CmdHF14AMfUCWrBl(const char *Cmd){
if ( blockNo <= 3 ) {
if (!chinese_card){
PrintAndLog("Access Denied");
return 1;
} else {
PrintAndLog("--Special block no: 0x%02x", blockNo);
PrintAndLog("--Data: %s", sprint_hex(bldata, 4));
@ -1266,6 +1283,7 @@ int CmdHF14AMfUCWrBl(const char *Cmd){
PrintAndLog("isOk:%02x", isOK);
} else {
PrintAndLog("Command execute timeout");
return 1;
}
}
} else {
@ -1279,6 +1297,7 @@ int CmdHF14AMfUCWrBl(const char *Cmd){
PrintAndLog("isOk : %02x", isOK);
} else {
PrintAndLog("Command execute timeout");
return 1;
}
}
return 0;