3) RsaSetKey\r
4) RsaPkcs1Verify\r
\r
-Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "InternalCryptLib.h"\r
\r
+#include <openssl/bn.h>\r
#include <openssl/rsa.h>\r
-#include <openssl/err.h>\r
-\r
+#include <openssl/objects.h>\r
\r
/**\r
Allocates and initializes one RSA context for subsequent use.\r
This function sets the tag-designated RSA key component into the established\r
RSA context from the user-specified non-negative integer (octet string format\r
represented in RSA PKCS#1).\r
- If BigNumber is NULL, then the specified key componenet in RSA context is cleared.\r
+ If BigNumber is NULL, then the specified key component in RSA context is cleared.\r
\r
If RsaContext is NULL, then return FALSE.\r
\r
@param[in, out] RsaContext Pointer to RSA context being set.\r
@param[in] KeyTag Tag of RSA key component being set.\r
@param[in] BigNumber Pointer to octet integer buffer.\r
- If NULL, then the specified key componenet in RSA\r
+ If NULL, then the specified key component in RSA\r
context is cleared.\r
@param[in] BnSize Size of big number buffer in bytes.\r
If BigNumber is NULL, then it is ignored.\r
IN UINTN BnSize\r
)\r
{\r
- RSA *RsaKey;\r
+ RSA *RsaKey;\r
+ BIGNUM *BnN;\r
+ BIGNUM *BnE;\r
+ BIGNUM *BnD;\r
+ BIGNUM *BnP;\r
+ BIGNUM *BnQ;\r
+ BIGNUM *BnDp;\r
+ BIGNUM *BnDq;\r
+ BIGNUM *BnQInv;\r
\r
//\r
// Check input parameters.\r
return FALSE;\r
}\r
\r
+ BnN = NULL;\r
+ BnE = NULL;\r
+ BnD = NULL;\r
+ BnP = NULL;\r
+ BnQ = NULL;\r
+ BnDp = NULL;\r
+ BnDq = NULL;\r
+ BnQInv = NULL;\r
+\r
+ //\r
+ // Retrieve the components from RSA object.\r
+ //\r
RsaKey = (RSA *) RsaContext;\r
+ RSA_get0_key (RsaKey, (const BIGNUM **)&BnN, (const BIGNUM **)&BnE, (const BIGNUM **)&BnD);\r
+ RSA_get0_factors (RsaKey, (const BIGNUM **)&BnP, (const BIGNUM **)&BnQ);\r
+ RSA_get0_crt_params (RsaKey, (const BIGNUM **)&BnDp, (const BIGNUM **)&BnDq, (const BIGNUM **)&BnQInv);\r
+\r
//\r
// Set RSA Key Components by converting octet string to OpenSSL BN representation.\r
// NOTE: For RSA public key (used in signature verification), only public components\r
switch (KeyTag) {\r
\r
//\r
- // RSA Public Modulus (N)\r
+ // RSA Public Modulus (N), Public Exponent (e) and Private Exponent (d)\r
//\r
case RsaKeyN:\r
- if (RsaKey->n != NULL) {\r
- BN_free (RsaKey->n);\r
- }\r
- RsaKey->n = NULL;\r
- if (BigNumber == NULL) {\r
- break;\r
- }\r
- RsaKey->n = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->n);\r
- if (RsaKey->n == NULL) {\r
- return FALSE;\r
- }\r
-\r
- break;\r
-\r
- //\r
- // RSA Public Exponent (e)\r
- //\r
case RsaKeyE:\r
- if (RsaKey->e != NULL) {\r
- BN_free (RsaKey->e);\r
+ case RsaKeyD:\r
+ if (BnN == NULL) {\r
+ BnN = BN_new ();\r
}\r
- RsaKey->e = NULL;\r
- if (BigNumber == NULL) {\r
- break;\r
+ if (BnE == NULL) {\r
+ BnE = BN_new ();\r
}\r
- RsaKey->e = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->e);\r
- if (RsaKey->e == NULL) {\r
- return FALSE;\r
+ if (BnD == NULL) {\r
+ BnD = BN_new ();\r
}\r
\r
- break;\r
-\r
- //\r
- // RSA Private Exponent (d)\r
- //\r
- case RsaKeyD:\r
- if (RsaKey->d != NULL) {\r
- BN_free (RsaKey->d);\r
- }\r
- RsaKey->d = NULL;\r
- if (BigNumber == NULL) {\r
- break;\r
- }\r
- RsaKey->d = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->d);\r
- if (RsaKey->d == NULL) {\r
+ if ((BnN == NULL) || (BnE == NULL) || (BnD == NULL)) {\r
return FALSE;\r
}\r
\r
- break;\r
-\r
- //\r
- // RSA Secret Prime Factor of Modulus (p)\r
- //\r
- case RsaKeyP:\r
- if (RsaKey->p != NULL) {\r
- BN_free (RsaKey->p);\r
- }\r
- RsaKey->p = NULL;\r
- if (BigNumber == NULL) {\r
+ switch (KeyTag) {\r
+ case RsaKeyN:\r
+ BnN = BN_bin2bn (BigNumber, (UINT32)BnSize, BnN);\r
+ break;\r
+ case RsaKeyE:\r
+ BnE = BN_bin2bn (BigNumber, (UINT32)BnSize, BnE);\r
+ break;\r
+ case RsaKeyD:\r
+ BnD = BN_bin2bn (BigNumber, (UINT32)BnSize, BnD);\r
break;\r
+ default:\r
+ return FALSE;\r
}\r
- RsaKey->p = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->p);\r
- if (RsaKey->p == NULL) {\r
+ if (RSA_set0_key (RsaKey, BN_dup(BnN), BN_dup(BnE), BN_dup(BnD)) == 0) {\r
return FALSE;\r
}\r
\r
break;\r
\r
//\r
- // RSA Secret Prime Factor of Modules (q)\r
+ // RSA Secret Prime Factor of Modulus (p and q)\r
//\r
+ case RsaKeyP:\r
case RsaKeyQ:\r
- if (RsaKey->q != NULL) {\r
- BN_free (RsaKey->q);\r
+ if (BnP == NULL) {\r
+ BnP = BN_new ();\r
}\r
- RsaKey->q = NULL;\r
- if (BigNumber == NULL) {\r
- break;\r
+ if (BnQ == NULL) {\r
+ BnQ = BN_new ();\r
}\r
- RsaKey->q = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->q);\r
- if (RsaKey->q == NULL) {\r
+ if ((BnP == NULL) || (BnQ == NULL)) {\r
return FALSE;\r
}\r
\r
- break;\r
-\r
- //\r
- // p's CRT Exponent (== d mod (p - 1))\r
- //\r
- case RsaKeyDp:\r
- if (RsaKey->dmp1 != NULL) {\r
- BN_free (RsaKey->dmp1);\r
- }\r
- RsaKey->dmp1 = NULL;\r
- if (BigNumber == NULL) {\r
+ switch (KeyTag) {\r
+ case RsaKeyP:\r
+ BnP = BN_bin2bn (BigNumber, (UINT32)BnSize, BnP);\r
break;\r
+ case RsaKeyQ:\r
+ BnQ = BN_bin2bn (BigNumber, (UINT32)BnSize, BnQ);\r
+ break;\r
+ default:\r
+ return FALSE;\r
}\r
- RsaKey->dmp1 = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->dmp1);\r
- if (RsaKey->dmp1 == NULL) {\r
+ if (RSA_set0_factors (RsaKey, BN_dup(BnP), BN_dup(BnQ)) == 0) {\r
return FALSE;\r
}\r
\r
break;\r
\r
//\r
- // q's CRT Exponent (== d mod (q - 1))\r
+ // p's CRT Exponent (== d mod (p - 1)), q's CRT Exponent (== d mod (q - 1)),\r
+ // and CRT Coefficient (== 1/q mod p)\r
//\r
+ case RsaKeyDp:\r
case RsaKeyDq:\r
- if (RsaKey->dmq1 != NULL) {\r
- BN_free (RsaKey->dmq1);\r
+ case RsaKeyQInv:\r
+ if (BnDp == NULL) {\r
+ BnDp = BN_new ();\r
}\r
- RsaKey->dmq1 = NULL;\r
- if (BigNumber == NULL) {\r
- break;\r
+ if (BnDq == NULL) {\r
+ BnDq = BN_new ();\r
}\r
- RsaKey->dmq1 = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->dmq1);\r
- if (RsaKey->dmq1 == NULL) {\r
+ if (BnQInv == NULL) {\r
+ BnQInv = BN_new ();\r
+ }\r
+ if ((BnDp == NULL) || (BnDq == NULL) || (BnQInv == NULL)) {\r
return FALSE;\r
}\r
\r
- break;\r
-\r
- //\r
- // The CRT Coefficient (== 1/q mod p)\r
- //\r
- case RsaKeyQInv:\r
- if (RsaKey->iqmp != NULL) {\r
- BN_free (RsaKey->iqmp);\r
- }\r
- RsaKey->iqmp = NULL;\r
- if (BigNumber == NULL) {\r
+ switch (KeyTag) {\r
+ case RsaKeyDp:\r
+ BnDp = BN_bin2bn (BigNumber, (UINT32)BnSize, BnDp);\r
+ break;\r
+ case RsaKeyDq:\r
+ BnDq = BN_bin2bn (BigNumber, (UINT32)BnSize, BnDq);\r
break;\r
+ case RsaKeyQInv:\r
+ BnQInv = BN_bin2bn (BigNumber, (UINT32)BnSize, BnQInv);\r
+ break;\r
+ default:\r
+ return FALSE;\r
}\r
- RsaKey->iqmp = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->iqmp);\r
- if (RsaKey->iqmp == NULL) {\r
+ if (RSA_set0_crt_params (RsaKey, BN_dup(BnDp), BN_dup(BnDq), BN_dup(BnQInv)) == 0) {\r
return FALSE;\r
}\r
\r
IN UINTN SigSize\r
)\r
{\r
- INTN Length;\r
- UINT8 *DecryptedSigature;\r
+ INT32 DigestType;\r
+ UINT8 *SigBuf;\r
\r
//\r
// Check input parameters.\r
if (SigSize > INT_MAX || SigSize == 0) {\r
return FALSE;\r
}\r
- \r
- //\r
- // Check for unsupported hash size:\r
- // Only MD5, SHA-1 or SHA-256 digest size is supported\r
- //\r
- if (HashSize != MD5_DIGEST_SIZE && HashSize != SHA1_DIGEST_SIZE && HashSize != SHA256_DIGEST_SIZE) {\r
- return FALSE;\r
- }\r
\r
//\r
- // Prepare buffer to store decrypted signature.\r
+ // Determine the message digest algorithm according to digest size.\r
+ // Only MD5, SHA-1 or SHA-256 algorithm is supported.\r
//\r
- DecryptedSigature = (UINT8 *) malloc (SigSize);\r
- if (DecryptedSigature == NULL) {\r
- return FALSE;\r
- }\r
+ switch (HashSize) {\r
+ case MD5_DIGEST_SIZE:\r
+ DigestType = NID_md5;\r
+ break;\r
\r
- //\r
- // RSA PKCS#1 Signature Decoding using OpenSSL RSA Decryption with Public Key\r
- //\r
- Length = RSA_public_decrypt (\r
- (UINT32) SigSize,\r
- Signature,\r
- DecryptedSigature,\r
- RsaContext,\r
- RSA_PKCS1_PADDING\r
- );\r
+ case SHA1_DIGEST_SIZE:\r
+ DigestType = NID_sha1;\r
+ break;\r
\r
- //\r
- // Invalid RSA Key or PKCS#1 Padding Checking Failed (if Length < 0)\r
- // NOTE: Length should be the addition of HashSize and some DER value.\r
- // Ignore more strict length checking here.\r
- //\r
- if (Length < (INTN) HashSize) {\r
- free (DecryptedSigature);\r
- return FALSE;\r
- }\r
+ case SHA256_DIGEST_SIZE:\r
+ DigestType = NID_sha256;\r
+ break;\r
\r
- //\r
- // Validate the MessageHash and Decoded Signature\r
- // NOTE: The decoded Signature should be the DER encoding of the DigestInfo value\r
- // DigestInfo ::= SEQUENCE {\r
- // digestAlgorithm AlgorithmIdentifier\r
- // digest OCTET STRING\r
- // }\r
- // Then Memory Comparing should skip the DER value of the underlying SEQUENCE\r
- // type and AlgorithmIdentifier.\r
- //\r
- if (CompareMem (MessageHash, DecryptedSigature + Length - HashSize, HashSize) == 0) {\r
- //\r
- // Valid RSA PKCS#1 Signature\r
- //\r
- free (DecryptedSigature);\r
- return TRUE;\r
- } else {\r
- //\r
- // Failed to verification\r
- //\r
- free (DecryptedSigature);\r
+ default:\r
return FALSE;\r
}\r
+\r
+ SigBuf = (UINT8 *) Signature;\r
+ return (BOOLEAN) RSA_verify (\r
+ DigestType,\r
+ MessageHash,\r
+ (UINT32) HashSize,\r
+ SigBuf,\r
+ (UINT32) SigSize,\r
+ (RSA *) RsaContext\r
+ );\r
}\r