]> cvs.zerfleddert.de Git - proxmark3-svn/blame - client/emv/crypto_polarssl.c
Merge pull request #531 from pwpiwi/loclass_gpl
[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);
108
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);
153 return NULL;
154 }
155
156 return &cp->cp;
157}
158
159static int myrand(void *rng_state, unsigned char *output, size_t len) {
160 size_t i;
161
162 if(rng_state != NULL)
163 rng_state = NULL;
164
165 for( i = 0; i < len; ++i )
166 output[i] = rand();
167
168 return 0;
169}
170
171
172static struct crypto_pk *crypto_pk_polarssl_genkey_rsa(va_list vl)
173{
174 struct crypto_pk_polarssl *cp = malloc(sizeof(*cp));
175 memset(cp, 0x00, sizeof(*cp));
176
177 int transient = va_arg(vl, int);
178 unsigned int nbits = va_arg(vl, unsigned int);
179 unsigned int exp = va_arg(vl, unsigned int);
180
181 if (transient) {
182 }
183
184 int res = rsa_gen_key(&cp->ctx, &myrand, NULL, nbits, exp);
185 if (res) {
186 fprintf(stderr, "PolarSSL private key generation error res=%x exp=%d nbits=%d.\n", res * -1, exp, nbits);
187 return NULL;
188 }
189
190 return &cp->cp;
191}
192
193static void crypto_pk_polarssl_close(struct crypto_pk *_cp)
194{
195 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
196
197 rsa_free(&cp->ctx);
198 free(cp);
199}
200
201static unsigned char *crypto_pk_polarssl_encrypt(const struct crypto_pk *_cp, const unsigned char *buf, size_t len, size_t *clen)
202{
203 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
204 int res;
205 unsigned char *result;
206
207 *clen = 0;
208 size_t keylen = mpi_size(&cp->ctx.N);
209
210 result = malloc(keylen);
211 if (!result) {
212 printf("RSA encrypt failed. Can't allocate result memory.\n");
213 return NULL;
214 }
215
216 res = rsa_public(&cp->ctx, buf, result);
217 if(res) {
218 printf("RSA encrypt failed. Error: %x data len: %d key len: %d\n", res * -1, len, keylen);
219 return NULL;
220 }
221
222 *clen = keylen;
223
224 return result;
225}
226
227static unsigned char *crypto_pk_polarssl_decrypt(const struct crypto_pk *_cp, const unsigned char *buf, size_t len, size_t *clen)
228{
229 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
230 int res;
231 unsigned char *result;
232
233 *clen = 0;
234 size_t keylen = mpi_size(&cp->ctx.N);
235
236 result = malloc(keylen);
237 if (!result) {
238 printf("RSA encrypt failed. Can't allocate result memory.\n");
239 return NULL;
240 }
241
242 res = rsa_private(&cp->ctx, buf, result); // CHECK???
243 if(res) {
244 printf("RSA decrypt failed. Error: %x data len: %d key len: %d\n", res * -1, len, keylen);
245 return NULL;
246 }
247
248 *clen = keylen;
249
250 return result;
251}
252
253static size_t crypto_pk_polarssl_get_nbits(const struct crypto_pk *_cp)
254{
255 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
256
257 return cp->ctx.len * 8;
258return 0;
259}
260
261static unsigned char *crypto_pk_polarssl_get_parameter(const struct crypto_pk *_cp, unsigned param, size_t *plen)
262{
263 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
264 unsigned char *result = NULL;
265 switch(param){
266 // mod
267 case 0:
268 *plen = mpi_size(&cp->ctx.N);
269 result = malloc(*plen);
270 memset(result, 0x00, *plen);
271 mpi_write_binary(&cp->ctx.N, result, *plen);
272 break;
273 // exp
274 case 1:
275 *plen = mpi_size(&cp->ctx.E);
276 result = malloc(*plen);
277 memset(result, 0x00, *plen);
278 mpi_write_binary(&cp->ctx.E, result, *plen);
279 break;
280 default:
281 printf("Error get parameter. Param=%d", param);
282 break;
283 }
284
285 return result;
286}
287
288static struct crypto_pk *crypto_pk_polarssl_open(enum crypto_algo_pk pk, va_list vl)
289{
290 struct crypto_pk *cp;
291
292 if (pk == PK_RSA)
293 cp = crypto_pk_polarssl_open_rsa(vl);
294 else
295 return NULL;
296
297 cp->close = crypto_pk_polarssl_close;
298 cp->encrypt = crypto_pk_polarssl_encrypt;
299 cp->get_parameter = crypto_pk_polarssl_get_parameter;
300 cp->get_nbits = crypto_pk_polarssl_get_nbits;
301
302 return cp;
303}
304
305static struct crypto_pk *crypto_pk_polarssl_open_priv(enum crypto_algo_pk pk, va_list vl)
306{
307 struct crypto_pk *cp;
308
309 if (pk == PK_RSA)
310 cp = crypto_pk_polarssl_open_priv_rsa(vl);
311 else
312 return NULL;
313
314 cp->close = crypto_pk_polarssl_close;
315 cp->encrypt = crypto_pk_polarssl_encrypt;
316 cp->decrypt = crypto_pk_polarssl_decrypt;
317 cp->get_parameter = crypto_pk_polarssl_get_parameter;
318 cp->get_nbits = crypto_pk_polarssl_get_nbits;
319
320 return cp;
321}
322
323static struct crypto_pk *crypto_pk_polarssl_genkey(enum crypto_algo_pk pk, va_list vl)
324{
325 struct crypto_pk *cp;
326
327 if (pk == PK_RSA)
328 cp = crypto_pk_polarssl_genkey_rsa(vl);
329 else
330 return NULL;
331
332 cp->close = crypto_pk_polarssl_close;
333 cp->encrypt = crypto_pk_polarssl_encrypt;
334 cp->decrypt = crypto_pk_polarssl_decrypt;
335 cp->get_parameter = crypto_pk_polarssl_get_parameter;
336 cp->get_nbits = crypto_pk_polarssl_get_nbits;
337
338 return cp;
339}
340
341static struct crypto_backend crypto_polarssl_backend = {
342 .hash_open = crypto_hash_polarssl_open,
343 .pk_open = crypto_pk_polarssl_open,
344 .pk_open_priv = crypto_pk_polarssl_open_priv,
345 .pk_genkey = crypto_pk_polarssl_genkey,
346};
347
348struct crypto_backend *crypto_polarssl_init(void)
349{
350 return &crypto_polarssl_backend;
351}
Impressum, Datenschutz