1 //-----------------------------------------------------------------------------
2 // Borrowed initially from https://github.com/lumag/emv-tools/
3 // Copyright (C) 2012, 2015 Dmitry Eremin-Solenikov
4 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // See LICENSE.txt for the text of the license.
17 //-----------------------------------------------------------------------------
18 // libopenemv - a library to work with EMV family of smart cards
19 //-----------------------------------------------------------------------------
25 #include "emv_pki_priv.h"
31 struct emv_pk
*emv_pki_make_ca(const struct crypto_pk
*cp
,
32 const unsigned char *rid
, unsigned char index
,
33 unsigned int expire
, enum crypto_algo_hash hash_algo
) {
34 size_t modlen
, explen
;
35 unsigned char *mod
, *exp
;
40 mod
= crypto_pk_get_parameter(cp
, 0, &modlen
);
41 exp
= crypto_pk_get_parameter(cp
, 1, &explen
);
43 if (!mod
|| !modlen
|| !exp
|| !explen
) {
50 struct emv_pk
*pk
= emv_pk_new(modlen
, explen
);
51 memcpy(pk
->rid
, rid
, 5);
54 pk
->pk_algo
= crypto_pk_get_algo(cp
);
55 pk
->hash_algo
= hash_algo
;
56 memcpy(pk
->modulus
, mod
, modlen
);
57 memcpy(pk
->exp
, exp
, explen
);
62 struct crypto_hash
*ch
= crypto_hash_open(pk
->hash_algo
);
68 crypto_hash_write(ch
, pk
->rid
, sizeof(pk
->rid
));
69 crypto_hash_write(ch
, &pk
->index
, 1);
70 crypto_hash_write(ch
, pk
->modulus
, pk
->mlen
);
71 crypto_hash_write(ch
, pk
->exp
, pk
->elen
);
73 unsigned char *h
= crypto_hash_read(ch
);
75 crypto_hash_close(ch
);
81 memcpy(pk
->hash
, h
, crypto_hash_get_size(ch
));
82 crypto_hash_close(ch
);
87 static struct tlvdb
*emv_pki_sign_message(const struct crypto_pk
*cp
,
88 tlv_tag_t cert_tag
, tlv_tag_t rem_tag
,
89 const unsigned char *msg
, size_t msg_len
,
90 ... /* A list of tlv pointers, end with NULL */
92 size_t tmp_len
= (crypto_pk_get_nbits(cp
) + 7) / 8;
93 unsigned char *tmp
= calloc(1, tmp_len
);
99 struct crypto_hash
*ch
= crypto_hash_open(HASH_SHA_1
);
106 tmp
[tmp_len
- 1] = 0xbc;
108 const unsigned char *rem
;
110 size_t hash_len
= crypto_hash_get_size(ch
);
111 size_t part_len
= tmp_len
- 2 - hash_len
;
112 if (part_len
< msg_len
) {
113 memcpy(tmp
+ 1, msg
, part_len
);
114 rem
= msg
+ part_len
;
115 rem_len
= msg_len
- part_len
;
117 memcpy(tmp
+ 1, msg
, msg_len
);
118 memset(tmp
+ 1 + msg_len
, 0xbb, part_len
- msg_len
);
122 crypto_hash_write(ch
, tmp
+ 1, part_len
);
123 crypto_hash_write(ch
, rem
, rem_len
);
126 va_start(vl
, msg_len
);
128 const struct tlv
*add_tlv
= va_arg(vl
, const struct tlv
*);
132 crypto_hash_write(ch
, add_tlv
->value
, add_tlv
->len
);
136 unsigned char *h
= crypto_hash_read(ch
);
138 crypto_hash_close(ch
);
144 memcpy(tmp
+ 1 + part_len
, h
, hash_len
);
145 crypto_hash_close(ch
);
148 unsigned char *cert
= crypto_pk_decrypt(cp
, tmp
, tmp_len
, &cert_len
);
154 struct tlvdb
*db
= tlvdb_fixed(cert_tag
, cert_len
, cert
);
160 struct tlvdb
*rdb
= tlvdb_fixed(rem_tag
, rem_len
, rem
);
172 static struct tlvdb
*emv_pki_sign_key(const struct crypto_pk
*cp
,
174 unsigned char msgtype
,
179 const struct tlv
*add_tlv
182 unsigned char *msg
= calloc(1, 1 + pan_len
+ 2 + 3 + 1 + 1 + 1 + 1 + ipk
->mlen
);
187 msg
[pos
++] = msgtype
;
188 memcpy(msg
+ pos
, ipk
->pan
, pan_len
);
190 msg
[pos
++] = (ipk
->expire
>> 8) & 0xff;
191 msg
[pos
++] = (ipk
->expire
>> 16) & 0xff;
192 memcpy(msg
+ pos
, ipk
->serial
, 3);
194 msg
[pos
++] = ipk
->hash_algo
;
195 msg
[pos
++] = ipk
->pk_algo
;
196 msg
[pos
++] = ipk
->mlen
;
197 msg
[pos
++] = ipk
->elen
;
198 memcpy(msg
+ pos
, ipk
->modulus
, ipk
->mlen
);
201 struct tlvdb
*exp_db
= tlvdb_fixed(exp_tag
, ipk
->elen
, ipk
->exp
);
207 struct tlvdb
*db
= emv_pki_sign_message(cp
,
210 tlvdb_get(exp_db
, exp_tag
, NULL
),
219 tlvdb_add(db
, exp_db
);
224 struct tlvdb
*emv_pki_sign_issuer_cert(const struct crypto_pk
*cp
, struct emv_pk
*issuer_pk
) {
225 return emv_pki_sign_key(cp
, issuer_pk
, 2, 4, 0x90, 0x9f32, 0x92, NULL
);
228 struct tlvdb
*emv_pki_sign_icc_cert(const struct crypto_pk
*cp
, struct emv_pk
*icc_pk
, const struct tlv
*sda_tlv
) {
229 return emv_pki_sign_key(cp
, icc_pk
, 4, 10, 0x9f46, 0x9f47, 0x9f48, sda_tlv
);
232 struct tlvdb
*emv_pki_sign_icc_pe_cert(const struct crypto_pk
*cp
, struct emv_pk
*icc_pe_pk
) {
233 return emv_pki_sign_key(cp
, icc_pe_pk
, 4, 10, 0x9f2d, 0x9f2e, 0x9f2f, NULL
);
236 struct tlvdb
*emv_pki_sign_dac(const struct crypto_pk
*cp
, const struct tlv
*dac_tlv
, const struct tlv
*sda_tlv
) {
238 unsigned char *msg
= calloc(1, 1 + 1 + dac_tlv
->len
);
244 msg
[pos
++] = HASH_SHA_1
;
245 memcpy(msg
+ pos
, dac_tlv
->value
, dac_tlv
->len
);
248 struct tlvdb
*db
= emv_pki_sign_message(cp
,
259 struct tlvdb
*emv_pki_sign_idn(const struct crypto_pk
*cp
, const struct tlv
*idn_tlv
, const struct tlv
*dyn_tlv
) {
261 unsigned char *msg
= calloc(1, 1 + 1 + 1 + 1 + idn_tlv
->len
);
267 msg
[pos
++] = HASH_SHA_1
;
268 msg
[pos
++] = idn_tlv
->len
+ 1;
269 msg
[pos
++] = idn_tlv
->len
;
270 memcpy(msg
+ pos
, idn_tlv
->value
, idn_tlv
->len
);
273 struct tlvdb
*db
= emv_pki_sign_message(cp
,