public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Wenxing Hou" <wenxing.hou@intel.com>
To: devel@edk2.groups.io
Cc: Jiewen Yao <jiewen.yao@intel.com>, Yi Li <yi1.li@intel.com>,
	Xiaoyu Lu <xiaoyu1.lu@intel.com>,
	Guomin Jiang <guomin.jiang@intel.com>
Subject: [edk2-devel] [PATCH v3 05/11] CryptoPkg: Add RSA functions based on Mbedtls
Date: Thu, 28 Sep 2023 23:34:10 +0800	[thread overview]
Message-ID: <20230928153416.537-6-wenxing.hou@intel.com> (raw)
In-Reply-To: <20230928153416.537-1-wenxing.hou@intel.com>

Add RSA APIs.

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4177

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yi Li <yi1.li@intel.com>
Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
---
 .../BaseCryptLibMbedTls/InternalCryptLib.h    |  25 ++
 .../BaseCryptLibMbedTls/Pk/CryptRsaBasic.c    | 278 ++++++++++++++++++
 .../Pk/CryptRsaBasicNull.c                    | 121 ++++++++
 .../BaseCryptLibMbedTls/Pk/CryptRsaExtNull.c  | 117 ++++++++
 .../BaseCryptLibMbedTls/Pk/CryptRsaPss.c      | 174 +++++++++++
 .../BaseCryptLibMbedTls/Pk/CryptRsaPssNull.c  |  46 +++
 .../Pk/CryptRsaPssSignNull.c                  |  60 ++++
 .../UnitTest/Library/BaseCryptLib/RsaTests.c  |  10 +
 8 files changed, 831 insertions(+)
 create mode 100644 CryptoPkg/Library/BaseCryptLibMbedTls/InternalCryptLib.h
 create mode 100644 CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaBasic.c
 create mode 100644 CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaBasicNull.c
 create mode 100644 CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaExtNull.c
 create mode 100644 CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaPss.c
 create mode 100644 CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaPssNull.c
 create mode 100644 CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaPssSignNull.c

diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/InternalCryptLib.h b/CryptoPkg/Library/BaseCryptLibMbedTls/InternalCryptLib.h
new file mode 100644
index 0000000000..039aa32028
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/InternalCryptLib.h
@@ -0,0 +1,25 @@
+/** @file
+  Internal include file for BaseCryptLib.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef INTERNAL_CRYPT_LIB_H_
+#define INTERNAL_CRYPT_LIB_H_
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseCryptLib.h>
+#include <stdio.h>
+
+//
+// We should alwasy add mbedtls/config.h here
+// to ensure the config override takes effect.
+//
+#include <mbedtls/mbedtls_config.h>
+
+#endif
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;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaBasicNull.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaBasicNull.c
new file mode 100644
index 0000000000..3e643509fd
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaBasicNull.c
@@ -0,0 +1,121 @@
+/** @file
+  RSA Asymmetric Cipher Wrapper Null Implementation.
+
+  This file implements following APIs which provide basic capabilities for RSA:
+  1) RsaNew
+  2) RsaFree
+  3) RsaSetKey
+  4) RsaPkcs1Verify
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.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
+  )
+{
+  //
+  // Allocates & Initializes RSA Context
+  //
+  ASSERT (FALSE);
+  return NULL;
+}
+
+/**
+  Release the specified RSA context.
+
+  @param[in]  RsaContext  Pointer to the RSA context to be released.
+
+**/
+VOID
+EFIAPI
+RsaFree (
+  IN  VOID  *RsaContext
+  )
+{
+  //
+  // Free RSA Context
+  //
+  ASSERT (FALSE);
+}
+
+/**
+  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
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  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 or SHA-256 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
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaExtNull.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaExtNull.c
new file mode 100644
index 0000000000..be810fb8ca
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaExtNull.c
@@ -0,0 +1,117 @@
+/** @file
+  RSA Asymmetric Cipher Wrapper Implementation over MbedTLS.
+
+  This file does not provide real capabilities for following APIs in RSA handling:
+  1) RsaGetKey
+  2) RsaGenerateKey
+  3) RsaCheckKey
+  4) RsaPkcs1Sign
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+/**
+  Gets the tag-designated RSA key component from the established RSA context.
+
+  Return FALSE to indicate this interface is not supported.
+
+  @param[in, out]  RsaContext  Pointer to RSA context being set.
+  @param[in]       KeyTag      Tag of RSA key component being set.
+  @param[out]      BigNumber   Pointer to octet integer buffer.
+  @param[in, out]  BnSize      On input, the size of big number buffer in bytes.
+                               On output, the size of data returned in big number buffer in bytes.
+
+  @retval FALSE  This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+RsaGetKey (
+  IN OUT  VOID         *RsaContext,
+  IN      RSA_KEY_TAG  KeyTag,
+  OUT     UINT8        *BigNumber,
+  IN OUT  UINTN        *BnSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Generates RSA key components.
+
+  Return FALSE to indicate this interface is not supported.
+
+  @param[in, out]  RsaContext           Pointer to RSA context being set.
+  @param[in]       ModulusLength        Length of RSA modulus N in bits.
+  @param[in]       PublicExponent       Pointer to RSA public exponent.
+  @param[in]       PublicExponentSize   Size of RSA public exponent buffer in bytes.
+
+  @retval FALSE  This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+RsaGenerateKey (
+  IN OUT  VOID         *RsaContext,
+  IN      UINTN        ModulusLength,
+  IN      CONST UINT8  *PublicExponent,
+  IN      UINTN        PublicExponentSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Validates key components of RSA context.
+
+  Return FALSE to indicate this interface is not supported.
+
+  @param[in]  RsaContext  Pointer to RSA context to check.
+
+  @retval FALSE  This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+RsaCheckKey (
+  IN  VOID  *RsaContext
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme.
+
+  Return FALSE to indicate this interface is not supported.
+
+  @param[in]       RsaContext   Pointer to RSA context for signature generation.
+  @param[in]       MessageHash  Pointer to octet message hash to be signed.
+  @param[in]       HashSize     Size of the message hash in bytes.
+  @param[out]      Signature    Pointer to buffer to receive RSA PKCS1-v1_5 signature.
+  @param[in, out]  SigSize      On input, the size of Signature buffer in bytes.
+                                On output, the size of data returned in Signature buffer in bytes.
+
+  @retval FALSE  This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPkcs1Sign (
+  IN      VOID         *RsaContext,
+  IN      CONST UINT8  *MessageHash,
+  IN      UINTN        HashSize,
+  OUT     UINT8        *Signature,
+  IN OUT  UINTN        *SigSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaPss.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaPss.c
new file mode 100644
index 0000000000..7927c34ae9
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaPss.c
@@ -0,0 +1,174 @@
+/** @file
+  RSA Asymmetric Cipher Wrapper Implementation over MbedTLS.
+
+  This file implements following APIs which provide basic capabilities for RSA:
+  1) RsaPssVerify
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+#include <mbedtls/rsa.h>
+
+/**
+  Verifies the RSA signature with RSASSA-PSS signature scheme defined in RFC 8017.
+  Implementation determines salt length automatically from the signature encoding.
+  Mask generation function is the same as the message digest algorithm.
+  Salt length should be equal to digest length.
+
+  @param[in]  RsaContext      Pointer to RSA context for signature verification.
+  @param[in]  Message         Pointer to octet message to be verified.
+  @param[in]  MsgSize         Size of the message in bytes.
+  @param[in]  Signature       Pointer to RSASSA-PSS signature to be verified.
+  @param[in]  SigSize         Size of signature in bytes.
+  @param[in]  DigestLen       Length of digest for RSA operation.
+  @param[in]  SaltLen         Salt length for PSS encoding.
+
+  @retval  TRUE   Valid signature encoded in RSASSA-PSS.
+  @retval  FALSE  Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssVerify (
+  IN  VOID         *RsaContext,
+  IN  CONST UINT8  *Message,
+  IN  UINTN        MsgSize,
+  IN  CONST UINT8  *Signature,
+  IN  UINTN        SigSize,
+  IN  UINT16       DigestLen,
+  IN  UINT16       SaltLen
+  )
+{
+  INT32                Ret;
+  mbedtls_md_type_t    md_alg;
+  UINT8                HashValue[SHA512_DIGEST_SIZE];
+  BOOLEAN              Status;
+  UINTN                ShaCtxSize;
+  VOID                 *ShaCtx;
+  mbedtls_rsa_context  *RsaKey;
+
+  if (RsaContext == NULL) {
+    return FALSE;
+  }
+
+  if ((Message == NULL) || (MsgSize == 0) || (MsgSize > INT_MAX)) {
+    return FALSE;
+  }
+
+  if (SaltLen != DigestLen) {
+    return FALSE;
+  }
+
+  if ((Signature == NULL) || (SigSize == 0) || (SigSize > INT_MAX)) {
+    return FALSE;
+  }
+
+  RsaKey = (mbedtls_rsa_context *)RsaContext;
+  if (mbedtls_rsa_complete (RsaKey) != 0) {
+    return FALSE;
+  }
+
+  ZeroMem (HashValue, DigestLen);
+
+  switch (DigestLen) {
+    case SHA256_DIGEST_SIZE:
+      md_alg     = MBEDTLS_MD_SHA256;
+      ShaCtxSize = Sha256GetContextSize ();
+      ShaCtx     = AllocateZeroPool (ShaCtxSize);
+
+      Status = Sha256Init (ShaCtx);
+      if (!Status) {
+        return FALSE;
+      }
+
+      Status = Sha256Update (ShaCtx, Message, MsgSize);
+      if (!Status) {
+        FreePool (ShaCtx);
+        return FALSE;
+      }
+
+      Status = Sha256Final (ShaCtx, HashValue);
+      if (!Status) {
+        FreePool (ShaCtx);
+        return FALSE;
+      }
+
+      FreePool (ShaCtx);
+      break;
+
+    case SHA384_DIGEST_SIZE:
+      md_alg     = MBEDTLS_MD_SHA384;
+      ShaCtxSize = Sha384GetContextSize ();
+      ShaCtx     = AllocateZeroPool (ShaCtxSize);
+
+      Status = Sha384Init (ShaCtx);
+      if (!Status) {
+        return FALSE;
+      }
+
+      Status = Sha384Update (ShaCtx, Message, MsgSize);
+      if (!Status) {
+        FreePool (ShaCtx);
+        return FALSE;
+      }
+
+      Status = Sha384Final (ShaCtx, HashValue);
+      if (!Status) {
+        FreePool (ShaCtx);
+        return FALSE;
+      }
+
+      FreePool (ShaCtx);
+      break;
+
+    case SHA512_DIGEST_SIZE:
+      md_alg     = MBEDTLS_MD_SHA512;
+      ShaCtxSize = Sha512GetContextSize ();
+      ShaCtx     = AllocateZeroPool (ShaCtxSize);
+
+      Status = Sha512Init (ShaCtx);
+      if (!Status) {
+        return FALSE;
+      }
+
+      Status = Sha512Update (ShaCtx, Message, MsgSize);
+      if (!Status) {
+        FreePool (ShaCtx);
+        return FALSE;
+      }
+
+      Status = Sha512Final (ShaCtx, HashValue);
+      if (!Status) {
+        FreePool (ShaCtx);
+        return FALSE;
+      }
+
+      FreePool (ShaCtx);
+      break;
+
+    default:
+      return FALSE;
+  }
+
+  if (mbedtls_rsa_get_len (RsaContext) != SigSize) {
+    return FALSE;
+  }
+
+  mbedtls_rsa_set_padding (RsaContext, MBEDTLS_RSA_PKCS_V21, md_alg);
+
+  Ret = mbedtls_rsa_rsassa_pss_verify (
+          RsaContext,
+          md_alg,
+          (UINT32)DigestLen,
+          HashValue,
+          Signature
+          );
+  if (Ret != 0) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaPssNull.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaPssNull.c
new file mode 100644
index 0000000000..75ad71a922
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaPssNull.c
@@ -0,0 +1,46 @@
+/** @file
+  RSA-PSS Asymmetric Cipher Wrapper Implementation over MbedTLS.
+
+  This file does not provide real capabilities for following APIs in RSA handling:
+  1) RsaPssVerify
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+/**
+  Verifies the RSA signature with RSASSA-PSS signature scheme defined in RFC 8017.
+  Implementation determines salt length automatically from the signature encoding.
+  Mask generation function is the same as the message digest algorithm.
+  Salt length should be equal to digest length.
+
+  @param[in]  RsaContext      Pointer to RSA context for signature verification.
+  @param[in]  Message         Pointer to octet message to be verified.
+  @param[in]  MsgSize         Size of the message in bytes.
+  @param[in]  Signature       Pointer to RSASSA-PSS signature to be verified.
+  @param[in]  SigSize         Size of signature in bytes.
+  @param[in]  DigestLen       Length of digest for RSA operation.
+  @param[in]  SaltLen         Salt length for PSS encoding.
+
+  @retval  TRUE   Valid signature encoded in RSASSA-PSS.
+  @retval  FALSE  Invalid signature or invalid RSA context.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssVerify (
+  IN  VOID         *RsaContext,
+  IN  CONST UINT8  *Message,
+  IN  UINTN        MsgSize,
+  IN  CONST UINT8  *Signature,
+  IN  UINTN        SigSize,
+  IN  UINT16       DigestLen,
+  IN  UINT16       SaltLen
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaPssSignNull.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaPssSignNull.c
new file mode 100644
index 0000000000..10687bd38e
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaPssSignNull.c
@@ -0,0 +1,60 @@
+/** @file
+  RSA-PSS Asymmetric Cipher Wrapper Implementation over MbedTLS.
+
+  This file does not provide real capabilities for following APIs in RSA handling:
+  1) RsaPssSign
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+/**
+  Carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme.
+
+  This function carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme defined in
+  RFC 8017.
+  Mask generation function is the same as the message digest algorithm.
+  If the Signature buffer is too small to hold the contents of signature, FALSE
+  is returned and SigSize is set to the required buffer size to obtain the signature.
+
+  If RsaContext is NULL, then return FALSE.
+  If Message is NULL, then return FALSE.
+  If MsgSize is zero or > INT_MAX, then return FALSE.
+  If DigestLen is NOT 32, 48 or 64, return FALSE.
+  If SaltLen is not equal to DigestLen, then return FALSE.
+  If SigSize is large enough but Signature is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      RsaContext   Pointer to RSA context for signature generation.
+  @param[in]      Message      Pointer to octet message to be signed.
+  @param[in]      MsgSize      Size of the message in bytes.
+  @param[in]      DigestLen    Length of the digest in bytes to be used for RSA signature operation.
+  @param[in]      SaltLen      Length of the salt in bytes to be used for PSS encoding.
+  @param[out]     Signature    Pointer to buffer to receive RSA PSS signature.
+  @param[in, out] SigSize      On input, the size of Signature buffer in bytes.
+                               On output, the size of data returned in Signature buffer in bytes.
+
+  @retval  TRUE   Signature successfully generated in RSASSA-PSS.
+  @retval  FALSE  Signature generation failed.
+  @retval  FALSE  SigSize is too small.
+  @retval  FALSE  This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+RsaPssSign (
+  IN      VOID         *RsaContext,
+  IN      CONST UINT8  *Message,
+  IN      UINTN        MsgSize,
+  IN      UINT16       DigestLen,
+  IN      UINT16       SaltLen,
+  OUT     UINT8        *Signature,
+  IN OUT  UINTN        *SigSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c
index 3f06e89b3c..c61f2da73d 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/RsaTests.c
@@ -194,6 +194,9 @@ TestVerifyRsaGenerateKeyComponents (
   BOOLEAN  Status;
   UINTN    KeySize;
   UINT8    *KeyBuffer;
+  UINT8    TestPublicExponent1[] = { 0x03 };
+  UINT8    TestPublicExponent2[] = { 0x01, 0x01 };
+  UINT8    TestPublicExponent3[] = { 0x01, 0x00, 0x01 };
 
   //
   // Generate RSA Key Components
@@ -202,6 +205,13 @@ TestVerifyRsaGenerateKeyComponents (
   Status = RsaGenerateKey (mRsa, RSA_MODULUS_LENGTH, NULL, 0);
   UT_ASSERT_TRUE (Status);
 
+  Status = RsaGenerateKey (mRsa, RSA_MODULUS_LENGTH, TestPublicExponent1, sizeof (TestPublicExponent1));
+  UT_ASSERT_TRUE (Status);
+  Status = RsaGenerateKey (mRsa, RSA_MODULUS_LENGTH, TestPublicExponent2, sizeof (TestPublicExponent2));
+  UT_ASSERT_TRUE (Status);
+  Status = RsaGenerateKey (mRsa, RSA_MODULUS_LENGTH, TestPublicExponent3, sizeof (TestPublicExponent3));
+  UT_ASSERT_TRUE (Status);
+
   KeySize   = RSA_MODULUS_LENGTH / 8;
   KeyBuffer = AllocatePool (KeySize);
   Status    = RsaGetKey (mRsa, RsaKeyE, KeyBuffer, &KeySize);
-- 
2.26.2.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#109157): https://edk2.groups.io/g/devel/message/109157
Mute This Topic: https://groups.io/mt/101639980/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



  parent reply	other threads:[~2023-09-28 15:34 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-28 15:34 [edk2-devel] [PATCH v3 00/11] Add HMAC/HKDF/RSA/HASH/AES features based on Mbedtls Wenxing Hou
2023-09-28 15:34 ` [edk2-devel] [PATCH v3 01/11] CryptoPkg: Add mbedtls submodule for EDKII Wenxing Hou
2023-10-11 18:21   ` Michael D Kinney
2023-09-28 15:34 ` [edk2-devel] [PATCH v3 02/11] CryptoPkg: Add mbedtls_config and MbedTlsLib.inf Wenxing Hou
2023-09-28 15:34 ` [edk2-devel] [PATCH v3 03/11] CryptoPkg: Add HMAC functions based on Mbedtls Wenxing Hou
2023-09-28 15:34 ` [edk2-devel] [PATCH v3 04/11] CryptoPkg: Add HKDF " Wenxing Hou
2023-09-28 15:34 ` Wenxing Hou [this message]
2023-09-28 15:34 ` [edk2-devel] [PATCH v3 06/11] CryptoPkg: Add all .inf files for BaseCryptLibMbedTls Wenxing Hou
2023-12-12  3:52   ` Alexey Kardashevskiy via groups.io
     [not found]   ` <179FF92851F08A90.471@groups.io>
2023-12-12  4:03     ` Alexey Kardashevskiy via groups.io
2023-09-28 15:34 ` [edk2-devel] [PATCH v3 07/11] CryptoPkg: Add Null functions for building pass Wenxing Hou
2023-09-28 15:34 ` [edk2-devel] [PATCH v3 08/11] CryptoPkg: Add MD5/SHA1/SHA2 functions based on Mbedtls Wenxing Hou
2023-09-28 15:34 ` [edk2-devel] [PATCH v3 09/11] CryptoPkg: Add Mbedtls submodule in CI Wenxing Hou
2023-10-11 18:23   ` Michael D Kinney
2023-09-28 15:34 ` [edk2-devel] [PATCH v3 10/11] CryptoPkg: Add basic Readme for BaseCryptLibMbedTls Wenxing Hou
2023-09-28 15:34 ` [edk2-devel] [PATCH v3 11/11] CryptoPkg: Add CryptAes functions based on Mbedtls Add CryptAes APIS Wenxing Hou
2023-10-07 12:38 ` [edk2-devel] [PATCH v3 00/11] Add HMAC/HKDF/RSA/HASH/AES features based on Mbedtls Li, Yi
     [not found] ` <178919F6750E1B48.1188@groups.io>
2023-10-07 13:39   ` [edk2-devel] [PATCH v3 09/11] CryptoPkg: Add Mbedtls submodule in CI Wenxing Hou
2023-10-10  1:49     ` Wenxing Hou
2023-10-11  8:04       ` Li, Yi
     [not found] ` <178BD38EB7306FC4.5378@groups.io>
2023-10-12  5:50   ` [edk2-devel] [PATCH v3 00/11] Add HMAC/HKDF/RSA/HASH/AES features based on Mbedtls Li, Yi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230928153416.537-6-wenxing.hou@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox