fix one too small
[RRG-proxmark3.git] / client / src / cmdhfict.c
blobfdfbb97e7e4fb035db6513aa068e074b3432ccde
1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
16 // SEOS commands
17 //-----------------------------------------------------------------------------
18 #include "cmdhfict.h"
19 #include <ctype.h> // tolower
20 #include <stdio.h>
21 #include <string.h>
23 #include "cliparser.h"
24 #include "cmdparser.h" // command_t
25 #include "comms.h" // clearCommandBuffer
26 #include "commonutil.h" // get_sw
27 #include "cmdhf14a.h" // manufacture
28 #include "cmdhfmf.h" // mf_print_sector
29 #include "cmdtrace.h"
30 #include "protocols.h" // definitions of ISO14A/7816 protocol
31 #include "iso7816/apduinfo.h" // GetAPDUCodeDescription
32 #include "protocols.h" // ISO7816 APDU return codes
33 #include "mifare/mifaredefault.h" // AES_KEY_LEN
34 #include "mifare/mifare4.h"
35 #include <mbedtls/aes.h>
36 #include <mbedtls/cmac.h>
37 //#include <mbedtls/entropy.h>
38 #include <mbedtls/error.h>
39 #include "ui.h"
41 static int CmdHelp(const char *Cmd);
44 // missing
45 #define ICT_DESFIRE_FILEKEY "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
46 #define ICT_DESFIRE_MASTER_APPKEY "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
47 #define ICT_BLE_DEFAULT_BASE_KEY "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
49 #define ICT_MIFARE_SECTOR 14
50 #define ICT_APP_ID 0x1023f5
51 #define ICT_REV_APP_ID 0xf52310
52 #define ICT_FILE_ID 0
53 #define ICT_FILE_SIZE 128
55 #define ICT_CT_DESFIRE 0
56 #define ICT_CT_CLASSIC 1
57 #define ICT_CT_NFC 2
59 static const uint8_t ICT_MIFARE_A_KEY[] = {0x9c, 0x28, 0xa6, 0x0f, 0x72, 0x49};
60 static const uint8_t ICT_MIFARE_B_KEY[] = {0xc9, 0x82, 0x6a, 0xf0, 0x27, 0x94};
62 static int derive_ble_key(uint8_t *unique_data, uint8_t len, uint8_t *app_key) {
64 if (unique_data == NULL || app_key == NULL) {
65 return PM3_EINVARG;
68 uint8_t input[1 + len];
69 input[0] = 0x01;
70 memcpy(input + 1, unique_data, len);
72 uint8_t mac[16];
73 memset(mac, 0x00, 16);
75 uint8_t key[AES_KEY_LEN];
76 memcpy(key, ICT_BLE_DEFAULT_BASE_KEY, sizeof(key));
78 // NIST 800-38B
79 mbedtls_aes_cmac_prf_128(key, MBEDTLS_AES_BLOCK_SIZE, input, sizeof(input), mac);
81 memcpy(app_key, mac, sizeof(mac));
82 return PM3_SUCCESS;
85 static int derive_app_key(uint8_t *uid, uint8_t *app_key) {
86 if (uid == NULL || app_key == NULL) {
87 return PM3_EINVARG;
91 c = b'\x88' + uid
92 ch, cl = c[0:4], c[4:8]
93 payload = (ch + cl + cl + ch) * 2
94 AES.new(ICT_DESFIRE_MASTER_APPKEY, AES.MODE_CBC, iv=b'\0'*16).decrypt(payload)[16:]
96 uint8_t input[] = {0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
97 memcpy(input + 1, uid, 7);
99 // uint32_t ch = bytes_to_num(input, 4);
100 // uint32_t cl = bytes_to_num(input + 4, 4);
101 // uint64_t payload = ((2 * ch) + (2 * cl) * 2);
103 uint8_t key[AES_KEY_LEN];
104 memcpy(key, ICT_DESFIRE_MASTER_APPKEY, AES_KEY_LEN);
106 uint8_t iv[16] = {0};
107 mbedtls_aes_context aes;
108 mbedtls_aes_init(&aes);
109 if (mbedtls_aes_setkey_enc(&aes, key, 128)) {
110 return PM3_ESOFT;
113 uint8_t output[8];
114 if (mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, sizeof(input), iv, input, output)) {
115 return PM3_ESOFT;
117 mbedtls_aes_free(&aes);
118 memcpy(app_key, output, sizeof(output));
119 return PM3_SUCCESS;
122 // Might miss payload..
123 static int diversify_mifare_key(const uint8_t *uid, uint8_t *app_key) {
124 if (uid == NULL || app_key == NULL) {
125 return PM3_EINVARG;
128 uint8_t input[8];
129 memcpy(input, uid, 4);
131 uint32_t big = bytes_to_num(uid, 4);
132 big ^= 0xFFFFFFFF;
133 num_to_bytes(big, 4, input + 4);
135 uint8_t key[AES_KEY_LEN];
136 memset(key, 0, sizeof(key));
137 // memcpy(key, ICT_DESFIRE_FILEKEY, AES_KEY_LEN);
139 uint8_t iv[16] = {0};
140 mbedtls_aes_context aes;
141 mbedtls_aes_init(&aes);
142 if (mbedtls_aes_setkey_enc(&aes, key, 128)) {
143 return PM3_ESOFT;
146 uint8_t output[8];
147 if (mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, sizeof(input), iv, input, output)) {
148 return PM3_ESOFT;
150 mbedtls_aes_free(&aes);
151 memcpy(app_key, output, sizeof(output));
152 return PM3_SUCCESS;
155 static int decrypt_card_sector(uint8_t *uid, const uint8_t *sector_data, uint8_t len, uint8_t *plain) {
156 if (uid == NULL || sector_data == NULL || plain == NULL) {
157 return PM3_EINVARG;
160 uint8_t input[len];
161 memcpy(input, sector_data, len);
163 uint8_t key[AES_KEY_LEN];
164 diversify_mifare_key(uid, key);
166 uint8_t iv[16] = {0};
167 mbedtls_aes_context aes;
168 mbedtls_aes_init(&aes);
169 if (mbedtls_aes_setkey_enc(&aes, key, 128)) {
170 return PM3_ESOFT;
173 uint8_t output[len];
174 if (mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, sizeof(input), iv, input, output)) {
175 return PM3_ESOFT;
177 mbedtls_aes_free(&aes);
179 memcpy(plain, output, sizeof(output));
180 return PM3_SUCCESS;
183 static int derive_mifare_key(uint8_t *uid, const uint8_t *base_key, uint8_t *app_key) {
184 if (uid == NULL || base_key == NULL || app_key == NULL) {
185 return PM3_EINVARG;
188 uint8_t diverse[MIFARE_KEY_SIZE];
189 diversify_mifare_key(uid, diverse);
191 for (uint8_t i = 0; i < MIFARE_KEY_SIZE; i++) {
192 app_key[i] = base_key[i] ^ diverse[i];
195 return PM3_SUCCESS;
198 static int derive_mifare_key_a(uint8_t *uid, uint8_t *app_key) {
199 return derive_mifare_key(uid, ICT_MIFARE_A_KEY, app_key);
202 static int derive_mifare_key_b(uint8_t *uid, uint8_t *app_key) {
203 return derive_mifare_key(uid, ICT_MIFARE_B_KEY, app_key);
206 static int decrypt_card_file(const uint8_t *card_file, uint8_t len, uint8_t *plain) {
207 if (card_file == NULL || plain == NULL) {
208 return PM3_EINVARG;
211 uint8_t input[ICT_FILE_SIZE];
212 memcpy(input, card_file, len);
214 uint8_t key[AES_KEY_LEN] = {0};
215 // memcpy(key, ICT_DESFIRE_FILEKEY, AES_KEY_LEN);
217 uint8_t iv[16] = {0};
218 mbedtls_aes_context aes;
219 mbedtls_aes_init(&aes);
220 if (mbedtls_aes_setkey_enc(&aes, key, 128)) {
221 return PM3_ESOFT;
224 uint8_t output[ICT_FILE_SIZE];
225 if (mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, ICT_FILE_SIZE, iv, input, output)) {
226 return PM3_ESOFT;
228 mbedtls_aes_free(&aes);
229 memcpy(plain, output, sizeof(output));
230 return PM3_SUCCESS;
233 static int encrypt_card_file(const uint8_t *card_file, uint8_t len, bool padding, uint8_t *enc) {
235 if (len > ICT_FILE_SIZE) {
236 return PM3_EINVARG;
239 uint8_t input[ICT_FILE_SIZE];
240 memcpy(input, card_file, len);
242 if (padding) {
243 memset(input + len, 0x4C, 128 - len);
246 uint8_t key[AES_KEY_LEN] = {0};
247 // memcpy(key, ICT_DESFIRE_FILEKEY, AES_KEY_LEN);
249 uint8_t iv[16] = {0};
250 mbedtls_aes_context aes;
251 mbedtls_aes_init(&aes);
252 if (mbedtls_aes_setkey_enc(&aes, key, 128)) {
253 return PM3_ESOFT;
256 uint8_t output[ICT_FILE_SIZE];
257 if (mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, ICT_FILE_SIZE, iv, input, output)) {
258 return PM3_ESOFT;
260 mbedtls_aes_free(&aes);
261 memcpy(enc, output, sizeof(output));
262 return PM3_SUCCESS;
265 static void itc_decode_card_blob(const uint8_t *data, uint8_t card_type) {
266 if (data == NULL) {
267 return;
270 uint8_t block[16];
271 if (card_type == ICT_CT_NFC)
272 memcpy(block, data+16, sizeof(block));
273 else
274 memcpy(block, data, sizeof(block));
276 uint8_t bit_count = data[8];
278 uint8_t wiegand[32];
280 if (card_type == ICT_CT_DESFIRE || card_type == ICT_CT_NFC) {
281 memcpy(wiegand, data + 11, 32-11);
284 if (card_type == ICT_CT_CLASSIC) {
285 memcpy(wiegand, data + 9, 32-9);
288 if (bit_count == 26) {
289 fc, cn = decode_wiegand_26(wiegand_payload)
290 ct = "Wiegand 26-bit"
292 if (bit_count == 34) {
293 fc, cn = decode_wiegand_34(wiegand_payload)
294 ct = "Wiegand 34-bit"
295 }else {
296 return f"Unknown format (bitlength={bit_count})", None, None
299 return ct, fc, cn
302 static void itc_encode_card_blob(uint8_t facility_code, uint16_t card_number, uint8_t bit_count) {
304 // encode wiegand ..
305 uint8_t wiegand[] = {0,0,0,0,0};
306 if (bit_count == 26) {
307 // wiegand_data = encode_wiegand_26(facility_code, card_number)
309 if (bit_count == 34) {
310 // wiegand_data = encode_wiegand_34(facility_code, card_number)
313 // card binary blog
314 uint8_t blob[] = {
315 '@', 'I', 'C', 'T', 0x00, 0x80, 0x00, 0x00, bit_count, 0x00, bit_count
317 // return b'@ICT' + bytes([0,128,0,0,bit_count, 0, bit_count]) + wiegand_data
321 static int ict_select(void) {
322 bool activate_field = true;
323 bool keep_field_on = true;
324 uint8_t response[PM3_CMD_DATA_SIZE];
325 int resplen = 0;
327 // --------------- Select SEOS applet ----------------
328 uint8_t aSELECT_AID[80];
329 int aSELECT_AID_n = 0;
330 param_gethex_to_eol("00a404000aa000000440000101000100", 0, aSELECT_AID, sizeof(aSELECT_AID), &aSELECT_AID_n);
331 int res = ExchangeAPDU14a(aSELECT_AID, aSELECT_AID_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
332 if (res != PM3_SUCCESS) {
333 DropField();
334 return res;
337 if (resplen < 2) {
338 DropField();
339 return PM3_ESOFT;
342 uint16_t sw = get_sw(response, resplen);
343 if (sw != ISO7816_OK) {
344 PrintAndLogEx(ERR, "Selecting SEOS applet aid failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
345 DropField();
346 return PM3_ESOFT;
349 activate_field = false;
350 keep_field_on = false;
351 // --------------- CC file reading ----------------
353 uint8_t aSELECT_FILE_ADF[30];
354 int aSELECT_FILE_ADF_n = 0;
355 param_gethex_to_eol("80a504001306112b0601040181e43801010201180101020200", 0, aSELECT_FILE_ADF, sizeof(aSELECT_FILE_ADF), &aSELECT_FILE_ADF_n);
356 res = ExchangeAPDU14a(aSELECT_FILE_ADF, aSELECT_FILE_ADF_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
357 if (res != PM3_SUCCESS) {
358 DropField();
359 return res;
362 sw = get_sw(response, resplen);
363 if (sw != ISO7816_OK) {
364 PrintAndLogEx(ERR, "Selecting ADF file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
365 DropField();
366 return PM3_ESOFT;
369 return PM3_SUCCESS;
372 int infoICT(bool verbose) {
373 int res = ict_select();
374 if (res == PM3_SUCCESS) {
375 PrintAndLogEx(NORMAL, "");
376 PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------");
378 return PM3_SUCCESS;
381 static int CmdHfIctInfo(const char *Cmd) {
382 CLIParserContext *ctx;
383 CLIParserInit(&ctx, "hf ict info",
384 "Get info from ICT encoded credential tags (MIFARE Classic / DESfire)",
385 "hf ict info");
387 void *argtable[] = {
388 arg_param_begin,
389 arg_param_end
391 CLIExecWithReturn(ctx, Cmd, argtable, true);
392 CLIParserFree(ctx);
393 return infoICT(true);
396 static int ict_select_card(iso14a_card_select_t *card) {
397 if (card == NULL) {
398 return PM3_EINVARG;
401 clearCommandBuffer();
402 SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0);
403 PacketResponseNG resp;
404 if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) {
405 return PM3_ESOFT;
409 0: couldn't read
410 1: OK, with ATS
411 2: OK, no ATS
412 3: proprietary Anticollision
414 uint64_t select_status = resp.oldarg[0];
415 if (select_status == 0) {
416 return PM3_ESOFT;
419 memcpy(card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t));
420 return PM3_SUCCESS;
423 static int CmdHfIctReader(const char *Cmd) {
424 CLIParserContext *ctx;
425 CLIParserInit(&ctx, "hf ict reader",
426 "Act as a reader",
427 "hf ict reader\n"
429 void *argtable[] = {
430 arg_param_begin,
431 arg_param_end
433 CLIExecWithReturn(ctx, Cmd, argtable, true);
434 CLIParserFree(ctx);
436 iso14a_card_select_t card;
437 if (ict_select_card(&card) != PM3_SUCCESS) {
438 return PM3_ESOFT;
441 PrintAndLogEx(INFO, "UID... %s", sprint_hex_inrow(card.uid, card.uidlen));
442 // MFC actions
443 uint8_t uid[4] = {0x04, 0x01, 0x02, 0x03};
444 uint8_t key[MIFARE_KEY_SIZE] = {0};
445 derive_mifare_key_a(card.uid, key);
446 PrintAndLogEx(INFO, "Derived KEY A... %s", sprint_hex_inrow(key, MIFARE_KEY_SIZE));
448 memset(key, 0, sizeof(key));
449 derive_mifare_key_b(card.uid, key);
450 PrintAndLogEx(INFO, "Derived KEY B... %s", sprint_hex_inrow(key, MIFARE_KEY_SIZE));
452 uint8_t encsector[48] = {0};
453 uint8_t plainsector[48] = {0};
454 decrypt_card_sector(uid, encsector, sizeof(encsector), plainsector);
456 // DESFIRE Actions
457 uint8_t aeskey[AES_KEY_LEN] = {0};
458 uint8_t desfireuid[7] = {0x04, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
459 derive_app_key(desfireuid, aeskey);
461 uint8_t uniquedata[16] = {0};
462 derive_ble_key(uniquedata, sizeof(uniquedata), aeskey);
464 uint8_t encdata[ICT_FILE_SIZE] = {0};
465 uint8_t plaindata[ICT_FILE_SIZE] = {0};
466 decrypt_card_file(encdata, sizeof(encdata), plaindata);
467 encrypt_card_file(plaindata, sizeof(plaindata), true, encdata);
469 // blob actions
470 uint8_t mfcblob[48] = {0};
471 itc_decode_card_blob(mfcblob, ICT_CT_CLASSIC);
472 itc_encode_card_blob(101, 1337, 26);
474 return PM3_SUCCESS;
477 static int CmdHfIctCredential(const char *Cmd) {
479 CLIParserContext *ctx;
480 CLIParserInit(&ctx, "hf ict credential",
481 "Read ICT sector from tag and decode",
482 "hf ict credential\n"
484 void *argtable[] = {
485 arg_param_begin,
486 arg_lit0("v", "verbose", "verbose output"),
487 arg_param_end
489 CLIExecWithReturn(ctx, Cmd, argtable, true);
490 bool verbose = arg_get_lit(ctx, 1);
491 CLIParserFree(ctx);
493 SetAPDULogging(false);
494 DropField();
496 iso14a_card_select_t card;
497 if (ict_select_card(&card) != PM3_SUCCESS) {
498 return PM3_ESOFT;
501 bool isdesfire = false;
502 if ((card.sak & 0x24) == 0x24) {
503 isdesfire = true;
504 } else if ((card.sak & 0x20) == 0x20) {
505 if (card.atqa[0] == 0x003 && card.atqa[1] == 0x40) {
506 isdesfire = true;
510 if (isdesfire) {
512 // read file in desfire application
513 // add decrypt sector
515 } else {
516 uint16_t sc_size = mfNumBlocksPerSector(ICT_MIFARE_SECTOR) * MFBLOCK_SIZE;
517 uint8_t *data = calloc(sc_size, sizeof(uint8_t));
518 if (data == NULL) {
519 PrintAndLogEx(ERR, "failed to allocate memory");
520 return PM3_EMALLOC;
523 // diversified key A?
524 int res = mfReadSector(ICT_MIFARE_SECTOR, MF_KEY_A, ICT_MIFARE_A_KEY, data);
525 if (res != PM3_SUCCESS) {
526 free(data);
527 return res;
529 uint8_t blocks = mfNumBlocksPerSector(ICT_MIFARE_SECTOR);
530 uint8_t start = mfFirstBlockOfSector(ICT_MIFARE_SECTOR);
532 mf_print_sector_hdr(ICT_MIFARE_SECTOR);
533 for (int i = 0; i < blocks; i++) {
534 mf_print_block_one(start + i, data + (i * MFBLOCK_SIZE), verbose);
537 // add decrypt sector
539 free(data);
541 return PM3_SUCCESS;
544 static int CmdHfIctList(const char *Cmd) {
545 return CmdTraceListAlias(Cmd, "hf ict", "14a -c");
548 static command_t CommandTable[] = {
549 {"help", CmdHelp, AlwaysAvailable, "This help"},
550 {"credential", CmdHfIctCredential, IfPm3Iso14443a, "Read ICT credential and decode"},
551 {"info", CmdHfIctInfo, IfPm3Iso14443a, "Tag information"},
552 {"list", CmdHfIctList, AlwaysAvailable, "List ICT history"},
553 {"reader", CmdHfIctReader, AlwaysAvailable, "Act like an IS14443-a reader"},
554 {NULL, NULL, NULL, NULL}
557 static int CmdHelp(const char *Cmd) {
558 (void)Cmd; // Cmd is not used so far
559 CmdsHelp(CommandTable);
560 return PM3_SUCCESS;
563 int CmdHFICT(const char *Cmd) {
564 clearCommandBuffer();
565 return CmdsParse(CommandTable, Cmd);