2 * Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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
23 #include "wolfssl_common.h"
27 #include "wolfssl_rsa_private_key.h"
28 #include "wolfssl_rsa_public_key.h"
29 #include "wolfssl_util.h"
31 #include <utils/debug.h>
32 #include <crypto/hashers/hasher.h>
33 #include <credentials/keys/signature_params.h>
35 #include <wolfssl/wolfcrypt/rsa.h>
36 #include <wolfssl/wolfcrypt/asn.h>
38 typedef struct private_wolfssl_rsa_private_key_t private_wolfssl_rsa_private_key_t
;
41 * Private data of a wolfssl_rsa_private_key_t object
43 struct private_wolfssl_rsa_private_key_t
{
48 wolfssl_rsa_private_key_t
public;
51 * RSA key object from wolfSSL
56 * Random number generator to use with RSA operations.
66 /* implemented in rsa public key */
67 bool wolfssl_rsa_encode_public(RsaKey
*rsa
, chunk_t
*encoding
);
68 bool wolfssl_rsa_fingerprint(RsaKey
*rsa
, cred_encoding_type_t type
, chunk_t
*fp
);
73 static bool build_signature(private_wolfssl_rsa_private_key_t
*this,
74 enum wc_HashType hash
, chunk_t data
, chunk_t
*sig
)
76 int ret
= wc_RsaSSL_Sign(data
.ptr
, data
.len
, sig
->ptr
, sig
->len
, &this->rsa
,
86 * Build an EMSA PKCS1 signature described in PKCS#1
88 static bool build_emsa_pkcs1_signature(private_wolfssl_rsa_private_key_t
*this,
89 enum wc_HashType hash
, chunk_t data
,
93 chunk_t dgst
, digestInfo
;
96 *sig
= chunk_alloc(wc_RsaEncryptSize(&this->rsa
));
98 if (hash
== WC_HASH_TYPE_NONE
)
100 success
= build_signature(this, hash
, data
, sig
);
102 else if (wolfssl_hash_chunk(hash
, data
, &dgst
))
104 digestInfo
= chunk_alloc(MAX_DER_DIGEST_SZ
);
105 len
= wc_EncodeSignature(digestInfo
.ptr
, dgst
.ptr
, dgst
.len
,
106 wc_HashGetOID(hash
));
109 digestInfo
.len
= len
;
110 success
= build_signature(this, hash
, digestInfo
, sig
);
112 chunk_free(&digestInfo
);
125 * Build an EMSA PSS signature described in PKCS#1
127 static bool build_emsa_pss_signature(private_wolfssl_rsa_private_key_t
*this,
128 rsa_pss_params_t
*params
, chunk_t data
,
131 bool success
= FALSE
;
132 chunk_t dgst
= chunk_empty
;
133 enum wc_HashType hash
;
136 if (!wolfssl_hash2type(params
->hash
, &hash
))
140 if (!wolfssl_hash2mgf1(params
->mgf1_hash
, &mgf
))
145 *sig
= chunk_alloc(wc_RsaEncryptSize(&this->rsa
));
147 if (wolfssl_hash_chunk(hash
, data
, &dgst
))
149 ret
= wc_RsaPSS_Sign_ex(dgst
.ptr
, dgst
.len
, sig
->ptr
, sig
->len
, hash
,
150 mgf
, params
->salt_len
, &this->rsa
, &this->rng
);
168 METHOD(private_key_t
, get_type
, key_type_t
,
169 private_wolfssl_rsa_private_key_t
*this)
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
)
180 case SIGN_RSA_EMSA_PKCS1_NULL
:
181 return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_NONE
, data
,
183 #ifdef WOLFSSL_SHA224
184 case SIGN_RSA_EMSA_PKCS1_SHA2_224
:
185 return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA224
, data
,
189 case SIGN_RSA_EMSA_PKCS1_SHA2_256
:
190 return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA256
, data
,
193 #ifdef WOLFSSL_SHA384
194 case SIGN_RSA_EMSA_PKCS1_SHA2_384
:
195 return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA384
, data
,
198 #ifdef WOLFSSL_SHA512
199 case SIGN_RSA_EMSA_PKCS1_SHA2_512
:
200 return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA512
, data
,
203 #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)
204 case SIGN_RSA_EMSA_PKCS1_SHA3_224
:
205 return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA3_224
,
208 #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
209 case SIGN_RSA_EMSA_PKCS1_SHA3_256
:
210 return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA3_256
,
213 #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)
214 case SIGN_RSA_EMSA_PKCS1_SHA3_384
:
215 return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA3_384
,
218 #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)
219 case SIGN_RSA_EMSA_PKCS1_SHA3_512
:
220 return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA3_512
,
224 case SIGN_RSA_EMSA_PKCS1_SHA1
:
225 return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_SHA
, data
,
229 case SIGN_RSA_EMSA_PKCS1_MD5
:
230 return build_emsa_pkcs1_signature(this, WC_HASH_TYPE_MD5
, data
,
234 case SIGN_RSA_EMSA_PSS
:
235 return build_emsa_pss_signature(this, params
, data
, signature
);
238 DBG1(DBG_LIB
, "signature scheme %N not supported via wolfssl",
239 signature_scheme_names
, scheme
);
244 METHOD(private_key_t
, decrypt
, bool,
245 private_wolfssl_rsa_private_key_t
*this, encryption_scheme_t scheme
,
246 void *params
, chunk_t crypto
, chunk_t
*plain
)
248 int padding
, mgf
, len
;
249 enum wc_HashType hash
;
250 chunk_t label
= chunk_empty
;
254 label
= *(chunk_t
*)params
;
259 case ENCRYPT_RSA_PKCS1
:
260 hash
= WC_HASH_TYPE_NONE
;
261 padding
= WC_RSA_PKCSV15_PAD
;
264 #ifndef WC_NO_RSA_OAEP
266 case ENCRYPT_RSA_OAEP_SHA1
:
267 hash
= WC_HASH_TYPE_SHA
;
268 padding
= WC_RSA_OAEP_PAD
;
272 #ifdef WOLFSSL_SHA224
273 case ENCRYPT_RSA_OAEP_SHA224
:
274 hash
= WC_HASH_TYPE_SHA224
;
275 padding
= WC_RSA_OAEP_PAD
;
280 case ENCRYPT_RSA_OAEP_SHA256
:
281 hash
= WC_HASH_TYPE_SHA256
;
282 padding
= WC_RSA_OAEP_PAD
;
286 #ifdef WOLFSSL_SHA384
287 case ENCRYPT_RSA_OAEP_SHA384
:
288 hash
= WC_HASH_TYPE_SHA384
;
289 padding
= WC_RSA_OAEP_PAD
;
293 #ifdef WOLFSSL_SHA512
294 case ENCRYPT_RSA_OAEP_SHA512
:
295 hash
= WC_HASH_TYPE_SHA512
;
296 padding
= WC_RSA_OAEP_PAD
;
302 DBG1(DBG_LIB
, "encryption scheme %N not supported via wolfssl",
303 encryption_scheme_names
, scheme
);
306 len
= wc_RsaEncryptSize(&this->rsa
);
307 *plain
= chunk_alloc(len
);
308 len
= wc_RsaPrivateDecrypt_ex(crypto
.ptr
, crypto
.len
, plain
->ptr
, len
,
309 &this->rsa
, padding
, hash
, mgf
,
310 label
.ptr
, label
.len
);
313 DBG1(DBG_LIB
, "RSA decryption failed");
321 METHOD(private_key_t
, get_keysize
, int,
322 private_wolfssl_rsa_private_key_t
*this)
324 return wc_RsaEncryptSize(&this->rsa
) * 8;
327 METHOD(private_key_t
, get_public_key
, public_key_t
*,
328 private_wolfssl_rsa_private_key_t
*this)
333 if (!wolfssl_rsa_encode_public(&this->rsa
, &enc
))
337 key
= lib
->creds
->create(lib
->creds
, CRED_PUBLIC_KEY
, KEY_RSA
,
338 BUILD_BLOB_ASN1_DER
, enc
, BUILD_END
);
343 METHOD(private_key_t
, get_fingerprint
, bool,
344 private_wolfssl_rsa_private_key_t
*this, cred_encoding_type_t type
,
345 chunk_t
*fingerprint
)
347 return wolfssl_rsa_fingerprint(&this->rsa
, type
, fingerprint
);
350 METHOD(private_key_t
, get_encoding
, bool,
351 private_wolfssl_rsa_private_key_t
*this, cred_encoding_type_t type
,
356 case PRIVKEY_ASN1_DER
:
362 /* n and d are of keysize length, p and q plus the three CRT
363 * params roughly half that, the version and e are small */
364 len
= wc_RsaEncryptSize(&this->rsa
) * 5 + MAX_SEQ_SZ
;
365 *encoding
= chunk_alloc(len
);
366 len
= wc_RsaKeyToDer(&this->rsa
, encoding
->ptr
, len
);
369 chunk_free(encoding
);
374 if (type
== PRIVKEY_PEM
)
376 chunk_t asn1_encoding
= *encoding
;
378 success
= lib
->encoding
->encode(lib
->encoding
, PRIVKEY_PEM
,
379 NULL
, encoding
, CRED_PART_RSA_PRIV_ASN1_DER
,
380 asn1_encoding
, CRED_PART_END
);
381 chunk_clear(&asn1_encoding
);
390 METHOD(private_key_t
, get_ref
, private_key_t
*,
391 private_wolfssl_rsa_private_key_t
*this)
394 return &this->public.key
;
397 METHOD(private_key_t
, destroy
, void,
398 private_wolfssl_rsa_private_key_t
*this)
400 if (ref_put(&this->ref
))
402 lib
->encoding
->clear_cache(lib
->encoding
, &this->rsa
);
403 wc_FreeRsaKey(&this->rsa
);
404 wc_FreeRng(&this->rng
);
410 * Internal generic constructor
412 static private_wolfssl_rsa_private_key_t
*create_empty()
414 private_wolfssl_rsa_private_key_t
*this;
419 .get_type
= _get_type
,
422 .get_keysize
= _get_keysize
,
423 .get_public_key
= _get_public_key
,
424 .equals
= private_key_equals
,
425 .belongs_to
= private_key_belongs_to
,
426 .get_fingerprint
= _get_fingerprint
,
427 .has_fingerprint
= private_key_has_fingerprint
,
428 .get_encoding
= _get_encoding
,
436 if (wc_InitRng(&this->rng
) != 0)
438 DBG1(DBG_LIB
, "init RNG failed, rsa private key create failed");
442 if (wc_InitRsaKey(&this->rsa
, NULL
) != 0)
444 DBG1(DBG_LIB
, "init RSA failed, rsa private key create failed");
445 wc_FreeRng(&this->rng
);
449 #ifdef WC_RSA_BLINDING
450 this->rsa
.rng
= &this->rng
;
457 * Described in header
459 wolfssl_rsa_private_key_t
*wolfssl_rsa_private_key_gen(key_type_t type
,
462 private_wolfssl_rsa_private_key_t
*this;
467 switch (va_arg(args
, builder_part_t
))
470 key_size
= va_arg(args
, u_int
);
484 this = create_empty();
490 if (wc_MakeRsaKey(&this->rsa
, key_size
, WC_RSA_EXPONENT
, &this->rng
) < 0)
495 return &this->public;
499 * Allocate a random number in the range [0, n-1]
501 static bool wolfssl_mp_rand(mp_int
*n
, WC_RNG
*rng
, mp_int
*r
)
505 /* ensure the number has enough memory. */
506 ret
= mp_set_bit(r
, mp_count_bits(n
));
509 len
= sizeof(*r
->dp
) * n
->used
;
510 ret
= wc_RNG_GenerateBlock(rng
, (byte
*)r
->dp
, len
);
514 ret
= mp_mod(r
, n
, r
);
520 * Recover the primes from n, e and d using the algorithm described in
521 * Appendix C of NIST SP 800-56B.
523 static bool calculate_pq(mp_int
*n
, mp_int
*e
, mp_int
*d
, mp_int
*p
, mp_int
*q
,
524 mp_int
*t1
, mp_int
*t2
, WC_RNG
* rng
)
527 bool success
= FALSE
;
535 /* k = (d * e) - 1 */
536 if (mp_mul(d
, e
, k
) != 0)
540 if (mp_sub_d(k
, 1, k
) != 0)
549 /* k = 2^t * r, where r is the largest odd integer dividing k, and t >= 1 */
550 if (mp_copy(k
, r
) != 0)
554 for (t
= 0; !mp_isodd(r
); t
++)
556 if (mp_div_2(r
, r
) != 0)
559 /* we need n-1 below */
560 if (mp_sub_d(n
, 1, n1
) != 0)
564 for (i
= 0; i
< 100; i
++)
565 { /* generate random integer g in [0, n-1] */
566 if (!wolfssl_mp_rand(n
, rng
, g
))
571 if (mp_exptmod(g
, r
, n
, y
) != 0)
575 /* try again if y == 1 or y == n-1 */
576 if (mp_isone(y
) || mp_cmp(y
, n1
) == MP_EQ
)
580 for (j
= 0; j
< t
; j
++)
581 { /* x = y^2 mod n */
582 if (mp_sqrmod(y
, n
, x
) != 0)
591 /* retry with new g if x = n-1 */
592 if (mp_cmp(x
, n1
) == MP_EQ
)
597 if (mp_copy(x
, y
) != 0)
606 /* p = gcd(y-1, n) */
607 if (mp_sub_d(y
, 1, y
) != 0)
611 if (mp_gcd(y
, n
, p
) != 0)
616 if (mp_div(n
, p
, q
, NULL
) != 0)
628 * Calculates dp = d (mod p-1) or dq = d (mod q-1) for the Chinese remainder
631 static bool dmodpq1(mp_int
*d
, mp_int
*pq
, mp_int
*res
)
635 return mp_sub_d(pq
, 1, res
) == 0 &&
636 mp_mod(d
, res
, res
) == 0;
640 * Calculates qinv = q^-1 (mod p) for the Chinese remainder algorithm.
642 static int qinv(mp_int
*q
, mp_int
*p
, mp_int
*res
)
645 return mp_invmod(q
, p
, res
) == 0;
649 * Described in header
651 wolfssl_rsa_private_key_t
*wolfssl_rsa_private_key_load(key_type_t type
,
654 private_wolfssl_rsa_private_key_t
*this;
655 chunk_t blob
, n
, e
, d
, p
, q
, exp1
, exp2
, coeff
;
659 blob
= n
= e
= d
= p
= q
= exp1
= exp2
= coeff
= chunk_empty
;
662 switch (va_arg(args
, builder_part_t
))
664 case BUILD_BLOB_ASN1_DER
:
665 blob
= va_arg(args
, chunk_t
);
667 case BUILD_RSA_MODULUS
:
668 n
= va_arg(args
, chunk_t
);
670 case BUILD_RSA_PUB_EXP
:
671 e
= va_arg(args
, chunk_t
);
673 case BUILD_RSA_PRIV_EXP
:
674 d
= va_arg(args
, chunk_t
);
676 case BUILD_RSA_PRIME1
:
677 p
= va_arg(args
, chunk_t
);
679 case BUILD_RSA_PRIME2
:
680 q
= va_arg(args
, chunk_t
);
683 exp1
= va_arg(args
, chunk_t
);
686 exp2
= va_arg(args
, chunk_t
);
688 case BUILD_RSA_COEFF
:
689 coeff
= va_arg(args
, chunk_t
);
699 this = create_empty();
708 ret
= wc_RsaPrivateKeyDecode(blob
.ptr
, &idx
, &this->rsa
, blob
.len
);
711 return &this->public;
714 else if (n
.ptr
&& e
.ptr
&& d
.ptr
)
716 this->rsa
.type
= RSA_PRIVATE
;
718 if (mp_read_unsigned_bin(&this->rsa
.n
, n
.ptr
, n
.len
) != 0)
722 if (mp_read_unsigned_bin(&this->rsa
.e
, e
.ptr
, e
.len
) != 0)
726 if (mp_read_unsigned_bin(&this->rsa
.d
, d
.ptr
, d
.len
) != 0)
732 if (mp_read_unsigned_bin(&this->rsa
.p
, p
.ptr
, p
.len
) != 0)
736 if (mp_read_unsigned_bin(&this->rsa
.q
, q
.ptr
, q
.len
) != 0)
741 else if (!calculate_pq(&this->rsa
.n
, &this->rsa
.e
, &this->rsa
.d
,
742 &this->rsa
.p
, &this->rsa
.q
, &this->rsa
.dP
,
743 &this->rsa
.dQ
, &this->rng
))
749 if (mp_read_unsigned_bin(&this->rsa
.dP
, exp1
.ptr
, exp1
.len
) != 0)
754 else if (!dmodpq1(&this->rsa
.d
, &this->rsa
.p
, &this->rsa
.dP
))
760 if (mp_read_unsigned_bin(&this->rsa
.dQ
, exp2
.ptr
, exp2
.len
) != 0)
765 else if (!dmodpq1(&this->rsa
.d
, &this->rsa
.q
, &this->rsa
.dQ
))
771 if (mp_read_unsigned_bin(&this->rsa
.u
, coeff
.ptr
, coeff
.len
) != 0)
776 else if (!qinv(&this->rsa
.q
, &this->rsa
.p
, &this->rsa
.u
))
781 return &this->public;