From b5412646db76cfc95b562699cb905befff7311d0 Mon Sep 17 00:00:00 2001 From: Wenxing Hou Date: Sun, 7 Apr 2024 15:21:48 +0800 Subject: CryptoPkg: Add more RSA related functions based on Mbedtls REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4177 Implement more RSA functions such as RsaPkcs1Sign based Mbedlts. Cc: Jiewen Yao Cc: Yi Li Signed-off-by: Wenxing Hou Reviewed-by: Yi Li Acked-by: Jiewen Yao --- .../BaseCryptLibMbedTls/Pk/CryptPkcs1Oaep.c | 278 ++++++++++++++++ .../Library/BaseCryptLibMbedTls/Pk/CryptRsaExt.c | 352 +++++++++++++++++++++ .../BaseCryptLibMbedTls/Pk/CryptRsaPssSign.c | 140 ++++++++ 3 files changed, 770 insertions(+) create mode 100644 CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs1Oaep.c create mode 100644 CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaExt.c create mode 100644 CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaPssSign.c diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs1Oaep.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs1Oaep.c new file mode 100644 index 0000000000..61ccdd78e6 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs1Oaep.c @@ -0,0 +1,278 @@ +/** @file + This file contains UEFI wrapper functions for RSA PKCS1v2 OAEP encryption routines. + + SPDX-License-Identifier: BSD-2-Clause-Patent + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ +**/ + +#include "InternalCryptLib.h" +#include +#include +#include + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to parse X509 certificate. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] PublicKey A pointer to the DER-encoded X509 certificate that + will be used to encrypt the data. + @param[in] PublicKeySize Size of the X509 cert buffer. + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +Pkcs1v2Encrypt ( + IN CONST UINT8 *PublicKey, + IN UINTN PublicKeySize, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + BOOLEAN Result; + UINT32 Ret; + UINT8 *OutData; + mbedtls_x509_crt CertContext; + mbedtls_rsa_context RsaContext; + + // + // Check input parameters. + // + if ((PublicKey == NULL) || (InData == NULL) || + (EncryptedData == NULL) || (EncryptedDataSize == NULL)) + { + return FALSE; + } + + // + // Check public key size. + // + if (PublicKeySize > UINT_MAX) { + // + // Public key size is too large for implementation. + // + return FALSE; + } + + *EncryptedData = NULL; + *EncryptedDataSize = 0; + Result = FALSE; + OutData = NULL; + + mbedtls_x509_crt_init (&CertContext); + + if (mbedtls_x509_crt_parse_der (&CertContext, PublicKey, (UINT32)PublicKeySize) != 0) { + goto _Exit; + } + + if (mbedtls_pk_get_type (&CertContext.pk) != MBEDTLS_PK_RSA) { + goto _Exit; + } + + mbedtls_rsa_init (&RsaContext); + if (mbedtls_rsa_set_padding (&RsaContext, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_NONE) != 0) { + goto _Exit; + } + + Ret = mbedtls_rsa_copy (&RsaContext, mbedtls_pk_rsa (CertContext.pk)); + if (Ret != 0) { + goto _Exit; + } + + *EncryptedDataSize = RsaContext.len; + + // + // Allocate a buffer for the output data. + // + OutData = AllocateZeroPool (*EncryptedDataSize); + if (OutData == NULL) { + // + // Fail to allocate the output buffer. + // + goto _Exit; + } + + Ret = mbedtls_rsa_pkcs1_encrypt ( + &RsaContext, + MbedtlsRand, + NULL, + InDataSize, + InData, + OutData + ); + if (Ret != 0) { + FreePool (OutData); + OutData = NULL; + goto _Exit; + } + + *EncryptedData = OutData; + Result = TRUE; + +_Exit: + // + // Release Resources + // + if (&CertContext != NULL) { + mbedtls_x509_crt_free (&CertContext); + } + + if (&RsaContext != NULL) { + mbedtls_rsa_free (&RsaContext); + } + + return Result; +} + +/** + Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + encrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - X509 key size does not match any known key size. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + - Data size is too large for the provided key size (max size is a function of key size + and hash digest size). + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a public key using RsaSetKey(). + @param[in] InData Data to be encrypted. + @param[in] InDataSize Size of the data buffer. + @param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer + to be used when initializing the PRNG. NULL otherwise. + @param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer. + 0 otherwise. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) + @param[out] EncryptedData Pointer to an allocated buffer containing the encrypted + message. + @param[out] EncryptedDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepEncrypt ( + IN VOID *RsaContext, + IN UINT8 *InData, + IN UINTN InDataSize, + IN CONST UINT8 *PrngSeed OPTIONAL, + IN UINTN PrngSeedSize OPTIONAL, + IN UINT16 DigestLen OPTIONAL, + OUT UINT8 **EncryptedData, + OUT UINTN *EncryptedDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] PrivateKey A pointer to the DER-encoded private key. + @param[in] PrivateKeySize Size of the private key buffer. + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +Pkcs1v2Decrypt ( + IN CONST UINT8 *PrivateKey, + IN UINTN PrivateKeySize, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the + decrypted message in a newly allocated buffer. + + Things that can cause a failure include: + - Fail to parse private key. + - Fail to allocate an intermediate buffer. + - Null pointer provided for a non-optional parameter. + + @param[in] RsaContext A pointer to an RSA context created by RsaNew() and + provisioned with a private key using RsaSetKey(). + @param[in] EncryptedData Data to be decrypted. + @param[in] EncryptedDataSize Size of the encrypted buffer. + @param[in] DigestLen [Optional] If provided, size of the hash used: + SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + SHA384_DIGEST_SIZE + SHA512_DIGEST_SIZE + 0 to use default (SHA1) + @param[out] OutData Pointer to an allocated buffer containing the encrypted + message. + @param[out] OutDataSize Size of the encrypted message buffer. + + @retval TRUE Encryption was successful. + @retval FALSE Encryption failed. + +**/ +BOOLEAN +EFIAPI +RsaOaepDecrypt ( + IN VOID *RsaContext, + IN UINT8 *EncryptedData, + IN UINTN EncryptedDataSize, + IN UINT16 DigestLen OPTIONAL, + OUT UINT8 **OutData, + OUT UINTN *OutDataSize + ) +{ + ASSERT (FALSE); + return FALSE; +} diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaExt.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaExt.c new file mode 100644 index 0000000000..5fe76f146d --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaExt.c @@ -0,0 +1,352 @@ +/** @file + RSA Asymmetric Cipher Wrapper Implementation over MbedTLS. + + This file implements following APIs which provide more capabilities for RSA: + 1) RsaGetKey + 2) RsaGenerateKey + 3) RsaCheckKey + 4) RsaPkcs1Sign + + RFC 8017 - PKCS #1: RSA Cryptography Specifications Version 2.2 + +Copyright (c) 2024, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "InternalCryptLib.h" +#include + +/** + Gets the tag-designated RSA key component from the established RSA context. + + This function retrieves the tag-designated RSA key component from the + established RSA context as a non-negative integer (octet string format + represented in RSA PKCS#1). + If specified key component has not been set or has been cleared, then returned + BnSize is set to 0. + If the BigNumber buffer is too small to hold the contents of the key, FALSE + is returned and BnSize is set to the required buffer size to obtain the key. + + If RsaContext is NULL, then return FALSE. + If BnSize is NULL, then return FALSE. + If BnSize is large enough but BigNumber 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[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 TRUE RSA key component was retrieved successfully. + @retval FALSE Invalid RSA key component tag. + @retval FALSE BnSize is too small. + +**/ +BOOLEAN +EFIAPI +RsaGetKey ( + IN OUT VOID *RsaContext, + IN RSA_KEY_TAG KeyTag, + OUT UINT8 *BigNumber, + IN OUT UINTN *BnSize + ) +{ + mbedtls_rsa_context *RsaKey; + INT32 Ret; + mbedtls_mpi Value; + UINTN Size; + + // + // Check input parameters. + // + if ((RsaContext == NULL) || (*BnSize > INT_MAX)) { + return FALSE; + } + + // + // Init mbedtls_mpi + // + mbedtls_mpi_init (&Value); + Size = *BnSize; + *BnSize = 0; + + RsaKey = (mbedtls_rsa_context *)RsaContext; + + switch (KeyTag) { + case RsaKeyN: + Ret = mbedtls_rsa_export (RsaKey, &Value, NULL, NULL, NULL, NULL); + break; + case RsaKeyE: + Ret = mbedtls_rsa_export (RsaKey, NULL, NULL, NULL, NULL, &Value); + break; + case RsaKeyD: + Ret = mbedtls_rsa_export (RsaKey, NULL, NULL, NULL, &Value, NULL); + break; + case RsaKeyQ: + Ret = mbedtls_rsa_export (RsaKey, NULL, NULL, &Value, NULL, NULL); + break; + case RsaKeyP: + Ret = mbedtls_rsa_export (RsaKey, NULL, &Value, NULL, NULL, NULL); + break; + case RsaKeyDp: + case RsaKeyDq: + case RsaKeyQInv: + default: + Ret = -1; + break; + } + + if (Ret != 0) { + goto End; + } + + if (mbedtls_mpi_size (&Value) == 0) { + Ret = 0; + goto End; + } + + *BnSize = Size; + + Size = mbedtls_mpi_size (&Value); + if (*BnSize < Size) { + Ret = 1; + *BnSize = Size; + goto End; + } + + if (BigNumber == NULL) { + Ret = 0; + *BnSize = Size; + goto End; + } + + if ((BigNumber != NULL) && (Ret == 0)) { + Ret = mbedtls_mpi_write_binary (&Value, BigNumber, Size); + *BnSize = Size; + } + +End: + mbedtls_mpi_free (&Value); + return Ret == 0; +} + +/** + Generates RSA key components. + + This function generates RSA key components. It takes RSA public exponent Pe and + length in bits of RSA modulus N as input, and generates all key components. + If PublicExponent is NULL, the default RSA public exponent (0x10001) will be used. + + Before this function can be invoked, pseudorandom number generator must be correctly + initialized by RandomSeed(). + + If RsaContext is NULL, then return FALSE. + + @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 TRUE RSA key component was generated successfully. + @retval FALSE Invalid RSA key component tag. + +**/ +BOOLEAN +EFIAPI +RsaGenerateKey ( + IN OUT VOID *RsaContext, + IN UINTN ModulusLength, + IN CONST UINT8 *PublicExponent, + IN UINTN PublicExponentSize + ) +{ + INT32 Ret; + mbedtls_rsa_context *Rsa; + INT32 Pe; + + // + // Check input parameters. + // + if ((RsaContext == NULL) || (ModulusLength > INT_MAX) || (PublicExponentSize > INT_MAX)) { + return FALSE; + } + + Rsa = (mbedtls_rsa_context *)RsaContext; + + if (PublicExponent == NULL) { + Pe = 0x10001; + } else { + if (PublicExponentSize == 0) { + return FALSE; + } + + switch (PublicExponentSize) { + case 1: + Pe = PublicExponent[0]; + break; + case 2: + Pe = PublicExponent[0] << 8 | PublicExponent[1]; + break; + case 3: + Pe = PublicExponent[0] << 16 | PublicExponent[1] << 8 | + PublicExponent[2]; + break; + case 4: + Pe = PublicExponent[0] << 24 | PublicExponent[1] << 16 | + PublicExponent[2] << 8 | PublicExponent[3]; + break; + default: + return FALSE; + } + } + + Ret = mbedtls_rsa_gen_key ( + Rsa, + MbedtlsRand, + NULL, + (UINT32)ModulusLength, + Pe + ); + + return Ret == 0; +} + +/** + Validates key components of RSA context. + NOTE: This function performs integrity checks on all the RSA key material, so + the RSA key structure must contain all the private key data. + + This function validates key components of RSA context in following aspects: + - Whether p is a prime + - Whether q is a prime + - Whether n = p * q + - Whether d*e = 1 mod lcm(p-1,q-1) + + If RsaContext is NULL, then return FALSE. + + @param[in] RsaContext Pointer to RSA context to check. + + @retval TRUE RSA key components are valid. + @retval FALSE RSA key components are not valid. + +**/ +BOOLEAN +EFIAPI +RsaCheckKey ( + IN VOID *RsaContext + ) +{ + if (RsaContext == NULL) { + return FALSE; + } + + UINT32 Ret; + + Ret = mbedtls_rsa_complete (RsaContext); + if (Ret == 0) { + Ret = mbedtls_rsa_check_privkey (RsaContext); + } + + return Ret == 0; +} + +/** + Carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme. + + This function carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme defined in + RSA PKCS#1. + 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 MessageHash 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. + If SigSize is large enough but Signature is NULL, then return FALSE. + + @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 TRUE Signature successfully generated in PKCS1-v1_5. + @retval FALSE Signature generation failed. + @retval FALSE SigSize is too small. + +**/ +BOOLEAN +EFIAPI +RsaPkcs1Sign ( + IN VOID *RsaContext, + IN CONST UINT8 *MessageHash, + IN UINTN HashSize, + OUT UINT8 *Signature, + IN OUT UINTN *SigSize + ) +{ + INT32 Ret; + mbedtls_md_type_t MdAlg; + + if ((RsaContext == NULL) || (MessageHash == NULL)) { + return FALSE; + } + + if (mbedtls_rsa_complete ((mbedtls_rsa_context *)RsaContext) != 0) { + return FALSE; + } + + switch (HashSize) { + #ifndef DISABLE_SHA1_DEPRECATED_INTERFACES + case SHA1_DIGEST_SIZE: + MdAlg = MBEDTLS_MD_SHA1; + break; + #endif + + case SHA256_DIGEST_SIZE: + MdAlg = MBEDTLS_MD_SHA256; + break; + + case SHA384_DIGEST_SIZE: + MdAlg = MBEDTLS_MD_SHA384; + break; + + case SHA512_DIGEST_SIZE: + MdAlg = MBEDTLS_MD_SHA512; + break; + + default: + return FALSE; + } + + if (mbedtls_rsa_get_len (RsaContext) > *SigSize) { + *SigSize = mbedtls_rsa_get_len (RsaContext); + return FALSE; + } + + if (Signature == NULL) { + return FALSE; + } + + Ret = mbedtls_rsa_set_padding (RsaContext, MBEDTLS_RSA_PKCS_V15, MdAlg); + if (Ret != 0) { + return FALSE; + } + + Ret = mbedtls_rsa_pkcs1_sign ( + RsaContext, + MbedtlsRand, + NULL, + MdAlg, + (UINT32)HashSize, + MessageHash, + Signature + ); + if (Ret != 0) { + return FALSE; + } + + *SigSize = mbedtls_rsa_get_len (RsaContext); + return TRUE; +} diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaPssSign.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaPssSign.c new file mode 100644 index 0000000000..5555f9261e --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptRsaPssSign.c @@ -0,0 +1,140 @@ +/** @file + RSA PSS Asymmetric Cipher Wrapper Implementation over MbedTLS. + + This file implements following APIs which provide basic capabilities for RSA: + 1) RsaPssSign + +Copyright (c) 2024, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "InternalCryptLib.h" +#include +#include +#include + +/** + 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 + ) +{ + INT32 Ret; + mbedtls_md_type_t MdAlg; + UINT8 HashValue[SHA512_DIGEST_SIZE]; + + if (RsaContext == NULL) { + return FALSE; + } + + if (mbedtls_rsa_complete ((mbedtls_rsa_context *)RsaContext) != 0) { + return FALSE; + } + + if ((Message == NULL) || (MsgSize == 0) || (MsgSize > INT_MAX)) { + return FALSE; + } + + if (SaltLen != DigestLen) { + return FALSE; + } + + ZeroMem (HashValue, DigestLen); + + switch (DigestLen) { + case SHA256_DIGEST_SIZE: + MdAlg = MBEDTLS_MD_SHA256; + if (mbedtls_sha256 (Message, MsgSize, HashValue, FALSE) != 0) { + return FALSE; + } + + break; + + case SHA384_DIGEST_SIZE: + MdAlg = MBEDTLS_MD_SHA384; + if (mbedtls_sha512 (Message, MsgSize, HashValue, TRUE) != 0) { + return FALSE; + } + + break; + + case SHA512_DIGEST_SIZE: + MdAlg = MBEDTLS_MD_SHA512; + if (mbedtls_sha512 (Message, MsgSize, HashValue, FALSE) != 0) { + return FALSE; + } + + break; + + default: + return FALSE; + } + + if (Signature == NULL) { + // + // If Signature is NULL, return safe SignatureSize + // + *SigSize = MBEDTLS_MPI_MAX_SIZE; + return FALSE; + } + + Ret = mbedtls_rsa_set_padding (RsaContext, MBEDTLS_RSA_PKCS_V21, MdAlg); + if (Ret != 0) { + return FALSE; + } + + Ret = mbedtls_rsa_rsassa_pss_sign ( + RsaContext, + MbedtlsRand, + NULL, + MdAlg, + (UINT32)DigestLen, + HashValue, + Signature + ); + if (Ret != 0) { + return FALSE; + } + + *SigSize = ((mbedtls_rsa_context *)RsaContext)->len; + return TRUE; +} -- cgit v1.2.3