2 RSA Asymmetric Cipher Wrapper Implementation over OpenSSL.
4 This file implements following APIs which provide more capabilities for RSA:
10 Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.<BR>
11 SPDX-License-Identifier: BSD-2-Clause-Patent
15 #include "InternalCryptLib.h"
17 #include <openssl/bn.h>
18 #include <openssl/rsa.h>
19 #include <openssl/err.h>
20 #include <openssl/objects.h>
23 Gets the tag-designated RSA key component from the established RSA context.
25 This function retrieves the tag-designated RSA key component from the
26 established RSA context as a non-negative integer (octet string format
27 represented in RSA PKCS#1).
28 If specified key component has not been set or has been cleared, then returned
30 If the BigNumber buffer is too small to hold the contents of the key, FALSE
31 is returned and BnSize is set to the required buffer size to obtain the key.
33 If RsaContext is NULL, then return FALSE.
34 If BnSize is NULL, then return FALSE.
35 If BnSize is large enough but BigNumber is NULL, then return FALSE.
37 @param[in, out] RsaContext Pointer to RSA context being set.
38 @param[in] KeyTag Tag of RSA key component being set.
39 @param[out] BigNumber Pointer to octet integer buffer.
40 @param[in, out] BnSize On input, the size of big number buffer in bytes.
41 On output, the size of data returned in big number buffer in bytes.
43 @retval TRUE RSA key component was retrieved successfully.
44 @retval FALSE Invalid RSA key component tag.
45 @retval FALSE BnSize is too small.
51 IN OUT VOID
*RsaContext
,
52 IN RSA_KEY_TAG KeyTag
,
62 // Check input parameters.
64 if ((RsaContext
== NULL
) || (BnSize
== NULL
)) {
68 RsaKey
= (RSA
*)RsaContext
;
75 // RSA Public Modulus (N)
78 RSA_get0_key (RsaKey
, (const BIGNUM
**)&BnKey
, NULL
, NULL
);
82 // RSA Public Exponent (e)
85 RSA_get0_key (RsaKey
, NULL
, (const BIGNUM
**)&BnKey
, NULL
);
89 // RSA Private Exponent (d)
92 RSA_get0_key (RsaKey
, NULL
, NULL
, (const BIGNUM
**)&BnKey
);
96 // RSA Secret Prime Factor of Modulus (p)
99 RSA_get0_factors (RsaKey
, (const BIGNUM
**)&BnKey
, NULL
);
103 // RSA Secret Prime Factor of Modules (q)
106 RSA_get0_factors (RsaKey
, NULL
, (const BIGNUM
**)&BnKey
);
110 // p's CRT Exponent (== d mod (p - 1))
113 RSA_get0_crt_params (RsaKey
, (const BIGNUM
**)&BnKey
, NULL
, NULL
);
117 // q's CRT Exponent (== d mod (q - 1))
120 RSA_get0_crt_params (RsaKey
, NULL
, (const BIGNUM
**)&BnKey
, NULL
);
124 // The CRT Coefficient (== 1/q mod p)
127 RSA_get0_crt_params (RsaKey
, NULL
, NULL
, (const BIGNUM
**)&BnKey
);
139 Size
= BN_num_bytes (BnKey
);
141 if (*BnSize
< Size
) {
146 if (BigNumber
== NULL
) {
151 *BnSize
= BN_bn2bin (BnKey
, BigNumber
);
157 Generates RSA key components.
159 This function generates RSA key components. It takes RSA public exponent E and
160 length in bits of RSA modulus N as input, and generates all key components.
161 If PublicExponent is NULL, the default RSA public exponent (0x10001) will be used.
163 Before this function can be invoked, pseudorandom number generator must be correctly
164 initialized by RandomSeed().
166 If RsaContext is NULL, then return FALSE.
168 @param[in, out] RsaContext Pointer to RSA context being set.
169 @param[in] ModulusLength Length of RSA modulus N in bits.
170 @param[in] PublicExponent Pointer to RSA public exponent.
171 @param[in] PublicExponentSize Size of RSA public exponent buffer in bytes.
173 @retval TRUE RSA key component was generated successfully.
174 @retval FALSE Invalid RSA key component tag.
180 IN OUT VOID
*RsaContext
,
181 IN UINTN ModulusLength
,
182 IN CONST UINT8
*PublicExponent
,
183 IN UINTN PublicExponentSize
190 // Check input parameters.
192 if ((RsaContext
== NULL
) || (ModulusLength
> INT_MAX
) || (PublicExponentSize
> INT_MAX
)) {
203 if (PublicExponent
== NULL
) {
204 if (BN_set_word (KeyE
, 0x10001) == 0) {
208 if (BN_bin2bn (PublicExponent
, (UINT32
)PublicExponentSize
, KeyE
) == NULL
) {
213 if (RSA_generate_key_ex ((RSA
*)RsaContext
, (UINT32
)ModulusLength
, KeyE
, NULL
) == 1) {
223 Validates key components of RSA context.
224 NOTE: This function performs integrity checks on all the RSA key material, so
225 the RSA key structure must contain all the private key data.
227 This function validates key components of RSA context in following aspects:
228 - Whether p is a prime
229 - Whether q is a prime
231 - Whether d*e = 1 mod lcm(p-1,q-1)
233 If RsaContext is NULL, then return FALSE.
235 @param[in] RsaContext Pointer to RSA context to check.
237 @retval TRUE RSA key components are valid.
238 @retval FALSE RSA key components are not valid.
250 // Check input parameters.
252 if (RsaContext
== NULL
) {
256 if (RSA_check_key ((RSA
*)RsaContext
) != 1) {
257 Reason
= ERR_GET_REASON (ERR_peek_last_error ());
258 if ((Reason
== RSA_R_P_NOT_PRIME
) ||
259 (Reason
== RSA_R_Q_NOT_PRIME
) ||
260 (Reason
== RSA_R_N_DOES_NOT_EQUAL_P_Q
) ||
261 (Reason
== RSA_R_D_E_NOT_CONGRUENT_TO_1
))
271 Carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme.
273 This function carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme defined in
275 If the Signature buffer is too small to hold the contents of signature, FALSE
276 is returned and SigSize is set to the required buffer size to obtain the signature.
278 If RsaContext is NULL, then return FALSE.
279 If MessageHash is NULL, then return FALSE.
280 If HashSize is not equal to the size of MD5, SHA-1, SHA-256, SHA-384 or SHA-512 digest, then return FALSE.
281 If SigSize is large enough but Signature is NULL, then return FALSE.
283 @param[in] RsaContext Pointer to RSA context for signature generation.
284 @param[in] MessageHash Pointer to octet message hash to be signed.
285 @param[in] HashSize Size of the message hash in bytes.
286 @param[out] Signature Pointer to buffer to receive RSA PKCS1-v1_5 signature.
287 @param[in, out] SigSize On input, the size of Signature buffer in bytes.
288 On output, the size of data returned in Signature buffer in bytes.
290 @retval TRUE Signature successfully generated in PKCS1-v1_5.
291 @retval FALSE Signature generation failed.
292 @retval FALSE SigSize is too small.
299 IN CONST UINT8
*MessageHash
,
301 OUT UINT8
*Signature
,
302 IN OUT UINTN
*SigSize
310 // Check input parameters.
312 if ((RsaContext
== NULL
) || (MessageHash
== NULL
)) {
316 Rsa
= (RSA
*)RsaContext
;
317 Size
= RSA_size (Rsa
);
319 if (*SigSize
< Size
) {
324 if (Signature
== NULL
) {
329 // Determine the message digest algorithm according to digest size.
330 // Only MD5, SHA-1, SHA-256, SHA-384 or SHA-512 algorithm is supported.
333 case MD5_DIGEST_SIZE
:
334 DigestType
= NID_md5
;
337 case SHA1_DIGEST_SIZE
:
338 DigestType
= NID_sha1
;
341 case SHA256_DIGEST_SIZE
:
342 DigestType
= NID_sha256
;
345 case SHA384_DIGEST_SIZE
:
346 DigestType
= NID_sha384
;
349 case SHA512_DIGEST_SIZE
:
350 DigestType
= NID_sha512
;
357 return (BOOLEAN
)RSA_sign (