]> git.zerfleddert.de Git - proxmark3-svn/blame - client/emv/test/dda_test.c
Code improved for less memory
[proxmark3-svn] / client / emv / test / dda_test.c
CommitLineData
d03fb293
OM
1/*
2 * emv-tools - a set of tools to work with EMV family of smart cards
3 * Copyright (C) 2012, 2015 Dmitry Eremin-Solenikov
4 *
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.
9 *
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.
14 */
15
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include "dda_test.h"
21
22#include "../emv_pk.h"
23#include "../crypto.h"
24#include "../dump.h"
25#include "../tlv.h"
26#include "../emv_pki.h"
27
28#include <stdio.h>
29#include <string.h>
30#include <stdlib.h>
31
32struct 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,
58 },
59};
60
61const 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,
73};
74
75const 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,
79};
80
81const unsigned char d_issuer_exp[] = {
82 0x03,
83};
84
85const 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,
97};
98
99const unsigned char d_icc_exp[] = {
100 0x03,
101};
102
103const 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,
111};
112
113const 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,
123};
124static const struct tlv ssd1_tlv = {
125 .len = sizeof(d_ssd1),
126 .value = d_ssd1,
127};
128
129const unsigned char d_pan[] = {
130 0x52, 0x85, 0x88, 0x12, 0x54, 0x34, 0x56, 0x53,
131};
132
133const unsigned char d_dd1[] = {
134 0x00, 0x00, 0x00, 0x00,
135};
136static const struct tlv dd1_tlv = {
137 .len = sizeof(d_dd1),
138 .value = d_dd1,
139};
140
141static int dda_test_raw(bool verbose)
142{
143 const struct emv_pk *pk = &mchip_05;
144
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;
150
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);
155
156 if (!ipk_data)
157 return 1;
158
159 if (verbose) {
160 printf("issuer cert:\n");
161 dump_buffer(ipk_data, ipk_data_len, stdout, 0);
162 }
163
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));
168
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;
175 }
176
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));
180
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;
187 }
188
189 if (verbose) {
190 printf("crypto hash:\n");
191 dump_buffer(h, 20, stdout, 0);
192 }
193
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;
199 }
200
201 crypto_hash_close(ch);
202 free(ipk_data);
203
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;
209
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);
214
215 if (!iccpk_data)
216 return 1;
217
218 if (verbose) {
219 printf("icc cert:\n");
220 dump_buffer(iccpk_data, iccpk_data_len, stdout, 0);
221 }
222
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));*/
227
228 ch = crypto_hash_open(HASH_SHA_1);
229 if (!ch) {
230 free(iccpk_pk);
231 free(iccpk_data);
232 return 1;
233 }
234
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));
238
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;
245 }
246
247 if (verbose) {
248 printf("crypto hash1.1:\n");
249 dump_buffer(h, 20, stdout, 0);
250 }
251
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;
257 }
258
259 crypto_hash_close(ch);
260 free(iccpk_data);
261
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;
267
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;
273
274 if (verbose) {
275 printf("sdad:\n");
276 dump_buffer(sdad, sdad_len, stdout, 0);
277 }
278
279 ch = crypto_hash_open(HASH_SHA_1);
280 if (!ch) {
281 free(sdad);
282 return 1;
283 }
284
285 crypto_hash_write(ch, sdad + 1, sdad_len - 22);
286 crypto_hash_write(ch, d_dd1, sizeof(d_dd1));
287
288 unsigned char *h2 = crypto_hash_read(ch);
289 if (!h2) {
290 crypto_hash_close(ch);
291 free(sdad);
292 return 1;
293 }
294
295 if (verbose) {
296 printf("crypto hash2:\n");
297 dump_buffer(h2, 20, stdout, 0);
298 }
299
300 crypto_hash_close(ch);
301
302 free(sdad);
303
304 return 0;
305}
306
307static int dda_test_pk(bool verbose)
308{
309 const struct emv_pk *pk = &mchip_05;
310 struct tlvdb *db;
311
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));
316
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;
322 }
323
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));*/
327
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;
334 }
335
336 tlvdb_add(db, tlvdb_external(0x9f4b, sizeof(d_sdad_cr), d_sdad_cr));
337
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;
345 }
346
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;
355 }
356
357 if (verbose) {
358 printf("IDN:\n");
359 dump_buffer(idn->value, idn->len, stdout, 0);
360 }
361
362 tlvdb_free(idndb);
363 emv_pk_free(iccpk);
364 emv_pk_free(ipk);
365 tlvdb_free(db);
366
367 return 0;
368}
369
370int exec_dda_test(bool verbose)
371{
372 int ret;
373 fprintf(stdout, "\n");
374
375 ret = dda_test_raw(verbose);
376 if (ret) {
377 fprintf(stderr, "DDA raw test: failed\n");
378 return ret;
379 }
380 fprintf(stdout, "DDA raw test: passed\n");
381
382 ret = dda_test_pk(verbose);
383 if (ret) {
384 fprintf(stderr, "DDA test pk: failed\n");
385 return ret;
386 }
387 fprintf(stdout, "DDA test pk: passed\n");
388
389 return 0;
390}
Impressum, Datenschutz