fix little endian vs big endian in the macros... again... but this time correct
[RRG-proxmark3.git] / client / src / emv / emv_pki.c
blob456e2960ac21791943b16a9d5f263e186da6bf3e
1 /*
2 * libopenemv - a library to work with EMV family of smart cards
3 * Copyright (C) 2015 Dmitry Eremin-Solenikov
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
16 #ifdef HAVE_CONFIG_H
17 #include <config.h>
18 #endif
20 #include "emv_pki.h"
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdarg.h>
26 #include "crypto.h"
27 #include "util.h"
28 #include "ui.h"
30 static bool strictExecution = true;
31 void PKISetStrictExecution(bool se) {
32 strictExecution = se;
35 static const unsigned char empty_tlv_value[] = {};
36 static const struct tlv empty_tlv = {.tag = 0x0, .len = 0, .value = empty_tlv_value};
38 static size_t emv_pki_hash_psn[256] = { 0, 0, 11, 2, 17, 2, };
40 static unsigned char *emv_pki_decode_message(const struct emv_pk *enc_pk,
41 uint8_t msgtype,
42 size_t *len,
43 const struct tlv *cert_tlv,
44 int tlv_count,
45 ... /* A list of tlv pointers */
46 ) {
47 struct crypto_pk *kcp;
48 unsigned char *data;
49 size_t data_len;
50 va_list vl;
52 if (!enc_pk)
53 return NULL;
55 if (!cert_tlv) {
56 PrintAndLogEx(WARNING, "ERROR: Can't find certificate");
57 return NULL;
60 if (cert_tlv->len != enc_pk->mlen) {
61 PrintAndLogEx(WARNING, "ERROR: Certificate length (%zu) not equal key length (%zu)", cert_tlv->len, enc_pk->mlen);
62 return NULL;
64 kcp = crypto_pk_open(enc_pk->pk_algo,
65 enc_pk->modulus, enc_pk->mlen,
66 enc_pk->exp, enc_pk->elen);
67 if (!kcp)
68 return NULL;
70 data = crypto_pk_encrypt(kcp, cert_tlv->value, cert_tlv->len, &data_len);
71 crypto_pk_close(kcp);
73 /* if (true){
74 PrintAndLogEx(SUCCESS, "Recovered data:\n");
75 print_buffer(data, data_len, 1);
76 }*/
78 if (data[data_len - 1] != 0xbc || data[0] != 0x6a || data[1] != msgtype) {
79 PrintAndLogEx(WARNING, "ERROR: Certificate format");
80 free(data);
81 return NULL;
84 size_t hash_pos = emv_pki_hash_psn[msgtype];
85 if (hash_pos == 0 || hash_pos > data_len) {
86 PrintAndLogEx(WARNING, "ERROR: Cant get hash position in the certificate");
87 free(data);
88 return NULL;
91 struct crypto_hash *ch;
92 ch = crypto_hash_open(data[hash_pos]);
93 if (!ch) {
94 PrintAndLogEx(WARNING, "ERROR: Cant do hash");
95 free(data);
96 return NULL;
99 size_t hash_len = crypto_hash_get_size(ch);
100 crypto_hash_write(ch, data + 1, data_len - 2 - hash_len);
102 va_start(vl, tlv_count);
103 for (int i = 0; i < tlv_count; i++) {
104 const struct tlv *add_tlv = va_arg(vl, const struct tlv *);
105 if (!add_tlv)
106 continue;
108 crypto_hash_write(ch, add_tlv->value, add_tlv->len);
110 va_end(vl);
112 uint8_t hash[hash_len];
113 memset(hash, 0, hash_len);
114 memcpy(hash, crypto_hash_read(ch), hash_len);
115 if (memcmp(data + data_len - 1 - hash_len, hash, hash_len)) {
116 PrintAndLogEx(WARNING, "ERROR: Calculated wrong hash");
117 PrintAndLogEx(WARNING, "decoded: " _YELLOW_("%s"), sprint_hex(data + data_len - 1 - hash_len, hash_len));
118 PrintAndLogEx(WARNING, "calculated: " _YELLOW_("%s"), sprint_hex(hash, hash_len));
120 if (strictExecution) {
121 crypto_hash_close(ch);
122 free(data);
123 return NULL;
127 crypto_hash_close(ch);
128 *len = data_len - hash_len - 1;
129 return data;
132 static unsigned emv_cn_length(const struct tlv *tlv) {
133 for (int i = 0; i < tlv->len; i++) {
134 unsigned char c = tlv->value[i];
136 if (c >> 4 == 0xf)
137 return 2 * i;
139 if ((c & 0xf) == 0xf)
140 return 2 * i + 1;
142 return 2 * tlv->len;
145 static unsigned char emv_cn_get(const struct tlv *tlv, unsigned pos) {
146 if (pos > tlv->len * 2)
147 return 0xf;
149 unsigned char c = tlv->value[pos / 2];
151 if (pos % 2)
152 return c & 0xf;
153 else
154 return c >> 4;
157 static struct emv_pk *emv_pki_decode_key_ex(const struct emv_pk *enc_pk,
158 unsigned char msgtype,
159 const struct tlv *pan_tlv,
160 const struct tlv *cert_tlv,
161 const struct tlv *exp_tlv,
162 const struct tlv *rem_tlv,
163 const struct tlv *add_tlv,
164 const struct tlv *sdatl_tlv,
165 bool showData
167 size_t pan_length;
168 unsigned char *data;
169 size_t data_len;
170 size_t pk_len;
172 if (!cert_tlv || !exp_tlv || !pan_tlv)
173 return NULL;
175 if (!rem_tlv)
176 rem_tlv = &empty_tlv;
178 if (msgtype == 2)
179 pan_length = 4;
180 else if (msgtype == 4)
181 pan_length = 10;
182 else {
183 PrintAndLogEx(WARNING, "ERROR: Message type must be 2 or 4");
184 return NULL;
187 data = emv_pki_decode_message(enc_pk, msgtype, &data_len,
188 cert_tlv,
190 rem_tlv,
191 exp_tlv,
192 add_tlv,
193 sdatl_tlv,
194 NULL);
195 if (!data || data_len < 11 + pan_length) {
196 PrintAndLogEx(WARNING, "ERROR: Can't decode message");
197 return NULL;
200 if (showData) {
201 PrintAndLogEx(SUCCESS, "Recovered data:");
202 print_buffer(data, data_len, 1);
205 /* Perform the rest of checks here */
207 struct tlv pan2_tlv = {
208 .tag = 0x5a,
209 .len = pan_length,
210 .value = &data[2],
212 unsigned pan_len = emv_cn_length(pan_tlv);
213 unsigned pan2_len = emv_cn_length(&pan2_tlv);
215 if (((msgtype == 2) && (pan2_len < 4 || pan2_len > pan_len)) ||
216 ((msgtype == 4) && (pan2_len != pan_len))) {
217 PrintAndLogEx(WARNING, "ERROR: Invalid PAN lengths");
218 free(data);
220 return NULL;
223 unsigned i;
224 for (i = 0; i < pan2_len; i++)
225 if (emv_cn_get(pan_tlv, i) != emv_cn_get(&pan2_tlv, i)) {
226 PrintAndLogEx(WARNING, "ERROR: PAN data mismatch");
227 PrintAndLogEx(WARNING, "tlv pan " _YELLOW_("%s"), sprint_hex(pan_tlv->value, pan_tlv->len));
228 PrintAndLogEx(WARNING, "cert pan " _YELLOW_("%s"), sprint_hex(pan2_tlv.value, pan2_tlv.len));
229 free(data);
231 return NULL;
234 pk_len = data[9 + pan_length];
235 if (pk_len > data_len - 11 - pan_length + rem_tlv->len) {
236 PrintAndLogEx(WARNING, "ERROR: Invalid pk length");
237 free(data);
238 return NULL;
241 if (exp_tlv->len != data[10 + pan_length]) {
242 free(data);
243 return NULL;
246 struct emv_pk *pk = emv_pk_new(pk_len, exp_tlv->len);
248 memcpy(pk->rid, enc_pk->rid, 5);
249 pk->index = enc_pk->index;
251 pk->hash_algo = data[7 + pan_length];
252 pk->pk_algo = data[8 + pan_length];
253 pk->expire = (data[3 + pan_length] << 16) | (data[2 + pan_length] << 8) | 0x31;
254 memcpy(pk->serial, data + 4 + pan_length, 3);
255 memcpy(pk->pan, data + 2, pan_length);
256 memset(pk->pan + pan_length, 0xff, 10 - pan_length);
258 memcpy(pk->modulus, data + 11 + pan_length,
259 pk_len < data_len - (11 + pan_length) ?
260 pk_len :
261 data_len - (11 + pan_length));
262 memcpy(pk->modulus + data_len - (11 + pan_length), rem_tlv->value, rem_tlv->len);
263 memcpy(pk->exp, exp_tlv->value, exp_tlv->len);
265 free(data);
266 return pk;
269 static struct emv_pk *emv_pki_decode_key(const struct emv_pk *enc_pk,
270 unsigned char msgtype,
271 const struct tlv *pan_tlv,
272 const struct tlv *cert_tlv,
273 const struct tlv *exp_tlv,
274 const struct tlv *rem_tlv,
275 const struct tlv *add_tlv,
276 const struct tlv *sdatl_tlv
278 return emv_pki_decode_key_ex(enc_pk, msgtype, pan_tlv, cert_tlv, exp_tlv, rem_tlv, add_tlv, sdatl_tlv, false);
281 struct emv_pk *emv_pki_recover_issuer_cert(const struct emv_pk *pk, struct tlvdb *db) {
282 return emv_pki_decode_key(pk, 2,
283 tlvdb_get(db, 0x5a, NULL),
284 tlvdb_get(db, 0x90, NULL),
285 tlvdb_get(db, 0x9f32, NULL),
286 tlvdb_get(db, 0x92, NULL),
287 NULL,
288 NULL);
291 struct emv_pk *emv_pki_recover_icc_cert(const struct emv_pk *pk, struct tlvdb *db, const struct tlv *sda_tlv) {
292 size_t sdatl_len;
293 unsigned char *sdatl = emv_pki_sdatl_fill(db, &sdatl_len);
294 struct tlv sda_tdata = {
295 .tag = 0x00, // dummy tag
296 .len = sdatl_len,
297 .value = sdatl
300 struct emv_pk *res = emv_pki_decode_key(pk, 4,
301 tlvdb_get(db, 0x5a, NULL),
302 tlvdb_get(db, 0x9f46, NULL),
303 tlvdb_get(db, 0x9f47, NULL),
304 tlvdb_get(db, 0x9f48, NULL),
305 sda_tlv,
306 &sda_tdata);
308 free(sdatl); // malloc here: emv_pki_sdatl_fill
309 return res;
312 struct emv_pk *emv_pki_recover_icc_pe_cert(const struct emv_pk *pk, struct tlvdb *db) {
313 return emv_pki_decode_key(pk, 4,
314 tlvdb_get(db, 0x5a, NULL),
315 tlvdb_get(db, 0x9f2d, NULL),
316 tlvdb_get(db, 0x9f2e, NULL),
317 tlvdb_get(db, 0x9f2f, NULL),
318 NULL,
319 NULL);
322 unsigned char *emv_pki_sdatl_fill(const struct tlvdb *db, size_t *sdatl_len) {
323 uint8_t buf[2048] = {0};
324 size_t len = 0;
326 *sdatl_len = 0;
328 const struct tlv *sda_tl = tlvdb_get(db, 0x9f4a, NULL);
329 if (!sda_tl || sda_tl->len == 0)
330 return NULL;
332 for (int i = 0; i < sda_tl->len; i++) {
333 uint32_t tag = sda_tl->value[i]; // here may be multibyte, but now not
334 const struct tlv *elm = tlvdb_get(db, tag, NULL);
335 if (elm) {
336 memcpy(&buf[len], elm->value, elm->len);
337 len += elm->len;
341 if (len) {
342 *sdatl_len = len;
343 unsigned char *value = malloc(len);
344 memcpy(value, buf, len);
345 return value;
348 return NULL;
351 struct tlvdb *emv_pki_recover_dac_ex(const struct emv_pk *enc_pk, const struct tlvdb *db, const struct tlv *sda_tlv, bool showData) {
352 size_t data_len = 0;
354 // Static Data Authentication Tag List
355 size_t sdatl_len;
356 unsigned char *sdatl = emv_pki_sdatl_fill(db, &sdatl_len);
357 struct tlv sda_tdata = {
358 .tag = 0x00, // dummy tag
359 .len = sdatl_len,
360 .value = sdatl
363 unsigned char *data = emv_pki_decode_message(enc_pk, 3, &data_len,
364 tlvdb_get(db, 0x93, NULL),
366 sda_tlv,
367 &sda_tdata,
368 NULL);
370 free(sdatl); // malloc here: emv_pki_sdatl_fill
372 if (!data || data_len < 5)
373 return NULL;
375 if (showData) {
376 PrintAndLogEx(SUCCESS, "Recovered data:");
377 print_buffer(data, data_len, 1);
380 struct tlvdb *dac_db = tlvdb_fixed(0x9f45, 2, data + 3);
381 free(data);
382 return dac_db;
385 struct tlvdb *emv_pki_recover_dac(const struct emv_pk *enc_pk, const struct tlvdb *db, const struct tlv *sda_tlv) {
386 return emv_pki_recover_dac_ex(enc_pk, db, sda_tlv, false);
389 struct tlvdb *emv_pki_recover_idn(const struct emv_pk *enc_pk, const struct tlvdb *db, const struct tlv *dyn_tlv) {
390 return emv_pki_recover_idn_ex(enc_pk, db, dyn_tlv, false);
393 struct tlvdb *emv_pki_recover_idn_ex(const struct emv_pk *enc_pk, const struct tlvdb *db, const struct tlv *dyn_tlv, bool showData) {
394 size_t data_len;
395 unsigned char *data = emv_pki_decode_message(enc_pk, 5, &data_len,
396 tlvdb_get(db, 0x9f4b, NULL),
398 dyn_tlv,
399 NULL);
401 if (!data || data_len < 3)
402 return NULL;
404 if (data[3] < 2 || data[3] > data_len - 3) {
405 free(data);
406 return NULL;
409 if (showData) {
410 PrintAndLogEx(SUCCESS, "Recovered data:");
411 print_buffer(data, data_len, 1);
414 size_t idn_len = data[4];
415 if (idn_len > data[3] - 1) {
416 free(data);
417 return NULL;
420 // 9f4c ICC Dynamic Number
421 struct tlvdb *idn_db = tlvdb_fixed(0x9f4c, idn_len, data + 5);
422 free(data);
423 return idn_db;
426 struct tlvdb *emv_pki_recover_atc_ex(const struct emv_pk *enc_pk, const struct tlvdb *db, bool showData) {
427 size_t data_len;
428 unsigned char *data = emv_pki_decode_message(enc_pk, 5, &data_len,
429 tlvdb_get(db, 0x9f4b, NULL),
431 tlvdb_get(db, 0x9f37, NULL),
432 tlvdb_get(db, 0x9f02, NULL),
433 tlvdb_get(db, 0x5f2a, NULL),
434 tlvdb_get(db, 0x9f69, NULL),
435 NULL);
437 if (!data || data_len < 3)
438 return NULL;
440 if (data[3] < 2 || data[3] > data_len - 3) {
441 free(data);
442 return NULL;
445 if (showData) {
446 PrintAndLogEx(SUCCESS, "Recovered data:");
447 print_buffer(data, data_len, 1);
450 size_t idn_len = data[4];
451 if (idn_len > data[3] - 1) {
452 free(data);
453 return NULL;
456 // 9f36 Application Transaction Counter (ATC)
457 struct tlvdb *atc_db = tlvdb_fixed(0x9f36, idn_len, data + 5);
459 free(data);
461 return atc_db;
464 static void tlv_hash(void *data, const struct tlv *tlv, int level, bool is_leaf) {
465 struct crypto_hash *ch = data;
466 size_t tag_len;
467 unsigned char *tag;
469 if (tlv_is_constructed(tlv))
470 return;
472 if (tlv->tag == 0x9f4b)
473 return;
475 tag = tlv_encode(tlv, &tag_len);
476 crypto_hash_write(ch, tag, tag_len);
477 free(tag);
480 struct tlvdb *emv_pki_perform_cda(const struct emv_pk *enc_pk, const struct tlvdb *db,
481 const struct tlvdb *this_db,
482 const struct tlv *pdol_data_tlv,
483 const struct tlv *crm1_tlv,
484 const struct tlv *crm2_tlv) {
485 return emv_pki_perform_cda_ex(enc_pk, db, this_db, pdol_data_tlv, crm1_tlv, crm2_tlv, false);
488 struct tlvdb *emv_pki_perform_cda_ex(const struct emv_pk *enc_pk, const struct tlvdb *db,
489 const struct tlvdb *this_db, // AC TLV result
490 const struct tlv *pdol_data_tlv, // PDOL
491 const struct tlv *crm1_tlv, // CDOL1
492 const struct tlv *crm2_tlv, // CDOL2
493 bool showData) {
494 const struct tlv *un_tlv = tlvdb_get(db, 0x9f37, NULL);
495 const struct tlv *cid_tlv = tlvdb_get(this_db, 0x9f27, NULL);
497 if (!un_tlv || !cid_tlv)
498 return NULL;
500 size_t data_len = 0;
501 unsigned char *data = emv_pki_decode_message(enc_pk, 5, &data_len,
502 tlvdb_get(this_db, 0x9f4b, NULL),
504 un_tlv,
505 NULL);
506 if (!data || data_len < 3) {
507 PrintAndLogEx(WARNING, "ERROR: can't decode message. [%zu bytes]", data_len);
508 return NULL;
511 if (showData) {
512 PrintAndLogEx(SUCCESS, "Recovered data:");
513 print_buffer(data, data_len, 1);
516 if (data[3] < 30 || data[3] > data_len - 4) {
517 PrintAndLogEx(WARNING, "ERROR: Invalid data length");
518 free(data);
519 return NULL;
522 if (!cid_tlv || cid_tlv->len != 1 || cid_tlv->value[0] != data[5 + data[4]]) {
523 PrintAndLogEx(WARNING, "ERROR: CID mismatch");
524 free(data);
525 return NULL;
528 struct crypto_hash *ch;
529 ch = crypto_hash_open(enc_pk->hash_algo);
530 if (!ch) {
531 PrintAndLogEx(WARNING, "ERROR: can't create hash");
532 free(data);
533 return NULL;
536 if (pdol_data_tlv)
537 crypto_hash_write(ch, pdol_data_tlv->value, pdol_data_tlv->len);
538 if (crm1_tlv)
539 crypto_hash_write(ch, crm1_tlv->value, crm1_tlv->len);
540 if (crm2_tlv)
541 crypto_hash_write(ch, crm2_tlv->value, crm2_tlv->len);
543 tlvdb_visit(this_db, tlv_hash, ch, 0);
545 if (memcmp(data + 5 + data[4] + 1 + 8, crypto_hash_read(ch), 20)) {
546 PrintAndLogEx(WARNING, "ERROR: calculated hash error");
547 crypto_hash_close(ch);
548 free(data);
549 return NULL;
551 crypto_hash_close(ch);
553 size_t idn_len = data[4];
554 if (idn_len > data[3] - 1) {
555 PrintAndLogEx(WARNING, "ERROR: Invalid IDN length");
556 free(data);
557 return NULL;
560 struct tlvdb *idn_db = tlvdb_fixed(0x9f4c, idn_len, data + 5);
561 free(data);
563 return idn_db;