Cleanup armsrc/string.c and string.h (#964)
[legacy-proxmark3.git] / client / emv / test / dda_test.c
blobafdd4e20bf45cc71e78c3c2b12fec6805ad1620d
1 /*
2 * emv-tools - a set of tools to work with EMV family of smart cards
3 * Copyright (C) 2012, 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 "dda_test.h"
22 #include "../emv_pk.h"
23 #include "../crypto.h"
24 #include "../dump.h"
25 #include "../tlv.h"
26 #include "../emv_pki.h"
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
32 struct emv_pk mchip_05 = {
33 .rid = { 0xa0, 0x00, 0x00, 0x00, 0x04, },
34 .index = 5,
35 .hash_algo = HASH_SHA_1,
36 .pk_algo = PK_RSA,
37 .hash = {
38 0xeb, 0xfa, 0x0d, 0x5d,
39 0x06, 0xd8, 0xce, 0x70,
40 0x2d, 0xa3, 0xea, 0xe8,
41 0x90, 0x70, 0x1d, 0x45,
42 0xe2, 0x74, 0xc8, 0x45, },
43 .exp = { 0x03, },
44 .elen = 1,
45 .mlen = 1408 / 8,
46 .modulus = (unsigned char[]){
47 0xb8, 0x04, 0x8a, 0xbc, 0x30, 0xc9, 0x0d, 0x97, 0x63, 0x36, 0x54, 0x3e, 0x3f, 0xd7, 0x09, 0x1c,
48 0x8f, 0xe4, 0x80, 0x0d, 0xf8, 0x20, 0xed, 0x55, 0xe7, 0xe9, 0x48, 0x13, 0xed, 0x00, 0x55, 0x5b,
49 0x57, 0x3f, 0xec, 0xa3, 0xd8, 0x4a, 0xf6, 0x13, 0x1a, 0x65, 0x1d, 0x66, 0xcf, 0xf4, 0x28, 0x4f,
50 0xb1, 0x3b, 0x63, 0x5e, 0xdd, 0x0e, 0xe4, 0x01, 0x76, 0xd8, 0xbf, 0x04, 0xb7, 0xfd, 0x1c, 0x7b,
51 0xac, 0xf9, 0xac, 0x73, 0x27, 0xdf, 0xaa, 0x8a, 0xa7, 0x2d, 0x10, 0xdb, 0x3b, 0x8e, 0x70, 0xb2,
52 0xdd, 0xd8, 0x11, 0xcb, 0x41, 0x96, 0x52, 0x5e, 0xa3, 0x86, 0xac, 0xc3, 0x3c, 0x0d, 0x9d, 0x45,
53 0x75, 0x91, 0x64, 0x69, 0xc4, 0xe4, 0xf5, 0x3e, 0x8e, 0x1c, 0x91, 0x2c, 0xc6, 0x18, 0xcb, 0x22,
54 0xdd, 0xe7, 0xc3, 0x56, 0x8e, 0x90, 0x02, 0x2e, 0x6b, 0xba, 0x77, 0x02, 0x02, 0xe4, 0x52, 0x2a,
55 0x2d, 0xd6, 0x23, 0xd1, 0x80, 0xe2, 0x15, 0xbd, 0x1d, 0x15, 0x07, 0xfe, 0x3d, 0xc9, 0x0c, 0xa3,
56 0x10, 0xd2, 0x7b, 0x3e, 0xfc, 0xcd, 0x8f, 0x83, 0xde, 0x30, 0x52, 0xca, 0xd1, 0xe4, 0x89, 0x38,
57 0xc6, 0x8d, 0x09, 0x5a, 0xac, 0x91, 0xb5, 0xf3, 0x7e, 0x28, 0xbb, 0x49, 0xec, 0x7e, 0xd5, 0x97,
61 const unsigned char d_issuer_cert[] = {
62 0x17, 0x14, 0x28, 0x4f, 0x76, 0x3b, 0x85, 0x86, 0xee, 0x6d, 0x31, 0x99, 0x51, 0xf7, 0xe6, 0x3f,
63 0xa2, 0x50, 0x76, 0xe5, 0x0d, 0xc9, 0xd3, 0x20, 0x0b, 0xa9, 0x98, 0xd3, 0xa0, 0x52, 0xad, 0xba,
64 0x9a, 0xb6, 0x9a, 0xc6, 0xad, 0x6a, 0xdd, 0x3c, 0xe0, 0x9f, 0x02, 0x78, 0xf4, 0x07, 0x4e, 0xc4,
65 0xee, 0x9b, 0x1d, 0x22, 0x68, 0xa3, 0xe9, 0x53, 0x57, 0x5e, 0x45, 0x4e, 0x50, 0xcd, 0x86, 0x0b,
66 0xf4, 0x24, 0xc5, 0x1c, 0x59, 0x77, 0x12, 0xd2, 0xaa, 0x05, 0x70, 0x89, 0xdd, 0x86, 0x73, 0xe5,
67 0x1b, 0x1e, 0x1d, 0x71, 0x88, 0x03, 0x48, 0x92, 0x07, 0x7a, 0xc1, 0x8a, 0x6a, 0xe2, 0x34, 0x88,
68 0xbe, 0xa9, 0xdf, 0x3b, 0x1a, 0x83, 0xf2, 0xc0, 0x80, 0x0c, 0xd7, 0xc5, 0xcd, 0xf2, 0xfd, 0xe0,
69 0x49, 0x6f, 0x7b, 0xc3, 0x9f, 0xb4, 0xbf, 0x36, 0x32, 0x99, 0xbf, 0xa6, 0x37, 0xb2, 0xec, 0x33,
70 0xc5, 0x07, 0xe3, 0x68, 0x21, 0xee, 0xc2, 0x07, 0x5f, 0x0e, 0x42, 0x0d, 0x38, 0xa1, 0xc9, 0xf3,
71 0x12, 0x72, 0x61, 0xba, 0x31, 0x6c, 0x98, 0x76, 0x74, 0xfa, 0xdb, 0x20, 0xea, 0x7f, 0xeb, 0x75,
72 0xee, 0x45, 0x5d, 0x12, 0x14, 0x6e, 0xa6, 0xf0, 0x2e, 0x8b, 0x01, 0xec, 0x2f, 0xa7, 0xa1, 0x15,
75 const unsigned char d_issuer_rem[] = {
76 0x6e, 0x63, 0xb7, 0xbc, 0x70, 0xab, 0xdd, 0x09, 0x34, 0x1b, 0x34, 0xc0, 0x32, 0x86, 0xba, 0x9b,
77 0xd8, 0x3b, 0xa7, 0x93, 0x6c, 0x5b, 0x77, 0x98, 0xfb, 0x22, 0xc5, 0xe5, 0x3f, 0xf2, 0x40, 0xa2,
78 0x6d, 0xbd, 0x64, 0x15,
81 const unsigned char d_issuer_exp[] = {
82 0x03,
85 const unsigned char d_icc_cert[] = {
86 0xa4, 0x2f, 0xbe, 0xb1, 0x56, 0xb9, 0x8d, 0xcb, 0x05, 0x54, 0xda, 0x06, 0x2a, 0xdc, 0xa5, 0x30,
87 0x9a, 0x91, 0xf0, 0x4f, 0xa2, 0xc7, 0xbd, 0x71, 0x02, 0xa8, 0xd7, 0x3f, 0x16, 0xa3, 0xcf, 0xad,
88 0xe8, 0xaa, 0xdf, 0x4f, 0x3f, 0xe2, 0xa2, 0x12, 0x5c, 0xcd, 0xd7, 0x7c, 0x6b, 0x9f, 0x78, 0xb5,
89 0xb4, 0x37, 0x1c, 0xe0, 0x80, 0x57, 0x25, 0xb0, 0xf9, 0xc0, 0x27, 0xaf, 0x14, 0x7d, 0x91, 0xe1,
90 0xff, 0xdb, 0x20, 0x1e, 0x9c, 0x17, 0x0c, 0xe7, 0x77, 0x05, 0x3a, 0x17, 0x2a, 0xd5, 0x26, 0xdc,
91 0xaf, 0xd3, 0x38, 0x95, 0xe1, 0xa9, 0x47, 0x30, 0x5c, 0x5b, 0x16, 0x7f, 0x2e, 0x7c, 0x6f, 0x99,
92 0x15, 0x81, 0xa6, 0x52, 0xee, 0x47, 0x31, 0x54, 0x76, 0x0c, 0x2e, 0xd7, 0x74, 0x21, 0x4e, 0x50,
93 0xdf, 0xec, 0xdd, 0x4c, 0xf2, 0x94, 0xc9, 0x74, 0xb8, 0x9e, 0xbc, 0xa2, 0x5b, 0x5a, 0xb3, 0xc0,
94 0xbe, 0xb5, 0x0d, 0xfa, 0xf7, 0x82, 0xaf, 0xde, 0x14, 0x33, 0xd9, 0x0c, 0xa2, 0xa8, 0x9d, 0x65,
95 0x1e, 0x75, 0xd6, 0x7e, 0xbc, 0x7c, 0x3e, 0x36, 0xf5, 0xa1, 0x65, 0xee, 0x61, 0x32, 0x61, 0x29,
96 0x39, 0xc1, 0xec, 0xd3, 0x99, 0xe4, 0x60, 0x74, 0xb9, 0x96, 0xd9, 0x3a, 0x88, 0xe0, 0x1e, 0x0a,
99 const unsigned char d_icc_exp[] = {
100 0x03,
103 const unsigned char d_sdad_cr[] = {
104 0x3d, 0x87, 0xf3, 0x10, 0x56, 0x10, 0x2d, 0x25, 0x12, 0xcf, 0xde, 0x30, 0x90, 0x06, 0x27, 0xc1,
105 0x26, 0x3a, 0x76, 0xd1, 0xda, 0xa8, 0x21, 0xf5, 0x08, 0x31, 0xe6, 0x06, 0xc5, 0x45, 0x44, 0xc2,
106 0x58, 0x13, 0x1e, 0xae, 0xbe, 0x87, 0x4d, 0xcb, 0x1a, 0x28, 0xcf, 0x82, 0xd3, 0xff, 0x91, 0x11,
107 0x82, 0x60, 0xbc, 0x91, 0x11, 0x37, 0x11, 0xd3, 0xb2, 0x89, 0xfa, 0x41, 0xbe, 0x69, 0xc7, 0xa7,
108 0xb5, 0xc7, 0x83, 0xe6, 0xf8, 0xf9, 0x7f, 0xce, 0x13, 0xf0, 0x8b, 0x13, 0xfa, 0x44, 0x18, 0x3e,
109 0x37, 0x18, 0xce, 0xbf, 0x0c, 0x41, 0x47, 0x3d, 0x2b, 0x0f, 0xf4, 0xde, 0x44, 0xb6, 0xa0, 0x2d,
110 0x75, 0xad, 0xb6, 0xd4, 0x96, 0x23, 0x93, 0xff, 0xdf, 0x4e, 0x69, 0x02, 0x6c, 0xdf, 0x38, 0xff,
113 const unsigned char d_ssd1[] = {
114 0x5f, 0x25, 0x03, 0x14, 0x05, 0x01, 0x5f, 0x24, 0x03, 0x15, 0x06, 0x30, 0x5a, 0x08, 0x52, 0x85,
115 0x88, 0x12, 0x54, 0x34, 0x56, 0x53, 0x5f, 0x34, 0x01, 0x01, 0x8e, 0x0c, 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x00, 0x1e, 0x03, 0x1f, 0x03, 0x9f, 0x07, 0x02, 0xff, 0x00, 0x9f, 0x0d, 0x05,
117 0xbc, 0x50, 0xbc, 0x00, 0x00, 0x9f, 0x0e, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x0f, 0x05,
118 0xbc, 0x70, 0xbc, 0x98, 0x00, 0x9f, 0x4a, 0x01, 0x82, 0x5f, 0x28, 0x02, 0x06, 0x43, 0x8c, 0x21,
119 0x9f, 0x02, 0x06, 0x9f, 0x03, 0x06, 0x9f, 0x1a, 0x02, 0x95, 0x05, 0x5f, 0x2a, 0x02, 0x9a, 0x03,
120 0x9c, 0x01, 0x9f, 0x37, 0x04, 0x9f, 0x35, 0x01, 0x9f, 0x45, 0x02, 0x9f, 0x4c, 0x08, 0x9f, 0x34,
121 0x03, 0x8d, 0x0c, 0x91, 0x0a, 0x8a, 0x02, 0x95, 0x05, 0x9f, 0x37, 0x04, 0x9f, 0x4c, 0x08,
122 0x39, 0x00,
124 static const struct tlv ssd1_tlv = {
125 .len = sizeof(d_ssd1),
126 .value = d_ssd1,
129 const unsigned char d_pan[] = {
130 0x52, 0x85, 0x88, 0x12, 0x54, 0x34, 0x56, 0x53,
133 const unsigned char d_dd1[] = {
134 0x00, 0x00, 0x00, 0x00,
136 static const struct tlv dd1_tlv = {
137 .len = sizeof(d_dd1),
138 .value = d_dd1,
141 static int dda_test_raw(bool verbose)
143 const struct emv_pk *pk = &mchip_05;
145 struct crypto_pk *kcp = crypto_pk_open(PK_RSA,
146 pk->modulus, pk->mlen,
147 pk->exp, pk->elen);
148 if (!kcp)
149 return 1;
151 unsigned char *ipk_data;
152 size_t ipk_data_len;
153 ipk_data = crypto_pk_encrypt(kcp, d_issuer_cert, sizeof(d_issuer_cert), &ipk_data_len);
154 crypto_pk_close(kcp);
156 if (!ipk_data)
157 return 1;
159 if (verbose) {
160 printf("issuer cert:\n");
161 dump_buffer(ipk_data, ipk_data_len, stdout, 0);
164 size_t ipk_pk_len = ipk_data[13];
165 unsigned char *ipk_pk = malloc(ipk_pk_len);
166 memcpy(ipk_pk, ipk_data + 15, ipk_data_len - 36);
167 memcpy(ipk_pk + ipk_data_len - 36, d_issuer_rem, sizeof(d_issuer_rem));
169 struct crypto_hash *ch;
170 ch = crypto_hash_open(HASH_SHA_1);
171 if (!ch) {
172 free(ipk_pk);
173 free(ipk_data);
174 return 1;
177 crypto_hash_write(ch, ipk_data + 1, 14);
178 crypto_hash_write(ch, ipk_pk, ipk_pk_len);
179 crypto_hash_write(ch, d_issuer_exp, sizeof(d_issuer_exp));
181 unsigned char *h = crypto_hash_read(ch);
182 if (!h) {
183 crypto_hash_close(ch);
184 free(ipk_pk);
185 free(ipk_data);
186 return 1;
189 if (verbose) {
190 printf("crypto hash:\n");
191 dump_buffer(h, 20, stdout, 0);
194 if (memcmp(ipk_data + ipk_data_len - 21, h, 20)) {
195 crypto_hash_close(ch);
196 free(ipk_pk);
197 free(ipk_data);
198 return 1;
201 crypto_hash_close(ch);
202 free(ipk_data);
204 struct crypto_pk *ikcp = crypto_pk_open(PK_RSA, ipk_pk, (int) ipk_pk_len,
205 d_issuer_exp, (int) sizeof(d_issuer_exp));
206 free(ipk_pk);
207 if (!ikcp)
208 return 1;
210 unsigned char *iccpk_data;
211 size_t iccpk_data_len;
212 iccpk_data = crypto_pk_encrypt(ikcp, d_icc_cert, sizeof(d_icc_cert), &iccpk_data_len);
213 crypto_pk_close(ikcp);
215 if (!iccpk_data)
216 return 1;
218 if (verbose) {
219 printf("icc cert:\n");
220 dump_buffer(iccpk_data, iccpk_data_len, stdout, 0);
223 size_t iccpk_pk_len = iccpk_data[19];
224 unsigned char *iccpk_pk = malloc(iccpk_pk_len);
225 memcpy(iccpk_pk, iccpk_data + 21, /*iccpk_data_len - 36*/iccpk_pk_len);
226 /*memcpy(iccpk_pk + iccpk_data_len - 36, icc_rem, sizeof(icc_rem));*/
228 ch = crypto_hash_open(HASH_SHA_1);
229 if (!ch) {
230 free(iccpk_pk);
231 free(iccpk_data);
232 return 1;
235 crypto_hash_write(ch, iccpk_data + 1, iccpk_data_len - 22);
236 crypto_hash_write(ch, d_icc_exp, sizeof(d_icc_exp));
237 crypto_hash_write(ch, d_ssd1, sizeof(d_ssd1));
239 h = crypto_hash_read(ch);
240 if (!h) {
241 crypto_hash_close(ch);
242 free(iccpk_pk);
243 free(iccpk_data);
244 return 1;
247 if (verbose) {
248 printf("crypto hash1.1:\n");
249 dump_buffer(h, 20, stdout, 0);
252 if (memcmp(iccpk_data + iccpk_data_len - 21, h, 20)) {
253 crypto_hash_close(ch);
254 free(iccpk_pk);
255 free(iccpk_data);
256 return 1;
259 crypto_hash_close(ch);
260 free(iccpk_data);
262 struct crypto_pk *icckcp = crypto_pk_open(PK_RSA, iccpk_pk, (int) iccpk_pk_len,
263 d_issuer_exp, (int) sizeof(d_issuer_exp));
264 free(iccpk_pk);
265 if (!icckcp)
266 return 1;
268 size_t sdad_len;
269 unsigned char *sdad = crypto_pk_encrypt(icckcp, d_sdad_cr, sizeof(d_sdad_cr), &sdad_len);
270 crypto_pk_close(icckcp);
271 if (!sdad)
272 return 1;
274 if (verbose) {
275 printf("sdad:\n");
276 dump_buffer(sdad, sdad_len, stdout, 0);
279 ch = crypto_hash_open(HASH_SHA_1);
280 if (!ch) {
281 free(sdad);
282 return 1;
285 crypto_hash_write(ch, sdad + 1, sdad_len - 22);
286 crypto_hash_write(ch, d_dd1, sizeof(d_dd1));
288 unsigned char *h2 = crypto_hash_read(ch);
289 if (!h2) {
290 crypto_hash_close(ch);
291 free(sdad);
292 return 1;
295 if (verbose) {
296 printf("crypto hash2:\n");
297 dump_buffer(h2, 20, stdout, 0);
300 crypto_hash_close(ch);
302 free(sdad);
304 return 0;
307 static int dda_test_pk(bool verbose)
309 const struct emv_pk *pk = &mchip_05;
310 struct tlvdb *db;
312 db = tlvdb_external(0x90, sizeof(d_issuer_cert), d_issuer_cert);
313 tlvdb_add(db, tlvdb_external(0x9f32, sizeof(d_issuer_exp), d_issuer_exp));
314 tlvdb_add(db, tlvdb_external(0x92, sizeof(d_issuer_rem), d_issuer_rem));
315 tlvdb_add(db, tlvdb_external(0x5a, sizeof(d_pan), d_pan));
317 struct emv_pk *ipk = emv_pki_recover_issuer_cert(pk, db);
318 if (!ipk) {
319 fprintf(stderr, "Could not recover Issuer certificate!\n");
320 tlvdb_free(db);
321 return 2;
324 tlvdb_add(db, tlvdb_external(0x9f46, sizeof(d_icc_cert), d_icc_cert));
325 tlvdb_add(db, tlvdb_external(0x9f47, sizeof(d_icc_exp), d_icc_exp));
326 /*tlvdb_add(db, tlvdb_external(0x9f48, sizeof(d_issuer_rem), d_issuer_rem));*/
328 struct emv_pk *iccpk = emv_pki_recover_icc_cert(ipk, db, &ssd1_tlv);
329 if (!iccpk) {
330 fprintf(stderr, "Could not recover ICC certificate!\n");
331 emv_pk_free(ipk);
332 tlvdb_free(db);
333 return 2;
336 tlvdb_add(db, tlvdb_external(0x9f4b, sizeof(d_sdad_cr), d_sdad_cr));
338 struct tlvdb *idndb = emv_pki_recover_idn(iccpk, db, &dd1_tlv);
339 if (!idndb) {
340 fprintf(stderr, "Could not recover IDN!\n");
341 emv_pk_free(iccpk);
342 emv_pk_free(ipk);
343 tlvdb_free(db);
344 return 2;
347 const struct tlv *idn = tlvdb_get(idndb, 0x9f4c, NULL);
348 if (!idn) {
349 fprintf(stderr, "IDN not found!\n");
350 tlvdb_free(idndb);
351 emv_pk_free(iccpk);
352 emv_pk_free(ipk);
353 tlvdb_free(db);
354 return 2;
357 if (verbose) {
358 printf("IDN:\n");
359 dump_buffer(idn->value, idn->len, stdout, 0);
362 tlvdb_free(idndb);
363 emv_pk_free(iccpk);
364 emv_pk_free(ipk);
365 tlvdb_free(db);
367 return 0;
370 int exec_dda_test(bool verbose)
372 int ret;
373 fprintf(stdout, "\n");
375 ret = dda_test_raw(verbose);
376 if (ret) {
377 fprintf(stderr, "DDA raw test: failed\n");
378 return ret;
380 fprintf(stdout, "DDA raw test: passed\n");
382 ret = dda_test_pk(verbose);
383 if (ret) {
384 fprintf(stderr, "DDA test pk: failed\n");
385 return ret;
387 fprintf(stdout, "DDA test pk: passed\n");
389 return 0;