fix one too small
[RRG-proxmark3.git] / client / src / emv / crypto_polarssl.c
blob00e484bf79a9d0f95c6cf742169473fdb8cff2ca
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.
5 //
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 //-----------------------------------------------------------------------------
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
25 #include "crypto_backend.h"
27 #include <stdlib.h> // malloc
28 #include <string.h> // memset
30 #include "rsa.h"
31 #include "sha1.h"
32 #include "ui.h" // printandlog
34 struct crypto_hash_polarssl {
35 struct crypto_hash ch;
36 mbedtls_sha1_context ctx;
39 static void crypto_hash_polarssl_close(struct crypto_hash *_ch) {
40 struct crypto_hash_polarssl *ch = (struct crypto_hash_polarssl *)_ch;
41 free(ch);
44 static void crypto_hash_polarssl_write(struct crypto_hash *_ch, const unsigned char *buf, size_t len) {
45 struct crypto_hash_polarssl *ch = (struct crypto_hash_polarssl *)_ch;
46 mbedtls_sha1_update(&(ch->ctx), buf, len);
49 static unsigned char *crypto_hash_polarssl_read(struct crypto_hash *_ch) {
50 struct crypto_hash_polarssl *ch = (struct crypto_hash_polarssl *)_ch;
51 static unsigned char sha1sum[20];
52 mbedtls_sha1_finish(&(ch->ctx), sha1sum);
53 return sha1sum;
56 static size_t crypto_hash_polarssl_get_size(const struct crypto_hash *ch) {
57 if (ch->algo == HASH_SHA_1)
58 return 20;
59 return 0;
62 static struct crypto_hash *crypto_hash_polarssl_open(enum crypto_algo_hash hash) {
63 if (hash != HASH_SHA_1)
64 return NULL;
66 struct crypto_hash_polarssl *ch = calloc(1, sizeof(*ch));
68 mbedtls_sha1_starts(&(ch->ctx));
70 ch->ch.write = crypto_hash_polarssl_write;
71 ch->ch.read = crypto_hash_polarssl_read;
72 ch->ch.close = crypto_hash_polarssl_close;
73 ch->ch.get_size = crypto_hash_polarssl_get_size;
75 return &ch->ch;
78 struct crypto_pk_polarssl {
79 struct crypto_pk cp;
80 mbedtls_rsa_context ctx;
83 static struct crypto_pk *crypto_pk_polarssl_open_rsa(va_list vl) {
84 struct crypto_pk_polarssl *cp = calloc(1, sizeof(*cp));
85 memset(cp, 0x00, sizeof(*cp));
87 char *mod = va_arg(vl, char *); // N
88 int modlen = va_arg(vl, size_t);
89 char *exp = va_arg(vl, char *); // E
90 int explen = va_arg(vl, size_t);
92 mbedtls_rsa_init(&cp->ctx, MBEDTLS_RSA_PKCS_V15, 0);
94 cp->ctx.len = modlen; // size(N) in bytes
95 mbedtls_mpi_read_binary(&cp->ctx.N, (const unsigned char *)mod, modlen);
96 mbedtls_mpi_read_binary(&cp->ctx.E, (const unsigned char *)exp, explen);
98 int res = mbedtls_rsa_check_pubkey(&cp->ctx);
99 if (res != 0) {
100 PrintAndLogEx(WARNING, "PolarSSL public key error res=%x exp=%d mod=%d", res * -1, explen, modlen);
101 free(cp);
102 return NULL;
105 return &cp->cp;
108 static struct crypto_pk *crypto_pk_polarssl_open_priv_rsa(va_list vl) {
109 struct crypto_pk_polarssl *cp = calloc(1, sizeof(*cp));
110 memset(cp, 0x00, sizeof(*cp));
111 char *mod = va_arg(vl, char *);
112 int modlen = va_arg(vl, size_t);
113 char *exp = va_arg(vl, char *);
114 int explen = va_arg(vl, size_t);
115 char *d = va_arg(vl, char *);
116 int dlen = va_arg(vl, size_t);
117 char *p = va_arg(vl, char *);
118 int plen = va_arg(vl, size_t);
119 char *q = va_arg(vl, char *);
120 int qlen = va_arg(vl, size_t);
121 char *dp = va_arg(vl, char *);
122 int dplen = va_arg(vl, size_t);
123 char *dq = va_arg(vl, char *);
124 int dqlen = va_arg(vl, size_t);
125 // calc QP via Q and P
126 // char *inv = va_arg(vl, char *);
127 // int invlen = va_arg(vl, size_t);
129 mbedtls_rsa_init(&cp->ctx, MBEDTLS_RSA_PKCS_V15, 0);
131 cp->ctx.len = modlen; // size(N) in bytes
132 mbedtls_mpi_read_binary(&cp->ctx.N, (const unsigned char *)mod, modlen);
133 mbedtls_mpi_read_binary(&cp->ctx.E, (const unsigned char *)exp, explen);
135 mbedtls_mpi_read_binary(&cp->ctx.D, (const unsigned char *)d, dlen);
136 mbedtls_mpi_read_binary(&cp->ctx.P, (const unsigned char *)p, plen);
137 mbedtls_mpi_read_binary(&cp->ctx.Q, (const unsigned char *)q, qlen);
138 mbedtls_mpi_read_binary(&cp->ctx.DP, (const unsigned char *)dp, dplen);
139 mbedtls_mpi_read_binary(&cp->ctx.DQ, (const unsigned char *)dq, dqlen);
141 int res = mbedtls_mpi_inv_mod(&cp->ctx.QP, &cp->ctx.Q, &cp->ctx.P);
142 if (res != 0) {
143 PrintAndLogEx(WARNING, "PolarSSL private key error res=%x exp=%d mod=%d", res * -1, explen, modlen);
144 free(cp);
145 return NULL;
148 res = mbedtls_rsa_check_privkey(&cp->ctx);
149 if (res != 0) {
150 PrintAndLogEx(WARNING, "PolarSSL private key error res=%x exp=%d mod=%d", res * -1, explen, modlen);
151 free(cp);
152 return NULL;
155 return &cp->cp;
158 static int myrand(void *rng_state, unsigned char *output, size_t len) {
159 size_t i;
160 (void)rng_state;
162 for (i = 0; i < len; ++i)
163 output[i] = rand();
165 return 0;
168 static struct crypto_pk *crypto_pk_polarssl_genkey_rsa(va_list vl) {
169 struct crypto_pk_polarssl *cp = calloc(1, sizeof(*cp));
170 memset(cp, 0x00, sizeof(*cp));
172 int transient = va_arg(vl, int);
173 unsigned int nbits = va_arg(vl, unsigned int);
174 unsigned int exp = va_arg(vl, unsigned int);
176 if (transient) {
179 int res = mbedtls_rsa_gen_key(&cp->ctx, &myrand, NULL, nbits, exp);
180 if (res) {
181 PrintAndLogEx(WARNING, "PolarSSL private key generation error res=%x exp=%u nbits=%u", res * -1, exp, nbits);
182 free(cp);
183 return NULL;
186 return &cp->cp;
189 static void crypto_pk_polarssl_close(struct crypto_pk *_cp) {
190 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
192 mbedtls_rsa_free(&cp->ctx);
193 free(cp);
196 static unsigned char *crypto_pk_polarssl_encrypt(const struct crypto_pk *_cp, const unsigned char *buf, size_t len, size_t *clen) {
197 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
198 *clen = 0;
199 size_t keylen = mbedtls_mpi_size(&cp->ctx.N);
201 unsigned char *result = calloc(1, keylen);
202 if (!result) {
203 PrintAndLogEx(WARNING, "RSA encrypt failed. Can't allocate result memory");
204 return NULL;
207 int res = mbedtls_rsa_public(&cp->ctx, buf, result);
208 if (res) {
209 PrintAndLogEx(WARNING, "RSA encrypt failed. Error: %x data len: %zu key len: %zu", res * -1, len, keylen);
210 free(result);
211 return NULL;
214 *clen = keylen;
215 return result;
218 static unsigned char *crypto_pk_polarssl_decrypt(const struct crypto_pk *_cp, const unsigned char *buf, size_t len, size_t *clen) {
219 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
220 *clen = 0;
221 size_t keylen = mbedtls_mpi_size(&cp->ctx.N);
223 unsigned char *result = calloc(1, keylen);
224 if (!result) {
225 PrintAndLogEx(WARNING, "RSA encrypt failed. Can't allocate result memory");
226 return NULL;
229 int res = mbedtls_rsa_private(&cp->ctx, NULL, NULL, buf, result); // CHECK???
230 if (res) {
231 PrintAndLogEx(WARNING, "RSA decrypt failed. Error: %x data len: %zu key len: %zu", res * -1, len, keylen);
232 free(result);
233 return NULL;
236 *clen = keylen;
237 return result;
240 static size_t crypto_pk_polarssl_get_nbits(const struct crypto_pk *_cp) {
241 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
242 return cp->ctx.len * 8;
245 static unsigned char *crypto_pk_polarssl_get_parameter(const struct crypto_pk *_cp, unsigned param, size_t *plen) {
246 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
247 unsigned char *result = NULL;
248 int res;
249 switch (param) {
250 // mod
251 case 0:
252 *plen = mbedtls_mpi_size(&cp->ctx.N);
253 result = calloc(1, *plen);
254 memset(result, 0x00, *plen);
255 res = mbedtls_mpi_write_binary(&cp->ctx.N, result, *plen);
256 if (res < 0) {
257 PrintAndLogEx(WARNING, "Error write_binary");
258 free(result);
259 result = 0;
261 break;
262 // exp
263 case 1:
264 *plen = mbedtls_mpi_size(&cp->ctx.E);
265 result = calloc(1, *plen);
266 memset(result, 0x00, *plen);
267 res = mbedtls_mpi_write_binary(&cp->ctx.E, result, *plen);
268 if (res < 0) {
269 PrintAndLogEx(WARNING, "Error write_binary");
270 free(result);
271 result = 0;
273 break;
274 default:
275 PrintAndLogEx(WARNING, "Error get parameter. Param = %u", param);
276 break;
278 return result;
281 static struct crypto_pk *crypto_pk_polarssl_open(enum crypto_algo_pk pk, va_list vl) {
282 struct crypto_pk *cp;
284 if (pk == PK_RSA)
285 cp = crypto_pk_polarssl_open_rsa(vl);
286 else
287 return NULL;
289 cp->close = crypto_pk_polarssl_close;
290 cp->encrypt = crypto_pk_polarssl_encrypt;
291 cp->get_parameter = crypto_pk_polarssl_get_parameter;
292 cp->get_nbits = crypto_pk_polarssl_get_nbits;
294 return cp;
297 static struct crypto_pk *crypto_pk_polarssl_open_priv(enum crypto_algo_pk pk, va_list vl) {
298 struct crypto_pk *cp;
300 if (pk == PK_RSA)
301 cp = crypto_pk_polarssl_open_priv_rsa(vl);
302 else
303 return NULL;
305 cp->close = crypto_pk_polarssl_close;
306 cp->encrypt = crypto_pk_polarssl_encrypt;
307 cp->decrypt = crypto_pk_polarssl_decrypt;
308 cp->get_parameter = crypto_pk_polarssl_get_parameter;
309 cp->get_nbits = crypto_pk_polarssl_get_nbits;
311 return cp;
314 static struct crypto_pk *crypto_pk_polarssl_genkey(enum crypto_algo_pk pk, va_list vl) {
315 struct crypto_pk *cp;
317 if (pk == PK_RSA)
318 cp = crypto_pk_polarssl_genkey_rsa(vl);
319 else
320 return NULL;
322 cp->close = crypto_pk_polarssl_close;
323 cp->encrypt = crypto_pk_polarssl_encrypt;
324 cp->decrypt = crypto_pk_polarssl_decrypt;
325 cp->get_parameter = crypto_pk_polarssl_get_parameter;
326 cp->get_nbits = crypto_pk_polarssl_get_nbits;
328 return cp;
331 static struct crypto_backend crypto_polarssl_backend = {
332 .hash_open = crypto_hash_polarssl_open,
333 .pk_open = crypto_pk_polarssl_open,
334 .pk_open_priv = crypto_pk_polarssl_open_priv,
335 .pk_genkey = crypto_pk_polarssl_genkey,
338 struct crypto_backend *crypto_polarssl_init(void) {
339 return &crypto_polarssl_backend;