wolfssl: Add wolfSSL plugin for cryptographic implementations
[strongswan.git] / src / libstrongswan / plugins / wolfssl / wolfssl_rsa_private_key.c
1 /*
2 * Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23 #include "wolfssl_common.h"
24
25 #ifndef NO_RSA
26
27 #include "wolfssl_rsa_private_key.h"
28 #include "wolfssl_rsa_public_key.h"
29 #include "wolfssl_util.h"
30
31 #include <crypto/hashers/hasher.h>
32 #include <utils/debug.h>
33 #include <credentials/keys/signature_params.h>
34
35 #include <wolfssl/wolfcrypt/rsa.h>
36
37 typedef struct private_wolfssl_rsa_private_key_t private_wolfssl_rsa_private_key_t;
38
39 /**
40 * Private data of a wolfssl_rsa_private_key_t object.
41 */
42 struct private_wolfssl_rsa_private_key_t {
43 /**
44 * Public interface for this signer.
45 */
46 wolfssl_rsa_private_key_t public;
47
48 /**
49 * RSA key object from wolfSSL
50 */
51 RsaKey rsa;
52
53 /**
54 * Random number generator to use with RSA operations.
55 */
56 WC_RNG rng;
57
58 /**
59 * reference count
60 */
61 refcount_t ref;
62 };
63
64 /* implemented in rsa public key */
65 bool wolfssl_rsa_fingerprint(RsaKey *rsa, cred_encoding_type_t type, chunk_t *fp);
66
67
68 /**
69 * Build RSA signature
70 */
71 static bool build_signature(private_wolfssl_rsa_private_key_t *this,
72 enum wc_HashType hash, chunk_t data, chunk_t *sig)
73 {
74 int ret = wc_RsaSSL_Sign(data.ptr, data.len, sig->ptr, sig->len, &this->rsa,
75 &this->rng);
76 if (ret > 0)
77 {
78 sig->len = ret;
79 }
80 return ret > 0;
81 }
82
83 /**
84 * Build an EMSA PKCS1 signature described in PKCS#1
85 */
86 static bool build_emsa_pkcs1_signature(private_wolfssl_rsa_private_key_t *this,
87 enum wc_HashType hash, chunk_t data,
88 chunk_t *sig)
89 {
90 bool success = FALSE;
91 chunk_t dgst, encDgst;
92 int ret;
93
94 *sig = chunk_alloc(wc_RsaEncryptSize(&this->rsa));
95
96 if (hash == WC_HASH_TYPE_NONE)
97 {
98 success = build_signature(this, hash, data, sig);
99 }
100 else if (wolfssl_hash_chunk(hash, data, &dgst))
101 {
102 encDgst = chunk_alloc(dgst.len + 20);
103 ret = wc_EncodeSignature(encDgst.ptr, dgst.ptr, dgst.len,
104 wc_HashGetOID(hash));
105 if (ret > 0)
106 {
107 encDgst.len = ret;
108 success = build_signature(this, hash, encDgst, sig);
109 }
110
111 chunk_free(&encDgst);
112 chunk_free(&dgst);
113 }
114
115 if (!success)
116 {
117 chunk_free(sig);
118 }
119 return success;
120 }
121
122 #ifdef WC_RSA_PSS
123 /**
124 * Build an EMSA PSS signature described in PKCS#1
125 */
126 static bool build_emsa_pss_signature(private_wolfssl_rsa_private_key_t *this,
127 rsa_pss_params_t *params, chunk_t data,
128 chunk_t *sig)
129 {
130 bool success = FALSE;
131 chunk_t dgst = chunk_empty;
132 enum wc_HashType hash;
133 int mgf;
134 int ret;
135
136 if (!wolfssl_hash2type(params->hash, &hash))
137 {
138 return FALSE;
139 }
140 if (!wolfssl_hash2mgf1(params->mgf1_hash, &mgf))
141 {
142 return FALSE;
143 }
144
145 *sig = chunk_alloc(wc_RsaEncryptSize(&this->rsa));
146
147 if (wolfssl_hash_chunk(hash, data, &dgst))
148 {
149 ret = wc_RsaPSS_Sign_ex(dgst.ptr, dgst.len, sig->ptr, sig->len, hash,
150 mgf, params->salt_len, &this->rsa, &this->rng);
151 if (ret > 0)
152 {
153 sig->len = ret;
154 success = TRUE;
155 }
156 }
157
158 chunk_free(&dgst);
159 if (!success)
160 {
161 chunk_free(sig);
162 }
163 return success;
164 }
165 #endif
166
167
168 METHOD(private_key_t, get_type, key_type_t,
169 private_wolfssl_rsa_private_key_t *this)
170 {
171 return KEY_RSA;
172 }
173
174 METHOD(private_key_t, sign, bool,
175 private_wolfssl_rsa_private_key_t *this, signature_scheme_t scheme,
176 void *params, chunk_t data, chunk_t *signature)
177 {
178 switch (scheme)
179 {
180 case SIGN_RSA_EMSA_PKCS1_NULL:
181 return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_NONE, data,
182 signature);
183 #ifdef WOLFSSL_SHA224
184 case SIGN_RSA_EMSA_PKCS1_SHA2_224:
185 return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA224, data,
186 signature);
187 #endif
188 #ifndef NO_SHA256
189 case SIGN_RSA_EMSA_PKCS1_SHA2_256:
190 return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA256, data,
191 signature);
192 #endif
193 #ifdef WOLFSSL_SHA384
194 case SIGN_RSA_EMSA_PKCS1_SHA2_384:
195 return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA384, data,
196 signature);
197 #endif
198 #ifdef WOLFSSL_SHA512
199 case SIGN_RSA_EMSA_PKCS1_SHA2_512:
200 return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA512, data,
201 signature);
202 #endif
203 #ifndef NO_SHA
204 case SIGN_RSA_EMSA_PKCS1_SHA1:
205 return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA, data,
206 signature);
207 #endif
208 #ifndef NO_MD5
209 case SIGN_RSA_EMSA_PKCS1_MD5:
210 return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_MD5, data,
211 signature);
212 #endif
213 #ifdef WC_RSA_PSS
214 case SIGN_RSA_EMSA_PSS:
215 return build_emsa_pss_signature(this, params, data, signature);
216 #endif
217 default:
218 DBG1(DBG_LIB, "signature scheme %N not supported in RSA",
219 signature_scheme_names, scheme);
220 return FALSE;
221 }
222 }
223
224 METHOD(private_key_t, decrypt, bool,
225 private_wolfssl_rsa_private_key_t *this, encryption_scheme_t scheme,
226 chunk_t crypto, chunk_t *plain)
227 {
228 int padding, mgf, len;
229 enum wc_HashType hash;
230 char *decrypted;
231
232 switch (scheme)
233 {
234 case ENCRYPT_RSA_PKCS1:
235 hash = WC_HASH_TYPE_NONE;
236 padding = WC_RSA_PKCSV15_PAD;
237 mgf = WC_MGF1NONE;
238 break;
239 #ifndef WC_NO_RSA_OAEP
240 #ifndef NO_SHA
241 case ENCRYPT_RSA_OAEP_SHA1:
242 hash = WC_HASH_TYPE_SHA;
243 padding = WC_RSA_OAEP_PAD;
244 mgf = WC_MGF1SHA1;
245 break;
246 #endif
247 #ifdef WOLFSSL_SHA224
248 case ENCRYPT_RSA_OAEP_SHA224:
249 hash = WC_HASH_TYPE_SHA224;
250 padding = WC_RSA_OAEP_PAD;
251 mgf = WC_MGF1SHA224;
252 break;
253 #endif
254 #ifndef NO_SHA256
255 case ENCRYPT_RSA_OAEP_SHA256:
256 hash = WC_HASH_TYPE_SHA256;
257 padding = WC_RSA_OAEP_PAD;
258 mgf = WC_MGF1SHA256;
259 break;
260 #endif
261 #ifdef WOLFSSL_SHA384
262 case ENCRYPT_RSA_OAEP_SHA384:
263 hash = WC_HASH_TYPE_SHA384;
264 padding = WC_RSA_OAEP_PAD;
265 mgf = WC_MGF1SHA384;
266 break;
267 #endif
268 #ifdef WOLFSSL_SHA512
269 case ENCRYPT_RSA_OAEP_SHA512:
270 hash = WC_HASH_TYPE_SHA512;
271 padding = WC_RSA_OAEP_PAD;
272 mgf = WC_MGF1SHA512;
273 break;
274 #endif
275 #endif
276 default:
277 DBG1(DBG_LIB, "encryption scheme %N not supported via wolfssl",
278 encryption_scheme_names, scheme);
279 return FALSE;
280 }
281 len = wc_RsaEncryptSize(&this->rsa);
282 decrypted = malloc(len);
283 len = wc_RsaPrivateDecrypt_ex(crypto.ptr, crypto.len, decrypted, len,
284 &this->rsa, padding, hash, mgf, NULL, 0);
285 if (len < 0)
286 {
287 DBG1(DBG_LIB, "RSA decryption failed");
288 free(decrypted);
289 return FALSE;
290 }
291 *plain = chunk_create(decrypted, len);
292 return TRUE;
293 }
294
295 METHOD(private_key_t, get_keysize, int,
296 private_wolfssl_rsa_private_key_t *this)
297 {
298 return wc_RsaEncryptSize(&this->rsa) * 8;
299 }
300
301 METHOD(private_key_t, get_public_key, public_key_t*,
302 private_wolfssl_rsa_private_key_t *this)
303 {
304 chunk_t enc;
305 public_key_t *key;
306 int len = wc_RsaEncryptSize(&this->rsa) * 2 + 20;
307
308 enc = chunk_alloc(len);
309 enc.len = wc_RsaKeyToPublicDer(&this->rsa, enc.ptr, len);
310 key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
311 BUILD_BLOB_ASN1_DER, enc, BUILD_END);
312 free(enc.ptr);
313 return key;
314 }
315
316 METHOD(private_key_t, get_fingerprint, bool,
317 private_wolfssl_rsa_private_key_t *this, cred_encoding_type_t type,
318 chunk_t *fingerprint)
319 {
320 return wolfssl_rsa_fingerprint(&this->rsa, type, fingerprint);
321 }
322
323 METHOD(private_key_t, get_encoding, bool,
324 private_wolfssl_rsa_private_key_t *this, cred_encoding_type_t type,
325 chunk_t *encoding)
326 {
327 switch (type)
328 {
329 case PRIVKEY_ASN1_DER:
330 case PRIVKEY_PEM:
331 {
332 bool success = TRUE;
333 int len = wc_RsaEncryptSize(&this->rsa) * 5 + 20;
334
335 *encoding = chunk_alloc(len);
336 len = wc_RsaKeyToDer(&this->rsa, encoding->ptr, len);
337 if (len < 0)
338 {
339 chunk_free(encoding);
340 return FALSE;
341 }
342 encoding->len = len;
343
344 if (type == PRIVKEY_PEM)
345 {
346 chunk_t asn1_encoding = *encoding;
347
348 success = lib->encoding->encode(lib->encoding, PRIVKEY_PEM,
349 NULL, encoding, CRED_PART_RSA_PRIV_ASN1_DER,
350 asn1_encoding, CRED_PART_END);
351 chunk_clear(&asn1_encoding);
352 }
353 return success;
354 }
355 default:
356 return FALSE;
357 }
358 }
359
360 METHOD(private_key_t, get_ref, private_key_t*,
361 private_wolfssl_rsa_private_key_t *this)
362 {
363 ref_get(&this->ref);
364 return &this->public.key;
365 }
366
367 METHOD(private_key_t, destroy, void,
368 private_wolfssl_rsa_private_key_t *this)
369 {
370 if (ref_put(&this->ref))
371 {
372 lib->encoding->clear_cache(lib->encoding, &this->rsa);
373 wc_FreeRsaKey(&this->rsa);
374 wc_FreeRng(&this->rng);
375 free(this);
376 }
377 }
378
379 /**
380 * Internal generic constructor
381 */
382 static private_wolfssl_rsa_private_key_t *create_empty()
383 {
384 private_wolfssl_rsa_private_key_t *this;
385
386 INIT(this,
387 .public = {
388 .key = {
389 .get_type = _get_type,
390 .sign = _sign,
391 .decrypt = _decrypt,
392 .get_keysize = _get_keysize,
393 .get_public_key = _get_public_key,
394 .equals = private_key_equals,
395 .belongs_to = private_key_belongs_to,
396 .get_fingerprint = _get_fingerprint,
397 .has_fingerprint = private_key_has_fingerprint,
398 .get_encoding = _get_encoding,
399 .get_ref = _get_ref,
400 .destroy = _destroy,
401 },
402 },
403 .ref = 1,
404 );
405
406 if (wc_InitRng(&this->rng) != 0)
407 {
408 DBG1(DBG_LIB, "Init RNG failed, rsa private key create failed\n");
409 free(this);
410 return NULL;
411 }
412 if (wc_InitRsaKey(&this->rsa, NULL) != 0)
413 {
414 DBG1(DBG_LIB, "Init RSA failed, rsa private key create failed\n");
415 wc_FreeRng(&this->rng);
416 free(this);
417 return NULL;
418 }
419 this->rsa.rng = &this->rng;
420
421 return this;
422 }
423
424 /*
425 * See header.
426 */
427 wolfssl_rsa_private_key_t *wolfssl_rsa_private_key_gen(key_type_t type,
428 va_list args)
429 {
430 private_wolfssl_rsa_private_key_t *this;
431 u_int key_size = 0;
432
433 while (TRUE)
434 {
435 switch (va_arg(args, builder_part_t))
436 {
437 case BUILD_KEY_SIZE:
438 key_size = va_arg(args, u_int);
439 continue;
440 case BUILD_END:
441 break;
442 default:
443 return NULL;
444 }
445 break;
446 }
447 if (!key_size)
448 {
449 return NULL;
450 }
451
452 this = create_empty();
453 if (this == NULL)
454 {
455 return NULL;
456 }
457
458 if (wc_MakeRsaKey(&this->rsa, key_size, WC_RSA_EXPONENT, &this->rng) < 0)
459 {
460 destroy(this);
461 return NULL;
462 }
463 return &this->public;
464 }
465
466 static bool wolfssl_mp_rand(mp_int* n, WC_RNG* rng, mp_int* r)
467 {
468 int len;
469 int ret;
470
471 /* Ensure the number has enough memory. */
472 ret = mp_set_bit(r, mp_count_bits(n));
473 if (ret == 0)
474 {
475 len = sizeof(*r->dp) * n->used;
476 ret = wc_RNG_GenerateBlock(rng, (byte *)r->dp, len);
477 }
478 if (ret == 0)
479 {
480 ret = mp_mod(r, n, r);
481 }
482
483 return ret == 0;
484 }
485
486 /**
487 * Recover the primes from n, e and d using the algorithm described in
488 * Appendix C of NIST SP 800-56B.
489 */
490 static bool calculate_pq(mp_int *n, mp_int *e, mp_int *d, mp_int *p, mp_int *q,
491 mp_int *t1, mp_int *t2, WC_RNG* rng)
492 {
493 int i, t, j;
494 bool success = FALSE;
495 mp_int* k = p;
496 mp_int* r = p;
497 mp_int* n1 = q;
498 mp_int* g = t2;
499 mp_int* y = t2;
500 mp_int* x = t1;
501
502
503 /* k = (d * e) - 1 */
504 if (mp_mul(k, d, e) != 0)
505 {
506 goto error;
507 }
508 if (mp_sub_d(k, 1, k) != 0)
509 {
510 goto error;
511 }
512 /* k must be even */
513 if (mp_isodd(k))
514 {
515 goto error;
516 }
517 /* k = 2^t * r, where r is the largest odd integer dividing k, and t >= 1 */
518 if (mp_copy(r, k) != 0)
519 {
520 goto error;
521 }
522 for (t = 0; !mp_isodd(r); t++)
523 { /* r = r/2 */
524 if (mp_div_2(r, r) != 0)
525 goto error;
526 }
527 /* we need n-1 below */
528 if (mp_sub_d(n, 1, n1) != 0)
529 {
530 goto error;
531 }
532 for (i = 0; i < 100; i++)
533 { /* generate random integer g in [0, n-1] */
534 if (!wolfssl_mp_rand(n, rng, g))
535 {
536 goto error;
537 }
538 /* y = g^r mod n */
539 if (mp_exptmod(g, r, n, y) != 0)
540 {
541 goto error;
542 }
543 /* try again if y == 1 or y == n-1 */
544 if (mp_isone(y) || mp_cmp(y, n1) == MP_EQ)
545 {
546 continue;
547 }
548 for (j = 0; j < t; j++)
549 { /* x = y^2 mod n */
550 if (mp_sqrmod(y, n, x) != 0)
551 {
552 goto error;
553 }
554 /* stop if x == 1 */
555 if (mp_isone(x))
556 {
557 goto done;
558 }
559 /* retry with new g if x = n-1 */
560 if (mp_cmp(x, n1) == MP_EQ)
561 {
562 break;
563 }
564 /* y = x */
565 if (mp_copy(y, x) != 0)
566 {
567 goto error;
568 }
569 }
570 }
571 goto error;
572
573 done:
574 /* p = gcd(y-1, n) */
575 if (mp_sub_d(y, 1, y) != 0)
576 {
577 goto error;
578 }
579 if (mp_gcd(y, n, p) != 0)
580 {
581 goto error;
582 }
583 /* q = n/p */
584 if (mp_div(n, p, q, NULL) != 0)
585 {
586 goto error;
587 }
588
589 success = TRUE;
590
591 error:
592 return success;
593 }
594
595 /**
596 * Calculates dp = d (mod p-1) or dq = d (mod q-1) for the Chinese remainder
597 * algorithm.
598 */
599 static int dmodpq1(mp_int *d, mp_int *pq, mp_int *res)
600 {
601 /* p|q - 1 */
602 if (mp_sub_d(pq, 1, res) != 0)
603 {
604 return FALSE;
605 }
606 /* d (mod p|q -1) */
607 if (mp_mod(d, res, res) != 0)
608 {
609 return FALSE;
610 }
611
612 return TRUE;
613 }
614
615 /**
616 * Calculates qinv = q^-1 (mod p) for the Chinese remainder algorithm.
617 */
618 static int qinv(mp_int *q, mp_int *p, mp_int *res)
619 {
620 /* q^-1 (mod p) */
621 return mp_invmod(q, p, res) == 0;
622 }
623
624 /*
625 * See header
626 */
627 wolfssl_rsa_private_key_t *wolfssl_rsa_private_key_load(key_type_t type,
628 va_list args)
629 {
630 private_wolfssl_rsa_private_key_t *this;
631 chunk_t blob, n, e, d, p, q, exp1, exp2, coeff;
632 word32 idx;
633 int ret;
634
635 blob = n = e = d = p = q = exp1 = exp2 = coeff = chunk_empty;
636 while (TRUE)
637 {
638 switch (va_arg(args, builder_part_t))
639 {
640 case BUILD_BLOB_ASN1_DER:
641 blob = va_arg(args, chunk_t);
642 continue;
643 case BUILD_RSA_MODULUS:
644 n = va_arg(args, chunk_t);
645 continue;
646 case BUILD_RSA_PUB_EXP:
647 e = va_arg(args, chunk_t);
648 continue;
649 case BUILD_RSA_PRIV_EXP:
650 d = va_arg(args, chunk_t);
651 continue;
652 case BUILD_RSA_PRIME1:
653 p = va_arg(args, chunk_t);
654 continue;
655 case BUILD_RSA_PRIME2:
656 q = va_arg(args, chunk_t);
657 continue;
658 case BUILD_RSA_EXP1:
659 exp1 = va_arg(args, chunk_t);
660 continue;
661 case BUILD_RSA_EXP2:
662 exp2 = va_arg(args, chunk_t);
663 continue;
664 case BUILD_RSA_COEFF:
665 coeff = va_arg(args, chunk_t);
666 continue;
667 case BUILD_END:
668 break;
669 default:
670 return NULL;
671 }
672 break;
673 }
674
675 this = create_empty();
676 if (this == NULL)
677 {
678 return NULL;
679 }
680
681 if (blob.ptr)
682 {
683 idx = 0;
684 ret = wc_RsaPrivateKeyDecode(blob.ptr, &idx, &this->rsa, blob.len);
685 if (ret == 0)
686 {
687 return &this->public;
688 }
689 }
690 else if (n.ptr && e.ptr && d.ptr)
691 {
692 if (mp_read_unsigned_bin(&this->rsa.n, n.ptr, n.len) != 0)
693 {
694 goto error;
695 }
696 if (mp_read_unsigned_bin(&this->rsa.e, e.ptr, e.len) != 0)
697 {
698 goto error;
699 }
700 if (mp_read_unsigned_bin(&this->rsa.d, d.ptr, d.len) != 0)
701 {
702 goto error;
703 }
704 if (p.ptr && q.ptr)
705 {
706 if (mp_read_unsigned_bin(&this->rsa.p, p.ptr, p.len) != 0)
707 {
708 goto error;
709 }
710 if (mp_read_unsigned_bin(&this->rsa.q, q.ptr, q.len) != 0)
711 {
712 goto error;
713 }
714 }
715 else if (!calculate_pq(&this->rsa.n, &this->rsa.e, &this->rsa.d,
716 &this->rsa.p, &this->rsa.q, &this->rsa.dP,
717 &this->rsa.dQ, &this->rng))
718 {
719 DBG1(DBG_LIB, "calculate pq failed, rsa private key load failed\n");
720 goto error;
721 }
722 if (exp1.ptr)
723 {
724 if (mp_read_unsigned_bin(&this->rsa.dP, exp1.ptr, exp1.len) != 0)
725 {
726 goto error;
727 }
728 }
729 else if (!dmodpq1(&this->rsa.d, &this->rsa.p, &this->rsa.dP))
730 {
731 goto error;
732 }
733 if (exp2.ptr)
734 {
735 if (mp_read_unsigned_bin(&this->rsa.dQ, exp2.ptr, exp2.len) != 0)
736 {
737 goto error;
738 }
739 }
740 else if (!dmodpq1(&this->rsa.d, &this->rsa.q, &this->rsa.dQ))
741 {
742 goto error;
743 }
744 if (coeff.ptr)
745 {
746 if (mp_read_unsigned_bin(&this->rsa.u, coeff.ptr, coeff.len) != 0)
747 {
748 goto error;
749 }
750 }
751 else if (!qinv(&this->rsa.q, &this->rsa.p, &this->rsa.u))
752 {
753 goto error;
754 }
755
756 return &this->public;
757 }
758 error:
759 destroy(this);
760 return NULL;
761 }
762
763 #endif /* NO_RSA */