summaryrefslogtreecommitdiffstats
path: root/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaBasic.c
diff options
context:
space:
mode:
Diffstat (limited to 'CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaBasic.c')
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaBasic.c278
1 files changed, 278 insertions, 0 deletions
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaBasic.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaBasic.c
new file mode 100644
index 0000000000..8b61ae02ec
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaBasic.c
@@ -0,0 +1,278 @@
+/** @file
+ RSA Asymmetric Cipher Wrapper Implementation over MbedTLS.
+
+ This file implements following APIs which provide basic capabilities for RSA:
+ 1) RsaNew
+ 2) RsaFree
+ 3) RsaSetKey
+ 4) RsaPkcs1Verify
+
+ RFC 8017 - PKCS #1: RSA Cryptography Specifications Version 2.2
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+#include <mbedtls/rsa.h>
+
+/**
+ Allocates and initializes one RSA context for subsequent use.
+
+ @return Pointer to the RSA context that has been initialized.
+ If the allocations fails, RsaNew() returns NULL.
+
+**/
+VOID *
+EFIAPI
+RsaNew (
+ VOID
+ )
+{
+ VOID *RsaContext;
+
+ RsaContext = AllocateZeroPool (sizeof (mbedtls_rsa_context));
+ if (RsaContext == NULL) {
+ return RsaContext;
+ }
+
+ mbedtls_rsa_init (RsaContext);
+ if (mbedtls_rsa_set_padding (RsaContext, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE) != 0) {
+ return NULL;
+ }
+
+ return RsaContext;
+}
+
+/**
+ Release the specified RSA context.
+
+ @param[in] RsaContext Pointer to the RSA context to be released.
+
+**/
+VOID
+EFIAPI
+RsaFree (
+ IN VOID *RsaContext
+ )
+{
+ mbedtls_rsa_free (RsaContext);
+ if (RsaContext != NULL) {
+ FreePool (RsaContext);
+ }
+}
+
+/**
+ Sets the tag-designated key component into the established RSA context.
+
+ This function sets the tag-designated RSA key component into the established
+ RSA context from the user-specified non-negative integer (octet string format
+ represented in RSA PKCS#1).
+ If BigNumber is NULL, then the specified key component in RSA context is cleared.
+
+ If RsaContext is NULL, then return FALSE.
+
+ @param[in, out] RsaContext Pointer to RSA context being set.
+ @param[in] KeyTag Tag of RSA key component being set.
+ @param[in] BigNumber Pointer to octet integer buffer.
+ If NULL, then the specified key component in RSA
+ context is cleared.
+ @param[in] BnSize Size of big number buffer in bytes.
+ If BigNumber is NULL, then it is ignored.
+
+ @retval TRUE RSA key component was set successfully.
+ @retval FALSE Invalid RSA key component tag.
+
+**/
+BOOLEAN
+EFIAPI
+RsaSetKey (
+ IN OUT VOID *RsaContext,
+ IN RSA_KEY_TAG KeyTag,
+ IN CONST UINT8 *BigNumber,
+ IN UINTN BnSize
+ )
+{
+ mbedtls_rsa_context *RsaKey;
+ INT32 Ret;
+ mbedtls_mpi Value;
+
+ //
+ // Check input parameters.
+ //
+ if ((RsaContext == NULL) || (BnSize > INT_MAX)) {
+ return FALSE;
+ }
+
+ mbedtls_mpi_init (&Value);
+
+ RsaKey = (mbedtls_rsa_context *)RsaContext;
+
+ // if BigNumber is Null clear
+ if (BigNumber != NULL) {
+ Ret = mbedtls_mpi_read_binary (&Value, BigNumber, BnSize);
+ if (Ret != 0) {
+ mbedtls_mpi_free (&Value);
+ return FALSE;
+ }
+ }
+
+ switch (KeyTag) {
+ case RsaKeyN:
+ Ret = mbedtls_rsa_import (
+ RsaKey,
+ &Value,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ );
+ break;
+ case RsaKeyE:
+ Ret = mbedtls_rsa_import (
+ RsaKey,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &Value
+ );
+ break;
+ case RsaKeyD:
+ Ret = mbedtls_rsa_import (
+ RsaKey,
+ NULL,
+ NULL,
+ NULL,
+ &Value,
+ NULL
+ );
+ break;
+ case RsaKeyQ:
+ Ret = mbedtls_rsa_import (
+ RsaKey,
+ NULL,
+ NULL,
+ &Value,
+ NULL,
+ NULL
+ );
+ break;
+ case RsaKeyP:
+ Ret = mbedtls_rsa_import (
+ RsaKey,
+ NULL,
+ &Value,
+ NULL,
+ NULL,
+ NULL
+ );
+ break;
+ case RsaKeyDp:
+ case RsaKeyDq:
+ case RsaKeyQInv:
+ default:
+ Ret = -1;
+ break;
+ }
+
+ mbedtls_mpi_free (&Value);
+ return Ret == 0;
+}
+
+/**
+ Verifies the RSA-SSA signature with EMSA-PKCS1-v1_5 encoding scheme defined in
+ RSA PKCS#1.
+
+ If RsaContext is NULL, then return FALSE.
+ If MessageHash is NULL, then return FALSE.
+ If Signature is NULL, then return FALSE.
+ If HashSize is not equal to the size of MD5, SHA-1, SHA-256, SHA-384 or SHA-512 digest, then return FALSE.
+
+ @param[in] RsaContext Pointer to RSA context for signature verification.
+ @param[in] MessageHash Pointer to octet message hash to be checked.
+ @param[in] HashSize Size of the message hash in bytes.
+ @param[in] Signature Pointer to RSA PKCS1-v1_5 signature to be verified.
+ @param[in] SigSize Size of signature in bytes.
+
+ @retval TRUE Valid signature encoded in PKCS1-v1_5.
+ @retval FALSE Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPkcs1Verify (
+ IN VOID *RsaContext,
+ IN CONST UINT8 *MessageHash,
+ IN UINTN HashSize,
+ IN CONST UINT8 *Signature,
+ IN UINTN SigSize
+ )
+{
+ INT32 Ret;
+ mbedtls_md_type_t md_alg;
+ mbedtls_rsa_context *RsaKey;
+
+ if ((RsaContext == NULL) || (MessageHash == NULL) || (Signature == NULL)) {
+ return FALSE;
+ }
+
+ if ((SigSize > INT_MAX) || (SigSize == 0)) {
+ return FALSE;
+ }
+
+ RsaKey = (mbedtls_rsa_context *)RsaContext;
+ if (mbedtls_rsa_complete (RsaKey) != 0) {
+ return FALSE;
+ }
+
+ switch (HashSize) {
+ #ifdef ENABLE_MD5_DEPRECATED_INTERFACES
+ case MD5_DIGEST_SIZE:
+ md_alg = MBEDTLS_MD_MD5;
+ break;
+ #endif
+
+ #ifndef DISABLE_SHA1_DEPRECATED_INTERFACES
+ case SHA1_DIGEST_SIZE:
+ md_alg = MBEDTLS_MD_SHA1;
+ break;
+ #endif
+
+ case SHA256_DIGEST_SIZE:
+ md_alg = MBEDTLS_MD_SHA256;
+ break;
+
+ case SHA384_DIGEST_SIZE:
+ md_alg = MBEDTLS_MD_SHA384;
+ break;
+
+ case SHA512_DIGEST_SIZE:
+ md_alg = MBEDTLS_MD_SHA512;
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ if (mbedtls_rsa_get_len (RsaContext) != SigSize) {
+ return FALSE;
+ }
+
+ mbedtls_rsa_set_padding (RsaContext, MBEDTLS_RSA_PKCS_V15, md_alg);
+
+ Ret = mbedtls_rsa_pkcs1_verify (
+ RsaContext,
+ md_alg,
+ (UINT32)HashSize,
+ MessageHash,
+ Signature
+ );
+ if (Ret != 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}