]> git.zerfleddert.de Git - proxmark3-svn/blame - client/emv/crypto_polarssl.c
Code improved for less memory
[proxmark3-svn] / client / emv / crypto_polarssl.c
CommitLineData
d03fb293
OM
1/*
2 * libopenemv - a library to work with EMV family of smart cards
3 * Copyright (C) 2015 Dmitry Eremin-Solenikov
4 * Copyright (C) 2017 Merlok
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library 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 GNU
14 * Lesser General Public License for more details.
15 */
16
17#ifdef HAVE_CONFIG_H
18#include <config.h>
19#endif
20
21#include "crypto.h"
22#include "crypto_backend.h"
23
24#include <stdarg.h>
25#include <stdio.h>
26#include <stdlib.h>
700d8687 27#include <string.h>
d03fb293 28
700d8687
OM
29#include "mbedtls/rsa.h"
30#include "mbedtls/sha1.h"
d03fb293
OM
31
32struct crypto_hash_polarssl {
33 struct crypto_hash ch;
700d8687 34 mbedtls_sha1_context ctx;
d03fb293
OM
35};
36
37static void crypto_hash_polarssl_close(struct crypto_hash *_ch)
38{
39 struct crypto_hash_polarssl *ch = (struct crypto_hash_polarssl *)_ch;
40
41 free(ch);
42}
43
44static void crypto_hash_polarssl_write(struct crypto_hash *_ch, const unsigned char *buf, size_t len)
45{
46 struct crypto_hash_polarssl *ch = (struct crypto_hash_polarssl *)_ch;
47
700d8687 48 mbedtls_sha1_update(&(ch->ctx), buf, len);
d03fb293
OM
49}
50
51static unsigned char *crypto_hash_polarssl_read(struct crypto_hash *_ch)
52{
53 struct crypto_hash_polarssl *ch = (struct crypto_hash_polarssl *)_ch;
54
55 static unsigned char sha1sum[20];
700d8687 56 mbedtls_sha1_finish(&(ch->ctx), sha1sum);
d03fb293
OM
57 return sha1sum;
58}
59
60static size_t crypto_hash_polarssl_get_size(const struct crypto_hash *ch)
61{
62 if (ch->algo == HASH_SHA_1)
63 return 20;
64 else
65 return 0;
66}
67
68static struct crypto_hash *crypto_hash_polarssl_open(enum crypto_algo_hash hash)
69{
70 if (hash != HASH_SHA_1)
71 return NULL;
72
73 struct crypto_hash_polarssl *ch = malloc(sizeof(*ch));
74
700d8687 75 mbedtls_sha1_starts(&(ch->ctx));
d03fb293
OM
76
77 ch->ch.write = crypto_hash_polarssl_write;
78 ch->ch.read = crypto_hash_polarssl_read;
79 ch->ch.close = crypto_hash_polarssl_close;
80 ch->ch.get_size = crypto_hash_polarssl_get_size;
81
82 return &ch->ch;
83}
84
85struct crypto_pk_polarssl {
86 struct crypto_pk cp;
700d8687 87 mbedtls_rsa_context ctx;
d03fb293
OM
88};
89
90static struct crypto_pk *crypto_pk_polarssl_open_rsa(va_list vl)
91{
92 struct crypto_pk_polarssl *cp = malloc(sizeof(*cp));
93 memset(cp, 0x00, sizeof(*cp));
94
95 char *mod = va_arg(vl, char *); // N
96 int modlen = va_arg(vl, size_t);
97 char *exp = va_arg(vl, char *); // E
98 int explen = va_arg(vl, size_t);
99
700d8687 100 mbedtls_rsa_init(&cp->ctx, MBEDTLS_RSA_PKCS_V15, 0);
d03fb293
OM
101
102 cp->ctx.len = modlen; // size(N) in bytes
700d8687
OM
103 mbedtls_mpi_read_binary(&cp->ctx.N, (const unsigned char *)mod, modlen);
104 mbedtls_mpi_read_binary(&cp->ctx.E, (const unsigned char *)exp, explen);
d03fb293 105
700d8687 106 int res = mbedtls_rsa_check_pubkey(&cp->ctx);
d03fb293
OM
107 if(res != 0) {
108 fprintf(stderr, "PolarSSL public key error res=%x exp=%d mod=%d.\n", res * -1, explen, modlen);
44964fd1 109 free(cp);
d03fb293
OM
110 return NULL;
111 }
112
113 return &cp->cp;
114}
115
116static struct crypto_pk *crypto_pk_polarssl_open_priv_rsa(va_list vl)
117{
118 struct crypto_pk_polarssl *cp = malloc(sizeof(*cp));
119 memset(cp, 0x00, sizeof(*cp));
120 char *mod = va_arg(vl, char *);
121 int modlen = va_arg(vl, size_t);
122 char *exp = va_arg(vl, char *);
123 int explen = va_arg(vl, size_t);
124 char *d = va_arg(vl, char *);
125 int dlen = va_arg(vl, size_t);
126 char *p = va_arg(vl, char *);
127 int plen = va_arg(vl, size_t);
128 char *q = va_arg(vl, char *);
129 int qlen = va_arg(vl, size_t);
130 char *dp = va_arg(vl, char *);
131 int dplen = va_arg(vl, size_t);
132 char *dq = va_arg(vl, char *);
133 int dqlen = va_arg(vl, size_t);
134 // calc QP via Q and P
135// char *inv = va_arg(vl, char *);
136// int invlen = va_arg(vl, size_t);
137
700d8687 138 mbedtls_rsa_init(&cp->ctx, MBEDTLS_RSA_PKCS_V15, 0);
d03fb293
OM
139
140 cp->ctx.len = modlen; // size(N) in bytes
700d8687
OM
141 mbedtls_mpi_read_binary(&cp->ctx.N, (const unsigned char *)mod, modlen);
142 mbedtls_mpi_read_binary(&cp->ctx.E, (const unsigned char *)exp, explen);
143
144 mbedtls_mpi_read_binary(&cp->ctx.D, (const unsigned char *)d, dlen);
145 mbedtls_mpi_read_binary(&cp->ctx.P, (const unsigned char *)p, plen);
146 mbedtls_mpi_read_binary(&cp->ctx.Q, (const unsigned char *)q, qlen);
147 mbedtls_mpi_read_binary(&cp->ctx.DP, (const unsigned char *)dp, dplen);
148 mbedtls_mpi_read_binary(&cp->ctx.DQ, (const unsigned char *)dq, dqlen);
149 mbedtls_mpi_inv_mod(&cp->ctx.QP, &cp->ctx.Q, &cp->ctx.P);
d03fb293 150
700d8687 151 int res = mbedtls_rsa_check_privkey(&cp->ctx);
d03fb293
OM
152 if(res != 0) {
153 fprintf(stderr, "PolarSSL private key error res=%x exp=%d mod=%d.\n", res * -1, explen, modlen);
44964fd1 154 free(cp);
d03fb293
OM
155 return NULL;
156 }
157
158 return &cp->cp;
159}
160
161static int myrand(void *rng_state, unsigned char *output, size_t len) {
162 size_t i;
163
164 if(rng_state != NULL)
165 rng_state = NULL;
166
167 for( i = 0; i < len; ++i )
168 output[i] = rand();
169
170 return 0;
171}
172
173
174static struct crypto_pk *crypto_pk_polarssl_genkey_rsa(va_list vl)
175{
176 struct crypto_pk_polarssl *cp = malloc(sizeof(*cp));
177 memset(cp, 0x00, sizeof(*cp));
178
179 int transient = va_arg(vl, int);
180 unsigned int nbits = va_arg(vl, unsigned int);
181 unsigned int exp = va_arg(vl, unsigned int);
182
183 if (transient) {
184 }
185
700d8687 186 int res = mbedtls_rsa_gen_key(&cp->ctx, &myrand, NULL, nbits, exp);
d03fb293
OM
187 if (res) {
188 fprintf(stderr, "PolarSSL private key generation error res=%x exp=%d nbits=%d.\n", res * -1, exp, nbits);
44964fd1 189 free(cp);
d03fb293
OM
190 return NULL;
191 }
192
193 return &cp->cp;
194}
195
196static void crypto_pk_polarssl_close(struct crypto_pk *_cp)
197{
198 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
199
700d8687 200 mbedtls_rsa_free(&cp->ctx);
d03fb293
OM
201 free(cp);
202}
203
204static unsigned char *crypto_pk_polarssl_encrypt(const struct crypto_pk *_cp, const unsigned char *buf, size_t len, size_t *clen)
205{
206 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
207 int res;
208 unsigned char *result;
209
210 *clen = 0;
700d8687 211 size_t keylen = mbedtls_mpi_size(&cp->ctx.N);
d03fb293
OM
212
213 result = malloc(keylen);
214 if (!result) {
215 printf("RSA encrypt failed. Can't allocate result memory.\n");
216 return NULL;
217 }
218
700d8687 219 res = mbedtls_rsa_public(&cp->ctx, buf, result);
d03fb293 220 if(res) {
b838c4ff 221 printf("RSA encrypt failed. Error: %x data len: %zd key len: %zd\n", res * -1, len, keylen);
44964fd1 222 free(result);
d03fb293
OM
223 return NULL;
224 }
225
226 *clen = keylen;
227
228 return result;
229}
230
231static unsigned char *crypto_pk_polarssl_decrypt(const struct crypto_pk *_cp, const unsigned char *buf, size_t len, size_t *clen)
232{
233 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
234 int res;
235 unsigned char *result;
236
237 *clen = 0;
700d8687 238 size_t keylen = mbedtls_mpi_size(&cp->ctx.N);
d03fb293
OM
239
240 result = malloc(keylen);
241 if (!result) {
242 printf("RSA encrypt failed. Can't allocate result memory.\n");
243 return NULL;
244 }
245
700d8687 246 res = mbedtls_rsa_private(&cp->ctx, NULL, NULL, buf, result); // CHECK???
d03fb293 247 if(res) {
b838c4ff 248 printf("RSA decrypt failed. Error: %x data len: %zd key len: %zd\n", res * -1, len, keylen);
44964fd1 249 free(result);
d03fb293
OM
250 return NULL;
251 }
252
253 *clen = keylen;
254
255 return result;
256}
257
258static size_t crypto_pk_polarssl_get_nbits(const struct crypto_pk *_cp)
259{
260 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
261
262 return cp->ctx.len * 8;
263return 0;
264}
265
266static unsigned char *crypto_pk_polarssl_get_parameter(const struct crypto_pk *_cp, unsigned param, size_t *plen)
267{
268 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
269 unsigned char *result = NULL;
270 switch(param){
271 // mod
272 case 0:
700d8687 273 *plen = mbedtls_mpi_size(&cp->ctx.N);
d03fb293
OM
274 result = malloc(*plen);
275 memset(result, 0x00, *plen);
700d8687 276 mbedtls_mpi_write_binary(&cp->ctx.N, result, *plen);
d03fb293
OM
277 break;
278 // exp
279 case 1:
700d8687 280 *plen = mbedtls_mpi_size(&cp->ctx.E);
d03fb293
OM
281 result = malloc(*plen);
282 memset(result, 0x00, *plen);
700d8687 283 mbedtls_mpi_write_binary(&cp->ctx.E, result, *plen);
d03fb293
OM
284 break;
285 default:
286 printf("Error get parameter. Param=%d", param);
287 break;
288 }
289
290 return result;
291}
292
293static struct crypto_pk *crypto_pk_polarssl_open(enum crypto_algo_pk pk, va_list vl)
294{
295 struct crypto_pk *cp;
296
297 if (pk == PK_RSA)
298 cp = crypto_pk_polarssl_open_rsa(vl);
299 else
300 return NULL;
301
302 cp->close = crypto_pk_polarssl_close;
303 cp->encrypt = crypto_pk_polarssl_encrypt;
304 cp->get_parameter = crypto_pk_polarssl_get_parameter;
305 cp->get_nbits = crypto_pk_polarssl_get_nbits;
306
307 return cp;
308}
309
310static struct crypto_pk *crypto_pk_polarssl_open_priv(enum crypto_algo_pk pk, va_list vl)
311{
312 struct crypto_pk *cp;
313
314 if (pk == PK_RSA)
315 cp = crypto_pk_polarssl_open_priv_rsa(vl);
316 else
317 return NULL;
318
319 cp->close = crypto_pk_polarssl_close;
320 cp->encrypt = crypto_pk_polarssl_encrypt;
321 cp->decrypt = crypto_pk_polarssl_decrypt;
322 cp->get_parameter = crypto_pk_polarssl_get_parameter;
323 cp->get_nbits = crypto_pk_polarssl_get_nbits;
324
325 return cp;
326}
327
328static struct crypto_pk *crypto_pk_polarssl_genkey(enum crypto_algo_pk pk, va_list vl)
329{
330 struct crypto_pk *cp;
331
332 if (pk == PK_RSA)
333 cp = crypto_pk_polarssl_genkey_rsa(vl);
334 else
335 return NULL;
336
337 cp->close = crypto_pk_polarssl_close;
338 cp->encrypt = crypto_pk_polarssl_encrypt;
339 cp->decrypt = crypto_pk_polarssl_decrypt;
340 cp->get_parameter = crypto_pk_polarssl_get_parameter;
341 cp->get_nbits = crypto_pk_polarssl_get_nbits;
342
343 return cp;
344}
345
346static struct crypto_backend crypto_polarssl_backend = {
347 .hash_open = crypto_hash_polarssl_open,
348 .pk_open = crypto_pk_polarssl_open,
349 .pk_open_priv = crypto_pk_polarssl_open_priv,
350 .pk_genkey = crypto_pk_polarssl_genkey,
351};
352
353struct crypto_backend *crypto_polarssl_init(void)
354{
355 return &crypto_polarssl_backend;
356}
Impressum, Datenschutz