REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the CryptoPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
		
			
				
	
	
		
			366 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			366 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  RSA Asymmetric Cipher Wrapper Implementation over OpenSSL.
 | 
						|
 | 
						|
  This file implements following APIs which provide more capabilities for RSA:
 | 
						|
  1) RsaGetKey
 | 
						|
  2) RsaGenerateKey
 | 
						|
  3) RsaCheckKey
 | 
						|
  4) RsaPkcs1Sign
 | 
						|
 | 
						|
Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.<BR>
 | 
						|
SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "InternalCryptLib.h"
 | 
						|
 | 
						|
#include <openssl/bn.h>
 | 
						|
#include <openssl/rsa.h>
 | 
						|
#include <openssl/err.h>
 | 
						|
#include <openssl/objects.h>
 | 
						|
 | 
						|
/**
 | 
						|
  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
 | 
						|
  )
 | 
						|
{
 | 
						|
  RSA     *RsaKey;
 | 
						|
  BIGNUM  *BnKey;
 | 
						|
  UINTN   Size;
 | 
						|
 | 
						|
  //
 | 
						|
  // Check input parameters.
 | 
						|
  //
 | 
						|
  if ((RsaContext == NULL) || (BnSize == NULL)) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  RsaKey  = (RSA *)RsaContext;
 | 
						|
  Size    = *BnSize;
 | 
						|
  *BnSize = 0;
 | 
						|
  BnKey   = NULL;
 | 
						|
 | 
						|
  switch (KeyTag) {
 | 
						|
    //
 | 
						|
    // RSA Public Modulus (N)
 | 
						|
    //
 | 
						|
    case RsaKeyN:
 | 
						|
      RSA_get0_key (RsaKey, (const BIGNUM **)&BnKey, NULL, NULL);
 | 
						|
      break;
 | 
						|
 | 
						|
    //
 | 
						|
    // RSA Public Exponent (e)
 | 
						|
    //
 | 
						|
    case RsaKeyE:
 | 
						|
      RSA_get0_key (RsaKey, NULL, (const BIGNUM **)&BnKey, NULL);
 | 
						|
      break;
 | 
						|
 | 
						|
    //
 | 
						|
    // RSA Private Exponent (d)
 | 
						|
    //
 | 
						|
    case RsaKeyD:
 | 
						|
      RSA_get0_key (RsaKey, NULL, NULL, (const BIGNUM **)&BnKey);
 | 
						|
      break;
 | 
						|
 | 
						|
    //
 | 
						|
    // RSA Secret Prime Factor of Modulus (p)
 | 
						|
    //
 | 
						|
    case RsaKeyP:
 | 
						|
      RSA_get0_factors (RsaKey, (const BIGNUM **)&BnKey, NULL);
 | 
						|
      break;
 | 
						|
 | 
						|
    //
 | 
						|
    // RSA Secret Prime Factor of Modules (q)
 | 
						|
    //
 | 
						|
    case RsaKeyQ:
 | 
						|
      RSA_get0_factors (RsaKey, NULL, (const BIGNUM **)&BnKey);
 | 
						|
      break;
 | 
						|
 | 
						|
    //
 | 
						|
    // p's CRT Exponent (== d mod (p - 1))
 | 
						|
    //
 | 
						|
    case RsaKeyDp:
 | 
						|
      RSA_get0_crt_params (RsaKey, (const BIGNUM **)&BnKey, NULL, NULL);
 | 
						|
      break;
 | 
						|
 | 
						|
    //
 | 
						|
    // q's CRT Exponent (== d mod (q - 1))
 | 
						|
    //
 | 
						|
    case RsaKeyDq:
 | 
						|
      RSA_get0_crt_params (RsaKey, NULL, (const BIGNUM **)&BnKey, NULL);
 | 
						|
      break;
 | 
						|
 | 
						|
    //
 | 
						|
    // The CRT Coefficient (== 1/q mod p)
 | 
						|
    //
 | 
						|
    case RsaKeyQInv:
 | 
						|
      RSA_get0_crt_params (RsaKey, NULL, NULL, (const BIGNUM **)&BnKey);
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (BnKey == NULL) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  *BnSize = Size;
 | 
						|
  Size    = BN_num_bytes (BnKey);
 | 
						|
 | 
						|
  if (*BnSize < Size) {
 | 
						|
    *BnSize = Size;
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (BigNumber == NULL) {
 | 
						|
    *BnSize = Size;
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  *BnSize = BN_bn2bin (BnKey, BigNumber);
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Generates RSA key components.
 | 
						|
 | 
						|
  This function generates RSA key components. It takes RSA public exponent E 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
 | 
						|
  )
 | 
						|
{
 | 
						|
  BIGNUM   *KeyE;
 | 
						|
  BOOLEAN  RetVal;
 | 
						|
 | 
						|
  //
 | 
						|
  // Check input parameters.
 | 
						|
  //
 | 
						|
  if ((RsaContext == NULL) || (ModulusLength > INT_MAX) || (PublicExponentSize > INT_MAX)) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  KeyE = BN_new ();
 | 
						|
  if (KeyE == NULL) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  RetVal = FALSE;
 | 
						|
 | 
						|
  if (PublicExponent == NULL) {
 | 
						|
    if (BN_set_word (KeyE, 0x10001) == 0) {
 | 
						|
      goto _Exit;
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    if (BN_bin2bn (PublicExponent, (UINT32)PublicExponentSize, KeyE) == NULL) {
 | 
						|
      goto _Exit;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (RSA_generate_key_ex ((RSA *)RsaContext, (UINT32)ModulusLength, KeyE, NULL) == 1) {
 | 
						|
    RetVal = TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
_Exit:
 | 
						|
  BN_free (KeyE);
 | 
						|
  return RetVal;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  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
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN  Reason;
 | 
						|
 | 
						|
  //
 | 
						|
  // Check input parameters.
 | 
						|
  //
 | 
						|
  if (RsaContext == NULL) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (RSA_check_key ((RSA *)RsaContext) != 1) {
 | 
						|
    Reason = ERR_GET_REASON (ERR_peek_last_error ());
 | 
						|
    if ((Reason == RSA_R_P_NOT_PRIME) ||
 | 
						|
        (Reason == RSA_R_Q_NOT_PRIME) ||
 | 
						|
        (Reason == RSA_R_N_DOES_NOT_EQUAL_P_Q) ||
 | 
						|
        (Reason == RSA_R_D_E_NOT_CONGRUENT_TO_1))
 | 
						|
    {
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  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
 | 
						|
  )
 | 
						|
{
 | 
						|
  RSA    *Rsa;
 | 
						|
  UINTN  Size;
 | 
						|
  INT32  DigestType;
 | 
						|
 | 
						|
  //
 | 
						|
  // Check input parameters.
 | 
						|
  //
 | 
						|
  if ((RsaContext == NULL) || (MessageHash == NULL)) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  Rsa  = (RSA *)RsaContext;
 | 
						|
  Size = RSA_size (Rsa);
 | 
						|
 | 
						|
  if (*SigSize < Size) {
 | 
						|
    *SigSize = Size;
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (Signature == NULL) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Determine the message digest algorithm according to digest size.
 | 
						|
  //   Only MD5, SHA-1, SHA-256, SHA-384 or SHA-512 algorithm is supported.
 | 
						|
  //
 | 
						|
  switch (HashSize) {
 | 
						|
    case MD5_DIGEST_SIZE:
 | 
						|
      DigestType = NID_md5;
 | 
						|
      break;
 | 
						|
 | 
						|
    case SHA1_DIGEST_SIZE:
 | 
						|
      DigestType = NID_sha1;
 | 
						|
      break;
 | 
						|
 | 
						|
    case SHA256_DIGEST_SIZE:
 | 
						|
      DigestType = NID_sha256;
 | 
						|
      break;
 | 
						|
 | 
						|
    case SHA384_DIGEST_SIZE:
 | 
						|
      DigestType = NID_sha384;
 | 
						|
      break;
 | 
						|
 | 
						|
    case SHA512_DIGEST_SIZE:
 | 
						|
      DigestType = NID_sha512;
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  return (BOOLEAN)RSA_sign (
 | 
						|
                    DigestType,
 | 
						|
                    MessageHash,
 | 
						|
                    (UINT32)HashSize,
 | 
						|
                    Signature,
 | 
						|
                    (UINT32 *)SigSize,
 | 
						|
                    (RSA *)RsaContext
 | 
						|
                    );
 | 
						|
}
 |