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