style
[RRG-proxmark3.git] / client / src / emv / crypto_polarssl.c
blobf9603ead5fffbdcc21d2a4ef46808564dc25432a
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
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.
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.
17 #ifdef HAVE_CONFIG_H
18 #include <config.h>
19 #endif
21 #include "crypto_backend.h"
23 #include <stdlib.h> // malloc
24 #include <string.h> // memset
26 #include "rsa.h"
27 #include "sha1.h"
28 #include "ui.h" // printandlog
30 struct crypto_hash_polarssl {
31 struct crypto_hash ch;
32 mbedtls_sha1_context ctx;
35 static void crypto_hash_polarssl_close(struct crypto_hash *_ch) {
36 struct crypto_hash_polarssl *ch = (struct crypto_hash_polarssl *)_ch;
37 free(ch);
40 static void crypto_hash_polarssl_write(struct crypto_hash *_ch, const unsigned char *buf, size_t len) {
41 struct crypto_hash_polarssl *ch = (struct crypto_hash_polarssl *)_ch;
42 mbedtls_sha1_update(&(ch->ctx), buf, len);
45 static unsigned char *crypto_hash_polarssl_read(struct crypto_hash *_ch) {
46 struct crypto_hash_polarssl *ch = (struct crypto_hash_polarssl *)_ch;
47 static unsigned char sha1sum[20];
48 mbedtls_sha1_finish(&(ch->ctx), sha1sum);
49 return sha1sum;
52 static size_t crypto_hash_polarssl_get_size(const struct crypto_hash *ch) {
53 if (ch->algo == HASH_SHA_1)
54 return 20;
55 return 0;
58 static struct crypto_hash *crypto_hash_polarssl_open(enum crypto_algo_hash hash) {
59 if (hash != HASH_SHA_1)
60 return NULL;
62 struct crypto_hash_polarssl *ch = malloc(sizeof(*ch));
64 mbedtls_sha1_starts(&(ch->ctx));
66 ch->ch.write = crypto_hash_polarssl_write;
67 ch->ch.read = crypto_hash_polarssl_read;
68 ch->ch.close = crypto_hash_polarssl_close;
69 ch->ch.get_size = crypto_hash_polarssl_get_size;
71 return &ch->ch;
74 struct crypto_pk_polarssl {
75 struct crypto_pk cp;
76 mbedtls_rsa_context ctx;
79 static struct crypto_pk *crypto_pk_polarssl_open_rsa(va_list vl) {
80 struct crypto_pk_polarssl *cp = malloc(sizeof(*cp));
81 memset(cp, 0x00, sizeof(*cp));
83 char *mod = va_arg(vl, char *); // N
84 int modlen = va_arg(vl, size_t);
85 char *exp = va_arg(vl, char *); // E
86 int explen = va_arg(vl, size_t);
88 mbedtls_rsa_init(&cp->ctx, MBEDTLS_RSA_PKCS_V15, 0);
90 cp->ctx.len = modlen; // size(N) in bytes
91 mbedtls_mpi_read_binary(&cp->ctx.N, (const unsigned char *)mod, modlen);
92 mbedtls_mpi_read_binary(&cp->ctx.E, (const unsigned char *)exp, explen);
94 int res = mbedtls_rsa_check_pubkey(&cp->ctx);
95 if (res != 0) {
96 PrintAndLogEx(WARNING, "PolarSSL public key error res=%x exp=%d mod=%d", res * -1, explen, modlen);
97 free(cp);
98 return NULL;
101 return &cp->cp;
104 static struct crypto_pk *crypto_pk_polarssl_open_priv_rsa(va_list vl) {
105 struct crypto_pk_polarssl *cp = malloc(sizeof(*cp));
106 memset(cp, 0x00, sizeof(*cp));
107 char *mod = va_arg(vl, char *);
108 int modlen = va_arg(vl, size_t);
109 char *exp = va_arg(vl, char *);
110 int explen = va_arg(vl, size_t);
111 char *d = va_arg(vl, char *);
112 int dlen = va_arg(vl, size_t);
113 char *p = va_arg(vl, char *);
114 int plen = va_arg(vl, size_t);
115 char *q = va_arg(vl, char *);
116 int qlen = va_arg(vl, size_t);
117 char *dp = va_arg(vl, char *);
118 int dplen = va_arg(vl, size_t);
119 char *dq = va_arg(vl, char *);
120 int dqlen = va_arg(vl, size_t);
121 // calc QP via Q and P
122 // char *inv = va_arg(vl, char *);
123 // int invlen = va_arg(vl, size_t);
125 mbedtls_rsa_init(&cp->ctx, MBEDTLS_RSA_PKCS_V15, 0);
127 cp->ctx.len = modlen; // size(N) in bytes
128 mbedtls_mpi_read_binary(&cp->ctx.N, (const unsigned char *)mod, modlen);
129 mbedtls_mpi_read_binary(&cp->ctx.E, (const unsigned char *)exp, explen);
131 mbedtls_mpi_read_binary(&cp->ctx.D, (const unsigned char *)d, dlen);
132 mbedtls_mpi_read_binary(&cp->ctx.P, (const unsigned char *)p, plen);
133 mbedtls_mpi_read_binary(&cp->ctx.Q, (const unsigned char *)q, qlen);
134 mbedtls_mpi_read_binary(&cp->ctx.DP, (const unsigned char *)dp, dplen);
135 mbedtls_mpi_read_binary(&cp->ctx.DQ, (const unsigned char *)dq, dqlen);
137 int res = mbedtls_mpi_inv_mod(&cp->ctx.QP, &cp->ctx.Q, &cp->ctx.P);
138 if (res != 0) {
139 PrintAndLogEx(WARNING, "PolarSSL private key error res=%x exp=%d mod=%d", res * -1, explen, modlen);
140 free(cp);
141 return NULL;
144 res = mbedtls_rsa_check_privkey(&cp->ctx);
145 if (res != 0) {
146 PrintAndLogEx(WARNING, "PolarSSL private key error res=%x exp=%d mod=%d", res * -1, explen, modlen);
147 free(cp);
148 return NULL;
151 return &cp->cp;
154 static int myrand(void *rng_state, unsigned char *output, size_t len) {
155 size_t i;
156 (void)rng_state;
158 for (i = 0; i < len; ++i)
159 output[i] = rand();
161 return 0;
164 static struct crypto_pk *crypto_pk_polarssl_genkey_rsa(va_list vl) {
165 struct crypto_pk_polarssl *cp = malloc(sizeof(*cp));
166 memset(cp, 0x00, sizeof(*cp));
168 int transient = va_arg(vl, int);
169 unsigned int nbits = va_arg(vl, unsigned int);
170 unsigned int exp = va_arg(vl, unsigned int);
172 if (transient) {
175 int res = mbedtls_rsa_gen_key(&cp->ctx, &myrand, NULL, nbits, exp);
176 if (res) {
177 PrintAndLogEx(WARNING, "PolarSSL private key generation error res=%x exp=%u nbits=%u", res * -1, exp, nbits);
178 free(cp);
179 return NULL;
182 return &cp->cp;
185 static void crypto_pk_polarssl_close(struct crypto_pk *_cp) {
186 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
188 mbedtls_rsa_free(&cp->ctx);
189 free(cp);
192 static unsigned char *crypto_pk_polarssl_encrypt(const struct crypto_pk *_cp, const unsigned char *buf, size_t len, size_t *clen) {
193 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
194 *clen = 0;
195 size_t keylen = mbedtls_mpi_size(&cp->ctx.N);
197 unsigned char *result = malloc(keylen);
198 if (!result) {
199 PrintAndLogEx(WARNING, "RSA encrypt failed. Can't allocate result memory");
200 return NULL;
203 int res = mbedtls_rsa_public(&cp->ctx, buf, result);
204 if (res) {
205 PrintAndLogEx(WARNING, "RSA encrypt failed. Error: %x data len: %zu key len: %zu", res * -1, len, keylen);
206 free(result);
207 return NULL;
210 *clen = keylen;
211 return result;
214 static unsigned char *crypto_pk_polarssl_decrypt(const struct crypto_pk *_cp, const unsigned char *buf, size_t len, size_t *clen) {
215 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
216 *clen = 0;
217 size_t keylen = mbedtls_mpi_size(&cp->ctx.N);
219 unsigned char *result = malloc(keylen);
220 if (!result) {
221 PrintAndLogEx(WARNING, "RSA encrypt failed. Can't allocate result memory");
222 return NULL;
225 int res = mbedtls_rsa_private(&cp->ctx, NULL, NULL, buf, result); // CHECK???
226 if (res) {
227 PrintAndLogEx(WARNING, "RSA decrypt failed. Error: %x data len: %zu key len: %zu", res * -1, len, keylen);
228 free(result);
229 return NULL;
232 *clen = keylen;
233 return result;
236 static size_t crypto_pk_polarssl_get_nbits(const struct crypto_pk *_cp) {
237 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
238 return cp->ctx.len * 8;
241 static unsigned char *crypto_pk_polarssl_get_parameter(const struct crypto_pk *_cp, unsigned param, size_t *plen) {
242 struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
243 unsigned char *result = NULL;
244 int res;
245 switch (param) {
246 // mod
247 case 0:
248 *plen = mbedtls_mpi_size(&cp->ctx.N);
249 result = malloc(*plen);
250 memset(result, 0x00, *plen);
251 res = mbedtls_mpi_write_binary(&cp->ctx.N, result, *plen);
252 if (res < 0) {
253 PrintAndLogEx(WARNING, "Error write_binary");
254 free(result);
255 result = 0;
257 break;
258 // exp
259 case 1:
260 *plen = mbedtls_mpi_size(&cp->ctx.E);
261 result = malloc(*plen);
262 memset(result, 0x00, *plen);
263 res = mbedtls_mpi_write_binary(&cp->ctx.E, result, *plen);
264 if (res < 0) {
265 PrintAndLogEx(WARNING, "Error write_binary");
266 free(result);
267 result = 0;
269 break;
270 default:
271 PrintAndLogEx(WARNING, "Error get parameter. Param = %u", param);
272 break;
274 return result;
277 static struct crypto_pk *crypto_pk_polarssl_open(enum crypto_algo_pk pk, va_list vl) {
278 struct crypto_pk *cp;
280 if (pk == PK_RSA)
281 cp = crypto_pk_polarssl_open_rsa(vl);
282 else
283 return NULL;
285 cp->close = crypto_pk_polarssl_close;
286 cp->encrypt = crypto_pk_polarssl_encrypt;
287 cp->get_parameter = crypto_pk_polarssl_get_parameter;
288 cp->get_nbits = crypto_pk_polarssl_get_nbits;
290 return cp;
293 static struct crypto_pk *crypto_pk_polarssl_open_priv(enum crypto_algo_pk pk, va_list vl) {
294 struct crypto_pk *cp;
296 if (pk == PK_RSA)
297 cp = crypto_pk_polarssl_open_priv_rsa(vl);
298 else
299 return NULL;
301 cp->close = crypto_pk_polarssl_close;
302 cp->encrypt = crypto_pk_polarssl_encrypt;
303 cp->decrypt = crypto_pk_polarssl_decrypt;
304 cp->get_parameter = crypto_pk_polarssl_get_parameter;
305 cp->get_nbits = crypto_pk_polarssl_get_nbits;
307 return cp;
310 static struct crypto_pk *crypto_pk_polarssl_genkey(enum crypto_algo_pk pk, va_list vl) {
311 struct crypto_pk *cp;
313 if (pk == PK_RSA)
314 cp = crypto_pk_polarssl_genkey_rsa(vl);
315 else
316 return NULL;
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;
324 return cp;
327 static struct crypto_backend crypto_polarssl_backend = {
328 .hash_open = crypto_hash_polarssl_open,
329 .pk_open = crypto_pk_polarssl_open,
330 .pk_open_priv = crypto_pk_polarssl_open_priv,
331 .pk_genkey = crypto_pk_polarssl_genkey,
334 struct crypto_backend *crypto_polarssl_init(void) {
335 return &crypto_polarssl_backend;