mirror of
https://git.proxmox.com/git/efi-boot-shim
synced 2025-06-03 16:27:15 +00:00
Update to current Tiano Cryptlib
This commit is contained in:
parent
4bf7fb2ef1
commit
36d13930ee
@ -38,7 +38,7 @@ AesGetContextSize (
|
||||
Initializes user-supplied memory as AES context for subsequent use.
|
||||
|
||||
This function initializes user-supplied memory pointed by AesContext as AES context.
|
||||
In addtion, it sets up all AES key materials for subsequent encryption and decryption
|
||||
In addition, it sets up all AES key materials for subsequent encryption and decryption
|
||||
operations.
|
||||
There are 3 options for key length, 128 bits, 192 bits, and 256 bits.
|
||||
|
||||
@ -241,7 +241,11 @@ AesCbcEncrypt (
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0 || Ivec == NULL || Output == NULL) {
|
||||
if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Ivec == NULL || Output == NULL || InputSize > INT_MAX) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -299,7 +303,11 @@ AesCbcDecrypt (
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0 || Ivec == NULL || Output == NULL) {
|
||||
if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Ivec == NULL || Output == NULL || InputSize > INT_MAX) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -32,14 +32,14 @@ Arc4GetContextSize (
|
||||
// for backup copy. When Arc4Reset() is called, we can use the backup copy to restore
|
||||
// the working copy to the initial state.
|
||||
//
|
||||
return (UINTN) (2 * sizeof(RC4_KEY));
|
||||
return (UINTN) (2 * sizeof (RC4_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes user-supplied memory as ARC4 context for subsequent use.
|
||||
|
||||
This function initializes user-supplied memory pointed by Arc4Context as ARC4 context.
|
||||
In addtion, it sets up all ARC4 key materials for subsequent encryption and decryption
|
||||
In addition, it sets up all ARC4 key materials for subsequent encryption and decryption
|
||||
operations.
|
||||
|
||||
If Arc4Context is NULL, then return FALSE.
|
||||
@ -75,7 +75,7 @@ Arc4Init (
|
||||
|
||||
RC4_set_key (Rc4Key, (UINT32) KeySize, Key);
|
||||
|
||||
CopyMem (Rc4Key + 1, Rc4Key, sizeof(RC4_KEY));
|
||||
CopyMem (Rc4Key + 1, Rc4Key, sizeof (RC4_KEY));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -115,7 +115,7 @@ Arc4Encrypt (
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (Arc4Context == NULL || Input == NULL || Output == NULL) {
|
||||
if (Arc4Context == NULL || Input == NULL || Output == NULL || InputSize > INT_MAX) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -161,7 +161,7 @@ Arc4Decrypt (
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (Arc4Context == NULL || Input == NULL || Output == NULL) {
|
||||
if (Arc4Context == NULL || Input == NULL || Output == NULL || InputSize > INT_MAX) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -205,7 +205,7 @@ Arc4Reset (
|
||||
|
||||
Rc4Key = (RC4_KEY *) Arc4Context;
|
||||
|
||||
CopyMem (Rc4Key, Rc4Key + 1, sizeof(RC4_KEY));
|
||||
CopyMem (Rc4Key, Rc4Key + 1, sizeof (RC4_KEY));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ TdesGetContextSize (
|
||||
Initializes user-supplied memory as TDES context for subsequent use.
|
||||
|
||||
This function initializes user-supplied memory pointed by TdesContext as TDES context.
|
||||
In addtion, it sets up all TDES key materials for subsequent encryption and decryption
|
||||
In addition, it sets up all TDES key materials for subsequent encryption and decryption
|
||||
operations.
|
||||
There are 3 key options as follows:
|
||||
KeyLength = 64, Keying option 1: K1 == K2 == K3 (Backward compatibility with DES)
|
||||
@ -76,9 +76,9 @@ TdesInit (
|
||||
KeySchedule = (DES_key_schedule *) TdesContext;
|
||||
|
||||
//
|
||||
//
|
||||
// If input Key is a weak key, return error.
|
||||
//
|
||||
if (DES_is_weak_key ((const_DES_cblock *) Key)) {
|
||||
if (DES_is_weak_key ((const_DES_cblock *) Key) == 1) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ TdesInit (
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (DES_is_weak_key ((const_DES_cblock *) Key + 8)) {
|
||||
if (DES_is_weak_key ((const_DES_cblock *) Key + 8) == 1) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ TdesInit (
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (DES_is_weak_key ((const_DES_cblock *) Key + 16)) {
|
||||
if (DES_is_weak_key ((const_DES_cblock *) Key + 16) == 1) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -275,7 +275,11 @@ TdesCbcEncrypt (
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0 || Ivec == NULL || Output == NULL) {
|
||||
if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Ivec == NULL || Output == NULL || InputSize > INT_MAX) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -339,7 +343,11 @@ TdesCbcDecrypt (
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0 || Ivec == NULL || Output == NULL) {
|
||||
if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Ivec == NULL || Output == NULL || InputSize > INT_MAX) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ Md4GetContextSize (
|
||||
//
|
||||
// Retrieves the OpenSSL MD4 Context Size
|
||||
//
|
||||
return (UINTN)(sizeof (MD4_CTX));
|
||||
return (UINTN) (sizeof (MD4_CTX));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,7 +61,7 @@ Md4Init (
|
||||
//
|
||||
// OpenSSL MD4 Context Initialization
|
||||
//
|
||||
return (BOOLEAN) (MD4_Init ((MD4_CTX *)Md4Context));
|
||||
return (BOOLEAN) (MD4_Init ((MD4_CTX *) Md4Context));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,7 +139,7 @@ Md4Update (
|
||||
//
|
||||
// OpenSSL MD4 Hash Update
|
||||
//
|
||||
return (BOOLEAN) (MD4_Update ((MD4_CTX *)Md4Context, Data, DataSize));
|
||||
return (BOOLEAN) (MD4_Update ((MD4_CTX *) Md4Context, Data, DataSize));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -179,5 +179,5 @@ Md4Final (
|
||||
//
|
||||
// OpenSSL MD4 Hash Finalization
|
||||
//
|
||||
return (BOOLEAN) (MD4_Final (HashValue, (MD4_CTX *)Md4Context));
|
||||
return (BOOLEAN) (MD4_Final (HashValue, (MD4_CTX *) Md4Context));
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ Md5GetContextSize (
|
||||
//
|
||||
// Retrieves the OpenSSL MD5 Context Size
|
||||
//
|
||||
return (UINTN)(sizeof (MD5_CTX));
|
||||
return (UINTN) (sizeof (MD5_CTX));
|
||||
}
|
||||
|
||||
|
||||
@ -63,7 +63,7 @@ Md5Init (
|
||||
//
|
||||
// OpenSSL MD5 Context Initialization
|
||||
//
|
||||
return (BOOLEAN) (MD5_Init ((MD5_CTX *)Md5Context));
|
||||
return (BOOLEAN) (MD5_Init ((MD5_CTX *) Md5Context));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -141,7 +141,7 @@ Md5Update (
|
||||
//
|
||||
// OpenSSL MD5 Hash Update
|
||||
//
|
||||
return (BOOLEAN) (MD5_Update ((MD5_CTX *)Md5Context, Data, DataSize));
|
||||
return (BOOLEAN) (MD5_Update ((MD5_CTX *) Md5Context, Data, DataSize));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -181,5 +181,5 @@ Md5Final (
|
||||
//
|
||||
// OpenSSL MD5 Hash Finalization
|
||||
//
|
||||
return (BOOLEAN) (MD5_Final (HashValue, (MD5_CTX *)Md5Context));
|
||||
return (BOOLEAN) (MD5_Final (HashValue, (MD5_CTX *) Md5Context));
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ Sha1GetContextSize (
|
||||
//
|
||||
// Retrieves OpenSSL SHA Context Size
|
||||
//
|
||||
return (UINTN)(sizeof (SHA_CTX));
|
||||
return (UINTN) (sizeof (SHA_CTX));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,7 +62,7 @@ Sha1Init (
|
||||
//
|
||||
// OpenSSL SHA-1 Context Initialization
|
||||
//
|
||||
return (BOOLEAN) (SHA1_Init ((SHA_CTX *)Sha1Context));
|
||||
return (BOOLEAN) (SHA1_Init ((SHA_CTX *) Sha1Context));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -140,7 +140,7 @@ Sha1Update (
|
||||
//
|
||||
// OpenSSL SHA-1 Hash Update
|
||||
//
|
||||
return (BOOLEAN) (SHA1_Update ((SHA_CTX *)Sha1Context, Data, DataSize));
|
||||
return (BOOLEAN) (SHA1_Update ((SHA_CTX *) Sha1Context, Data, DataSize));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -180,5 +180,5 @@ Sha1Final (
|
||||
//
|
||||
// OpenSSL SHA-1 Hash Finalization
|
||||
//
|
||||
return (BOOLEAN) (SHA1_Final (HashValue, (SHA_CTX *)Sha1Context));
|
||||
return (BOOLEAN) (SHA1_Final (HashValue, (SHA_CTX *) Sha1Context));
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ Sha256GetContextSize (
|
||||
//
|
||||
// Retrieves OpenSSL SHA-256 Context Size
|
||||
//
|
||||
return (UINTN)(sizeof (SHA256_CTX));
|
||||
return (UINTN) (sizeof (SHA256_CTX));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,7 +61,7 @@ Sha256Init (
|
||||
//
|
||||
// OpenSSL SHA-256 Context Initialization
|
||||
//
|
||||
return (BOOLEAN) (SHA256_Init ((SHA256_CTX *)Sha256Context));
|
||||
return (BOOLEAN) (SHA256_Init ((SHA256_CTX *) Sha256Context));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,7 +139,7 @@ Sha256Update (
|
||||
//
|
||||
// OpenSSL SHA-256 Hash Update
|
||||
//
|
||||
return (BOOLEAN) (SHA256_Update ((SHA256_CTX *)Sha256Context, Data, DataSize));
|
||||
return (BOOLEAN) (SHA256_Update ((SHA256_CTX *) Sha256Context, Data, DataSize));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -179,5 +179,5 @@ Sha256Final (
|
||||
//
|
||||
// OpenSSL SHA-256 Hash Finalization
|
||||
//
|
||||
return (BOOLEAN) (SHA256_Final (HashValue, (SHA256_CTX *)Sha256Context));
|
||||
return (BOOLEAN) (SHA256_Final (HashValue, (SHA256_CTX *) Sha256Context));
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ HmacMd5GetContextSize (
|
||||
//
|
||||
// Retrieves the OpenSSL HMAC-MD5 Context Size
|
||||
//
|
||||
return (UINTN)(sizeof (HMAC_CTX));
|
||||
return (UINTN) (sizeof (HMAC_CTX));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,7 +58,7 @@ HmacMd5Init (
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (HmacMd5Context == NULL) {
|
||||
if (HmacMd5Context == NULL || KeySize > INT_MAX) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ HmacSha1GetContextSize (
|
||||
//
|
||||
// Retrieves the OpenSSL HMAC-SHA1 Context Size
|
||||
//
|
||||
return (UINTN)(sizeof (HMAC_CTX));
|
||||
return (UINTN) (sizeof (HMAC_CTX));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,7 +58,7 @@ HmacSha1Init (
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (HmacSha1Context == NULL) {
|
||||
if (HmacSha1Context == NULL || KeySize > INT_MAX) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseCryptLib.h>
|
||||
|
||||
#include "OpenSslSupport.h"
|
||||
|
||||
//
|
||||
// Environment Setting for OpenSSL-based UEFI Crypto Library.
|
||||
//
|
||||
@ -28,25 +30,5 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#define OPENSSL_SYSNAME_UWIN
|
||||
#endif
|
||||
|
||||
/**
|
||||
Pop single certificate from STACK_OF(X509).
|
||||
|
||||
If X509Stack, Cert, or CertSize is NULL, then return FALSE.
|
||||
|
||||
@param[in] X509Stack Pointer to a X509 stack object.
|
||||
@param[out] Cert Pointer to a X509 certificate.
|
||||
@param[out] CertSize Length of output X509 certificate in bytes.
|
||||
|
||||
@retval TRUE The X509 stack pop succeeded.
|
||||
@retval FALSE The pop operation failed.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
X509PopCertificate (
|
||||
IN VOID *X509Stack,
|
||||
OUT UINT8 **Cert,
|
||||
OUT UINTN *CertSize
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1400,7 +1400,7 @@ RsaPkcs1Verify (
|
||||
IN VOID *RsaContext,
|
||||
IN CONST UINT8 *MessageHash,
|
||||
IN UINTN HashSize,
|
||||
IN UINT8 *Signature,
|
||||
IN CONST UINT8 *Signature,
|
||||
IN UINTN SigSize
|
||||
);
|
||||
|
||||
|
@ -27,7 +27,8 @@ OBJS = Hash/CryptMd4.o \
|
||||
Cipher/CryptTdes.o \
|
||||
Cipher/CryptArc4.o \
|
||||
Rand/CryptRand.o \
|
||||
Pk/CryptRsa.o \
|
||||
Pk/CryptRsaBasic.o \
|
||||
Pk/CryptRsaExt.o \
|
||||
Pk/CryptPkcs7.o \
|
||||
Pk/CryptDh.o \
|
||||
Pk/CryptX509.o \
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
PEM (Privacy Enhanced Mail) Format Handler Wrapper Implementation over OpenSSL.
|
||||
|
||||
Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@ -36,7 +36,7 @@ PasswordCallback (
|
||||
{
|
||||
INTN KeyLength;
|
||||
|
||||
ZeroMem ((VOID *)Buf, (UINTN)Size);
|
||||
ZeroMem ((VOID *) Buf, (UINTN) Size);
|
||||
if (Key != NULL) {
|
||||
//
|
||||
// Duplicate key phrase directly.
|
||||
@ -86,31 +86,41 @@ RsaGetPrivateKeyFromPem (
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Status = FALSE;
|
||||
PemBio = NULL;
|
||||
|
||||
//
|
||||
// Add possible block-cipher descriptor for PEM data decryption.
|
||||
// NOTE: Only support most popular ciphers (3DES, AES) for the encrypted PEM.
|
||||
//
|
||||
EVP_add_cipher (EVP_des_ede3_cbc());
|
||||
EVP_add_cipher (EVP_aes_128_cbc());
|
||||
EVP_add_cipher (EVP_aes_192_cbc());
|
||||
EVP_add_cipher (EVP_aes_256_cbc());
|
||||
if (EVP_add_cipher (EVP_des_ede3_cbc ()) == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
if (EVP_add_cipher (EVP_aes_128_cbc ()) == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
if (EVP_add_cipher (EVP_aes_192_cbc ()) == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
if (EVP_add_cipher (EVP_aes_256_cbc ()) == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Status = FALSE;
|
||||
|
||||
//
|
||||
// Read encrypted PEM Data.
|
||||
//
|
||||
PemBio = BIO_new (BIO_s_mem ());
|
||||
BIO_write (PemBio, PemData, (int)PemSize);
|
||||
if (PemBio == NULL) {
|
||||
goto _Exit;
|
||||
}
|
||||
|
||||
if (BIO_write (PemBio, PemData, (int) PemSize) <= 0) {
|
||||
goto _Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve RSA Private Key from encrypted PEM data.
|
||||
//
|
||||
*RsaContext = PEM_read_bio_RSAPrivateKey (PemBio, NULL, (pem_password_cb *)&PasswordCallback, (void *)Password);
|
||||
*RsaContext = PEM_read_bio_RSAPrivateKey (PemBio, NULL, (pem_password_cb *) &PasswordCallback, (void *) Password);
|
||||
if (*RsaContext != NULL) {
|
||||
Status = TRUE;
|
||||
}
|
||||
|
@ -26,6 +26,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pkcs7.h>
|
||||
|
||||
//
|
||||
// OID ASN.1 Value for SPC_INDIRECT_DATA_OBJID
|
||||
//
|
||||
UINT8 mSpcIndirectOidValue[] = {
|
||||
0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x04
|
||||
};
|
||||
|
||||
/**
|
||||
Verifies the validility of a PE/COFF Authenticode Signature as described in "Windows
|
||||
@ -70,6 +76,7 @@ AuthenticodeVerify (
|
||||
UINT8 *SpcIndirectDataContent;
|
||||
UINT8 Asn1Byte;
|
||||
UINTN ContentSize;
|
||||
UINT8 *SpcIndirectDataOid;
|
||||
|
||||
//
|
||||
// Check input parameters.
|
||||
@ -106,6 +113,19 @@ AuthenticodeVerify (
|
||||
// some authenticode-specific structure. Use opaque ASN.1 string to retrieve
|
||||
// PKCS#7 ContentInfo here.
|
||||
//
|
||||
SpcIndirectDataOid = (UINT8 *)(Pkcs7->d.sign->contents->type->data);
|
||||
if (CompareMem (
|
||||
SpcIndirectDataOid,
|
||||
mSpcIndirectOidValue,
|
||||
sizeof (mSpcIndirectOidValue)
|
||||
) != 0) {
|
||||
//
|
||||
// Un-matched SPC_INDIRECT_DATA_OBJID.
|
||||
//
|
||||
goto _Exit;
|
||||
}
|
||||
|
||||
|
||||
SpcIndirectDataContent = (UINT8 *)(Pkcs7->d.sign->contents->d.other->value.asn1_string->data);
|
||||
|
||||
//
|
||||
|
@ -32,7 +32,7 @@ DhNew (
|
||||
//
|
||||
// Allocates & Initializes DH Context by OpenSSL DH_new()
|
||||
//
|
||||
return (VOID *)DH_new ();
|
||||
return (VOID *) DH_new ();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,7 +52,7 @@ DhFree (
|
||||
//
|
||||
// Free OpenSSL DH Context
|
||||
//
|
||||
DH_free ((DH *)DhContext);
|
||||
DH_free ((DH *) DhContext);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -91,7 +91,7 @@ DhGenerateParameter (
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (DhContext == NULL || Prime == NULL) {
|
||||
if (DhContext == NULL || Prime == NULL || PrimeLength > INT_MAX) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -139,12 +139,13 @@ DhSetParameter (
|
||||
IN CONST UINT8 *Prime
|
||||
)
|
||||
{
|
||||
DH *Dh;
|
||||
DH *Dh;
|
||||
BIGNUM *Bn;
|
||||
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (DhContext == NULL || Prime == NULL) {
|
||||
if (DhContext == NULL || Prime == NULL || PrimeLength > INT_MAX) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -152,14 +153,46 @@ DhSetParameter (
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Dh = (DH *) DhContext;
|
||||
Dh->p = BN_new();
|
||||
Dh->g = BN_new();
|
||||
Bn = NULL;
|
||||
|
||||
BN_bin2bn (Prime, (UINT32) (PrimeLength / 8), Dh->p);
|
||||
BN_set_word (Dh->g, (UINT32) Generator);
|
||||
Dh = (DH *) DhContext;
|
||||
Dh->g = NULL;
|
||||
Dh->p = BN_new ();
|
||||
if (Dh->p == NULL) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
Dh->g = BN_new ();
|
||||
if (Dh->g == NULL) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
Bn = BN_bin2bn (Prime, (UINT32) (PrimeLength / 8), Dh->p);
|
||||
if (Bn == NULL) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (BN_set_word (Dh->g, (UINT32) Generator) == 0) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
Error:
|
||||
|
||||
if (Dh->p != NULL) {
|
||||
BN_free (Dh->p);
|
||||
}
|
||||
|
||||
if (Dh->g != NULL) {
|
||||
BN_free (Dh->g);
|
||||
}
|
||||
|
||||
if (Bn != NULL) {
|
||||
BN_free (Bn);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -194,6 +227,7 @@ DhGenerateKey (
|
||||
{
|
||||
BOOLEAN RetVal;
|
||||
DH *Dh;
|
||||
INTN Size;
|
||||
|
||||
//
|
||||
// Check input parameters.
|
||||
@ -207,12 +241,17 @@ DhGenerateKey (
|
||||
}
|
||||
|
||||
Dh = (DH *) DhContext;
|
||||
*PublicKeySize = 0;
|
||||
|
||||
RetVal = (BOOLEAN) DH_generate_key (DhContext);
|
||||
if (RetVal) {
|
||||
Size = BN_num_bytes (Dh->pub_key);
|
||||
if ((Size > 0) && (*PublicKeySize < (UINTN) Size)) {
|
||||
*PublicKeySize = Size;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BN_bn2bin (Dh->pub_key, PublicKey);
|
||||
*PublicKeySize = BN_num_bytes (Dh->pub_key);
|
||||
*PublicKeySize = Size;
|
||||
}
|
||||
|
||||
return RetVal;
|
||||
@ -227,7 +266,8 @@ DhGenerateKey (
|
||||
If DhContext is NULL, then return FALSE.
|
||||
If PeerPublicKey is NULL, then return FALSE.
|
||||
If KeySize is NULL, then return FALSE.
|
||||
If KeySize is large enough but Key is NULL, then return FALSE.
|
||||
If Key is NULL, then return FALSE.
|
||||
If KeySize is not large enough, then return FALSE.
|
||||
|
||||
@param[in, out] DhContext Pointer to the DH context.
|
||||
@param[in] PeerPublicKey Pointer to the peer's public key.
|
||||
@ -252,23 +292,37 @@ DhComputeKey (
|
||||
)
|
||||
{
|
||||
BIGNUM *Bn;
|
||||
INTN Size;
|
||||
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (DhContext == NULL || PeerPublicKey == NULL || KeySize == NULL) {
|
||||
if (DhContext == NULL || PeerPublicKey == NULL || KeySize == NULL || Key == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Key == NULL && *KeySize != 0) {
|
||||
if (PeerPublicKeySize > INT_MAX) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bn = BN_bin2bn (PeerPublicKey, (UINT32) PeerPublicKeySize, NULL);
|
||||
if (Bn == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*KeySize = (BOOLEAN) DH_compute_key (Key, Bn, DhContext);
|
||||
Size = DH_compute_key (Key, Bn, DhContext);
|
||||
if (Size < 0) {
|
||||
BN_free (Bn);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (*KeySize < (UINTN) Size) {
|
||||
*KeySize = Size;
|
||||
BN_free (Bn);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*KeySize = Size;
|
||||
BN_free (Bn);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1,722 +0,0 @@
|
||||
/** @file
|
||||
RSA Asymmetric Cipher Wrapper Implementation over OpenSSL.
|
||||
|
||||
Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "InternalCryptLib.h"
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
//
|
||||
// ASN.1 value for Hash Algorithm ID with the Distringuished Encoding Rules (DER)
|
||||
// Refer to Section 9.2 of PKCS#1 v2.1
|
||||
//
|
||||
CONST UINT8 Asn1IdMd5[] = {
|
||||
0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,
|
||||
0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10
|
||||
};
|
||||
|
||||
CONST UINT8 Asn1IdSha1[] = {
|
||||
0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
|
||||
0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
|
||||
};
|
||||
|
||||
CONST UINT8 Asn1IdSha256[] = {
|
||||
0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
|
||||
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
|
||||
0x00, 0x04, 0x20
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
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 by OpenSSL RSA_new()
|
||||
//
|
||||
return (VOID *)RSA_new ();
|
||||
}
|
||||
|
||||
/**
|
||||
Release the specified RSA context.
|
||||
|
||||
If RsaContext is NULL, then return FALSE.
|
||||
|
||||
@param[in] RsaContext Pointer to the RSA context to be released.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
RsaFree (
|
||||
IN VOID *RsaContext
|
||||
)
|
||||
{
|
||||
//
|
||||
// Free OpenSSL RSA Context
|
||||
//
|
||||
RSA_free ((RSA *)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 componenet 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 componenet 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
|
||||
)
|
||||
{
|
||||
RSA *RsaKey;
|
||||
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (RsaContext == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RsaKey = (RSA *)RsaContext;
|
||||
//
|
||||
// Set RSA Key Components by converting octet string to OpenSSL BN representation.
|
||||
// NOTE: For RSA public key (used in signature verification), only public components
|
||||
// (N, e) are needed.
|
||||
//
|
||||
switch (KeyTag) {
|
||||
|
||||
//
|
||||
// RSA Public Modulus (N)
|
||||
//
|
||||
case RsaKeyN:
|
||||
if (RsaKey->n != NULL) {
|
||||
BN_free (RsaKey->n);
|
||||
}
|
||||
RsaKey->n = NULL;
|
||||
if (BigNumber == NULL) {
|
||||
break;
|
||||
}
|
||||
RsaKey->n = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->n);
|
||||
break;
|
||||
|
||||
//
|
||||
// RSA Public Exponent (e)
|
||||
//
|
||||
case RsaKeyE:
|
||||
if (RsaKey->e != NULL) {
|
||||
BN_free (RsaKey->e);
|
||||
}
|
||||
RsaKey->e = NULL;
|
||||
if (BigNumber == NULL) {
|
||||
break;
|
||||
}
|
||||
RsaKey->e = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->e);
|
||||
break;
|
||||
|
||||
//
|
||||
// RSA Private Exponent (d)
|
||||
//
|
||||
case RsaKeyD:
|
||||
if (RsaKey->d != NULL) {
|
||||
BN_free (RsaKey->d);
|
||||
}
|
||||
RsaKey->d = NULL;
|
||||
if (BigNumber == NULL) {
|
||||
break;
|
||||
}
|
||||
RsaKey->d = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->d);
|
||||
break;
|
||||
|
||||
//
|
||||
// RSA Secret Prime Factor of Modulus (p)
|
||||
//
|
||||
case RsaKeyP:
|
||||
if (RsaKey->p != NULL) {
|
||||
BN_free (RsaKey->p);
|
||||
}
|
||||
RsaKey->p = NULL;
|
||||
if (BigNumber == NULL) {
|
||||
break;
|
||||
}
|
||||
RsaKey->p = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->p);
|
||||
break;
|
||||
|
||||
//
|
||||
// RSA Secret Prime Factor of Modules (q)
|
||||
//
|
||||
case RsaKeyQ:
|
||||
if (RsaKey->q != NULL) {
|
||||
BN_free (RsaKey->q);
|
||||
}
|
||||
RsaKey->q = NULL;
|
||||
if (BigNumber == NULL) {
|
||||
break;
|
||||
}
|
||||
RsaKey->q = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->q);
|
||||
break;
|
||||
|
||||
//
|
||||
// p's CRT Exponent (== d mod (p - 1))
|
||||
//
|
||||
case RsaKeyDp:
|
||||
if (RsaKey->dmp1 != NULL) {
|
||||
BN_free (RsaKey->dmp1);
|
||||
}
|
||||
RsaKey->dmp1 = NULL;
|
||||
if (BigNumber == NULL) {
|
||||
break;
|
||||
}
|
||||
RsaKey->dmp1 = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->dmp1);
|
||||
break;
|
||||
|
||||
//
|
||||
// q's CRT Exponent (== d mod (q - 1))
|
||||
//
|
||||
case RsaKeyDq:
|
||||
if (RsaKey->dmq1 != NULL) {
|
||||
BN_free (RsaKey->dmq1);
|
||||
}
|
||||
RsaKey->dmq1 = NULL;
|
||||
if (BigNumber == NULL) {
|
||||
break;
|
||||
}
|
||||
RsaKey->dmq1 = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->dmq1);
|
||||
break;
|
||||
|
||||
//
|
||||
// The CRT Coefficient (== 1/q mod p)
|
||||
//
|
||||
case RsaKeyQInv:
|
||||
if (RsaKey->iqmp != NULL) {
|
||||
BN_free (RsaKey->iqmp);
|
||||
}
|
||||
RsaKey->iqmp = NULL;
|
||||
if (BigNumber == NULL) {
|
||||
break;
|
||||
}
|
||||
RsaKey->iqmp = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->iqmp);
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
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;
|
||||
|
||||
switch (KeyTag) {
|
||||
|
||||
//
|
||||
// RSA Public Modulus (N)
|
||||
//
|
||||
case RsaKeyN:
|
||||
if (RsaKey->n == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
BnKey = RsaKey->n;
|
||||
break;
|
||||
|
||||
//
|
||||
// RSA Public Exponent (e)
|
||||
//
|
||||
case RsaKeyE:
|
||||
if (RsaKey->e == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
BnKey = RsaKey->e;
|
||||
break;
|
||||
|
||||
//
|
||||
// RSA Private Exponent (d)
|
||||
//
|
||||
case RsaKeyD:
|
||||
if (RsaKey->d == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
BnKey = RsaKey->d;
|
||||
break;
|
||||
|
||||
//
|
||||
// RSA Secret Prime Factor of Modulus (p)
|
||||
//
|
||||
case RsaKeyP:
|
||||
if (RsaKey->p == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
BnKey = RsaKey->p;
|
||||
break;
|
||||
|
||||
//
|
||||
// RSA Secret Prime Factor of Modules (q)
|
||||
//
|
||||
case RsaKeyQ:
|
||||
if (RsaKey->q == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
BnKey = RsaKey->q;
|
||||
break;
|
||||
|
||||
//
|
||||
// p's CRT Exponent (== d mod (p - 1))
|
||||
//
|
||||
case RsaKeyDp:
|
||||
if (RsaKey->dmp1 == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
BnKey = RsaKey->dmp1;
|
||||
break;
|
||||
|
||||
//
|
||||
// q's CRT Exponent (== d mod (q - 1))
|
||||
//
|
||||
case RsaKeyDq:
|
||||
if (RsaKey->dmq1 == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
BnKey = RsaKey->dmq1;
|
||||
break;
|
||||
|
||||
//
|
||||
// The CRT Coefficient (== 1/q mod p)
|
||||
//
|
||||
case RsaKeyQInv:
|
||||
if (RsaKey->iqmp == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
BnKey = RsaKey->iqmp;
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*BnSize = Size;
|
||||
Size = BN_num_bytes (BnKey);
|
||||
|
||||
if (*BnSize < Size) {
|
||||
*BnSize = Size;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (BigNumber == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
*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) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
KeyE = BN_new ();
|
||||
if (PublicExponent == NULL) {
|
||||
BN_set_word (KeyE, 0x10001);
|
||||
} else {
|
||||
BN_bin2bn (PublicExponent, (UINT32) PublicExponentSize, KeyE);
|
||||
}
|
||||
|
||||
RetVal = FALSE;
|
||||
if (RSA_generate_key_ex ((RSA *) RsaContext, (UINT32) ModulusLength, KeyE, NULL) == 1) {
|
||||
RetVal = TRUE;
|
||||
}
|
||||
|
||||
BN_free (KeyE);
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
/**
|
||||
Validates key components of RSA context.
|
||||
|
||||
This function validates key compoents 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;
|
||||
}
|
||||
|
||||
/**
|
||||
Performs the PKCS1-v1_5 encoding methods defined in RSA PKCS #1.
|
||||
|
||||
@param Message Message buffer to be encoded.
|
||||
@param MessageSize Size of message buffer in bytes.
|
||||
@param DigestInfo Pointer to buffer of digest info for output.
|
||||
|
||||
@return Size of DigestInfo in bytes.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
DigestInfoEncoding (
|
||||
IN CONST UINT8 *Message,
|
||||
IN UINTN MessageSize,
|
||||
OUT UINT8 *DigestInfo
|
||||
)
|
||||
{
|
||||
CONST UINT8 *HashDer;
|
||||
UINTN DerSize;
|
||||
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (Message == NULL || DigestInfo == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// The original message length is used to determine the hash algorithm since
|
||||
// message is digest value hashed by the specified algorithm.
|
||||
//
|
||||
switch (MessageSize) {
|
||||
case MD5_DIGEST_SIZE:
|
||||
HashDer = Asn1IdMd5;
|
||||
DerSize = sizeof (Asn1IdMd5);
|
||||
break;
|
||||
|
||||
case SHA1_DIGEST_SIZE:
|
||||
HashDer = Asn1IdSha1;
|
||||
DerSize = sizeof (Asn1IdSha1);
|
||||
break;
|
||||
|
||||
case SHA256_DIGEST_SIZE:
|
||||
HashDer = Asn1IdSha256;
|
||||
DerSize = sizeof (Asn1IdSha256);
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CopyMem (DigestInfo, HashDer, DerSize);
|
||||
CopyMem (DigestInfo + DerSize, Message, MessageSize);
|
||||
|
||||
return (DerSize + MessageSize);
|
||||
}
|
||||
|
||||
/**
|
||||
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 or SHA-256 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;
|
||||
INTN ReturnVal;
|
||||
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (RsaContext == NULL || MessageHash == NULL ||
|
||||
(HashSize != MD5_DIGEST_SIZE && HashSize != SHA1_DIGEST_SIZE && HashSize != SHA256_DIGEST_SIZE)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Rsa = (RSA *) RsaContext;
|
||||
Size = BN_num_bytes (Rsa->n);
|
||||
|
||||
if (*SigSize < Size) {
|
||||
*SigSize = Size;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Signature == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Size = DigestInfoEncoding (MessageHash, HashSize, Signature);
|
||||
|
||||
ReturnVal = RSA_private_encrypt (
|
||||
(UINT32) Size,
|
||||
Signature,
|
||||
Signature,
|
||||
Rsa,
|
||||
RSA_PKCS1_PADDING
|
||||
);
|
||||
|
||||
if (ReturnVal < (INTN) Size) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*SigSize = (UINTN)ReturnVal;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
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 UINT8 *Signature,
|
||||
IN UINTN SigSize
|
||||
)
|
||||
{
|
||||
INTN Length;
|
||||
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (RsaContext == NULL || MessageHash == NULL || Signature == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Check for unsupported hash size:
|
||||
// Only MD5, SHA-1 or SHA-256 digest size is supported
|
||||
//
|
||||
if (HashSize != MD5_DIGEST_SIZE && HashSize != SHA1_DIGEST_SIZE && HashSize != SHA256_DIGEST_SIZE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// RSA PKCS#1 Signature Decoding using OpenSSL RSA Decryption with Public Key
|
||||
//
|
||||
Length = RSA_public_decrypt (
|
||||
(UINT32) SigSize,
|
||||
Signature,
|
||||
Signature,
|
||||
RsaContext,
|
||||
RSA_PKCS1_PADDING
|
||||
);
|
||||
|
||||
//
|
||||
// Invalid RSA Key or PKCS#1 Padding Checking Failed (if Length < 0)
|
||||
// NOTE: Length should be the addition of HashSize and some DER value.
|
||||
// Ignore more strict length checking here.
|
||||
//
|
||||
if (Length < (INTN) HashSize) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate the MessageHash and Decoded Signature
|
||||
// NOTE: The decoded Signature should be the DER encoding of the DigestInfo value
|
||||
// DigestInfo ::= SEQUENCE {
|
||||
// digestAlgorithm AlgorithmIdentifier
|
||||
// digest OCTET STRING
|
||||
// }
|
||||
// Then Memory Comparing should skip the DER value of the underlying SEQUENCE
|
||||
// type and AlgorithmIdentifier.
|
||||
//
|
||||
if (CompareMem (MessageHash, Signature + Length - HashSize, HashSize) == 0) {
|
||||
//
|
||||
// Valid RSA PKCS#1 Signature
|
||||
//
|
||||
return TRUE;
|
||||
} else {
|
||||
//
|
||||
// Failed to verification
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
}
|
335
Cryptlib/Pk/CryptRsaBasic.c
Normal file
335
Cryptlib/Pk/CryptRsaBasic.c
Normal file
@ -0,0 +1,335 @@
|
||||
/** @file
|
||||
RSA Asymmetric Cipher Wrapper Implementation over OpenSSL.
|
||||
|
||||
This file implements following APIs which provide basic capabilities for RSA:
|
||||
1) RsaNew
|
||||
2) RsaFree
|
||||
3) RsaSetKey
|
||||
4) RsaPkcs1Verify
|
||||
|
||||
Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "InternalCryptLib.h"
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/objects.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 by OpenSSL RSA_new()
|
||||
//
|
||||
return (VOID *) RSA_new ();
|
||||
}
|
||||
|
||||
/**
|
||||
Release the specified RSA context.
|
||||
|
||||
@param[in] RsaContext Pointer to the RSA context to be released.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
RsaFree (
|
||||
IN VOID *RsaContext
|
||||
)
|
||||
{
|
||||
//
|
||||
// Free OpenSSL RSA Context
|
||||
//
|
||||
RSA_free ((RSA *) 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 componenet 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 componenet 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
|
||||
)
|
||||
{
|
||||
RSA *RsaKey;
|
||||
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (RsaContext == NULL || BnSize > INT_MAX) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RsaKey = (RSA *) RsaContext;
|
||||
//
|
||||
// Set RSA Key Components by converting octet string to OpenSSL BN representation.
|
||||
// NOTE: For RSA public key (used in signature verification), only public components
|
||||
// (N, e) are needed.
|
||||
//
|
||||
switch (KeyTag) {
|
||||
|
||||
//
|
||||
// RSA Public Modulus (N)
|
||||
//
|
||||
case RsaKeyN:
|
||||
if (RsaKey->n != NULL) {
|
||||
BN_free (RsaKey->n);
|
||||
}
|
||||
RsaKey->n = NULL;
|
||||
if (BigNumber == NULL) {
|
||||
break;
|
||||
}
|
||||
RsaKey->n = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->n);
|
||||
if (RsaKey->n == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
//
|
||||
// RSA Public Exponent (e)
|
||||
//
|
||||
case RsaKeyE:
|
||||
if (RsaKey->e != NULL) {
|
||||
BN_free (RsaKey->e);
|
||||
}
|
||||
RsaKey->e = NULL;
|
||||
if (BigNumber == NULL) {
|
||||
break;
|
||||
}
|
||||
RsaKey->e = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->e);
|
||||
if (RsaKey->e == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
//
|
||||
// RSA Private Exponent (d)
|
||||
//
|
||||
case RsaKeyD:
|
||||
if (RsaKey->d != NULL) {
|
||||
BN_free (RsaKey->d);
|
||||
}
|
||||
RsaKey->d = NULL;
|
||||
if (BigNumber == NULL) {
|
||||
break;
|
||||
}
|
||||
RsaKey->d = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->d);
|
||||
if (RsaKey->d == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
//
|
||||
// RSA Secret Prime Factor of Modulus (p)
|
||||
//
|
||||
case RsaKeyP:
|
||||
if (RsaKey->p != NULL) {
|
||||
BN_free (RsaKey->p);
|
||||
}
|
||||
RsaKey->p = NULL;
|
||||
if (BigNumber == NULL) {
|
||||
break;
|
||||
}
|
||||
RsaKey->p = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->p);
|
||||
if (RsaKey->p == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
//
|
||||
// RSA Secret Prime Factor of Modules (q)
|
||||
//
|
||||
case RsaKeyQ:
|
||||
if (RsaKey->q != NULL) {
|
||||
BN_free (RsaKey->q);
|
||||
}
|
||||
RsaKey->q = NULL;
|
||||
if (BigNumber == NULL) {
|
||||
break;
|
||||
}
|
||||
RsaKey->q = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->q);
|
||||
if (RsaKey->q == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
//
|
||||
// p's CRT Exponent (== d mod (p - 1))
|
||||
//
|
||||
case RsaKeyDp:
|
||||
if (RsaKey->dmp1 != NULL) {
|
||||
BN_free (RsaKey->dmp1);
|
||||
}
|
||||
RsaKey->dmp1 = NULL;
|
||||
if (BigNumber == NULL) {
|
||||
break;
|
||||
}
|
||||
RsaKey->dmp1 = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->dmp1);
|
||||
if (RsaKey->dmp1 == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
//
|
||||
// q's CRT Exponent (== d mod (q - 1))
|
||||
//
|
||||
case RsaKeyDq:
|
||||
if (RsaKey->dmq1 != NULL) {
|
||||
BN_free (RsaKey->dmq1);
|
||||
}
|
||||
RsaKey->dmq1 = NULL;
|
||||
if (BigNumber == NULL) {
|
||||
break;
|
||||
}
|
||||
RsaKey->dmq1 = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->dmq1);
|
||||
if (RsaKey->dmq1 == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
//
|
||||
// The CRT Coefficient (== 1/q mod p)
|
||||
//
|
||||
case RsaKeyQInv:
|
||||
if (RsaKey->iqmp != NULL) {
|
||||
BN_free (RsaKey->iqmp);
|
||||
}
|
||||
RsaKey->iqmp = NULL;
|
||||
if (BigNumber == NULL) {
|
||||
break;
|
||||
}
|
||||
RsaKey->iqmp = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->iqmp);
|
||||
if (RsaKey->iqmp == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
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
|
||||
)
|
||||
{
|
||||
INT32 DigestType;
|
||||
UINT8 *SigBuf;
|
||||
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (RsaContext == NULL || MessageHash == NULL || Signature == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (SigSize > INT_MAX || SigSize == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Determine the message digest algorithm according to digest size.
|
||||
// Only MD5, SHA-1 or SHA-256 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;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SigBuf = (UINT8 *) Signature;
|
||||
return (BOOLEAN) RSA_verify (
|
||||
DigestType,
|
||||
MessageHash,
|
||||
(UINT32) HashSize,
|
||||
SigBuf,
|
||||
(UINT32) SigSize,
|
||||
(RSA *) RsaContext
|
||||
);
|
||||
}
|
377
Cryptlib/Pk/CryptRsaExt.c
Normal file
377
Cryptlib/Pk/CryptRsaExt.c
Normal file
@ -0,0 +1,377 @@
|
||||
/** @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 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "InternalCryptLib.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;
|
||||
|
||||
switch (KeyTag) {
|
||||
|
||||
//
|
||||
// RSA Public Modulus (N)
|
||||
//
|
||||
case RsaKeyN:
|
||||
if (RsaKey->n == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
BnKey = RsaKey->n;
|
||||
break;
|
||||
|
||||
//
|
||||
// RSA Public Exponent (e)
|
||||
//
|
||||
case RsaKeyE:
|
||||
if (RsaKey->e == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
BnKey = RsaKey->e;
|
||||
break;
|
||||
|
||||
//
|
||||
// RSA Private Exponent (d)
|
||||
//
|
||||
case RsaKeyD:
|
||||
if (RsaKey->d == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
BnKey = RsaKey->d;
|
||||
break;
|
||||
|
||||
//
|
||||
// RSA Secret Prime Factor of Modulus (p)
|
||||
//
|
||||
case RsaKeyP:
|
||||
if (RsaKey->p == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
BnKey = RsaKey->p;
|
||||
break;
|
||||
|
||||
//
|
||||
// RSA Secret Prime Factor of Modules (q)
|
||||
//
|
||||
case RsaKeyQ:
|
||||
if (RsaKey->q == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
BnKey = RsaKey->q;
|
||||
break;
|
||||
|
||||
//
|
||||
// p's CRT Exponent (== d mod (p - 1))
|
||||
//
|
||||
case RsaKeyDp:
|
||||
if (RsaKey->dmp1 == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
BnKey = RsaKey->dmp1;
|
||||
break;
|
||||
|
||||
//
|
||||
// q's CRT Exponent (== d mod (q - 1))
|
||||
//
|
||||
case RsaKeyDq:
|
||||
if (RsaKey->dmq1 == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
BnKey = RsaKey->dmq1;
|
||||
break;
|
||||
|
||||
//
|
||||
// The CRT Coefficient (== 1/q mod p)
|
||||
//
|
||||
case RsaKeyQInv:
|
||||
if (RsaKey->iqmp == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
BnKey = RsaKey->iqmp;
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*BnSize = Size;
|
||||
Size = BN_num_bytes (BnKey);
|
||||
|
||||
if (*BnSize < Size) {
|
||||
*BnSize = Size;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (BigNumber == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
*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.
|
||||
|
||||
This function validates key compoents 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 or SHA-256 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 = BN_num_bytes (Rsa->n);
|
||||
|
||||
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 or SHA-256 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;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return (BOOLEAN) RSA_sign (
|
||||
DigestType,
|
||||
MessageHash,
|
||||
(UINT32) HashSize,
|
||||
Signature,
|
||||
(UINT32 *) SigSize,
|
||||
(RSA *) RsaContext
|
||||
);
|
||||
}
|
@ -38,9 +38,7 @@ X509ConstructCertificate (
|
||||
OUT UINT8 **SingleX509Cert
|
||||
)
|
||||
{
|
||||
BIO *CertBio;
|
||||
X509 *X509Cert;
|
||||
BOOLEAN Status;
|
||||
|
||||
//
|
||||
// Check input parameters.
|
||||
@ -49,31 +47,17 @@ X509ConstructCertificate (
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Status = FALSE;
|
||||
|
||||
//
|
||||
// Read DER-encoded X509 Certificate and Construct X509 object.
|
||||
//
|
||||
CertBio = BIO_new (BIO_s_mem ());
|
||||
BIO_write (CertBio, Cert, (int) CertSize);
|
||||
if (CertBio == NULL) {
|
||||
goto _Exit;
|
||||
}
|
||||
X509Cert = d2i_X509_bio (CertBio, NULL);
|
||||
X509Cert = d2i_X509 (NULL, &Cert, (long) CertSize);
|
||||
if (X509Cert == NULL) {
|
||||
goto _Exit;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*SingleX509Cert = (UINT8 *) X509Cert;
|
||||
Status = TRUE;
|
||||
|
||||
_Exit:
|
||||
//
|
||||
// Release Resources.
|
||||
//
|
||||
BIO_free (CertBio);
|
||||
|
||||
return Status;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -224,91 +208,6 @@ X509StackFree (
|
||||
sk_X509_pop_free ((STACK_OF(X509) *) X509Stack, X509_free);
|
||||
}
|
||||
|
||||
/**
|
||||
Pop single certificate from STACK_OF(X509).
|
||||
|
||||
If X509Stack, Cert, or CertSize is NULL, then return FALSE.
|
||||
|
||||
@param[in] X509Stack Pointer to a X509 stack object.
|
||||
@param[out] Cert Pointer to a X509 certificate.
|
||||
@param[out] CertSize Length of output X509 certificate in bytes.
|
||||
|
||||
@retval TRUE The X509 stack pop succeeded.
|
||||
@retval FALSE The pop operation failed.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
X509PopCertificate (
|
||||
IN VOID *X509Stack,
|
||||
OUT UINT8 **Cert,
|
||||
OUT UINTN *CertSize
|
||||
)
|
||||
{
|
||||
BIO *CertBio;
|
||||
X509 *X509Cert;
|
||||
STACK_OF(X509) *CertStack;
|
||||
BOOLEAN Status;
|
||||
int Result;
|
||||
int Length;
|
||||
VOID *Buffer;
|
||||
|
||||
Status = FALSE;
|
||||
|
||||
if ((X509Stack == NULL) || (Cert == NULL) || (CertSize == NULL)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
CertStack = (STACK_OF(X509) *) X509Stack;
|
||||
|
||||
X509Cert = sk_X509_pop (CertStack);
|
||||
|
||||
if (X509Cert == NULL) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Buffer = NULL;
|
||||
|
||||
CertBio = BIO_new (BIO_s_mem ());
|
||||
if (CertBio == NULL) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Result = i2d_X509_bio (CertBio, X509Cert);
|
||||
if (Result == 0) {
|
||||
goto _Exit;
|
||||
}
|
||||
|
||||
Length = ((BUF_MEM *) CertBio->ptr)->length;
|
||||
if (Length <= 0) {
|
||||
goto _Exit;
|
||||
}
|
||||
|
||||
Buffer = malloc (Length);
|
||||
if (Buffer == NULL) {
|
||||
goto _Exit;
|
||||
}
|
||||
|
||||
Result = BIO_read (CertBio, Buffer, Length);
|
||||
if (Result != Length) {
|
||||
goto _Exit;
|
||||
}
|
||||
|
||||
*Cert = Buffer;
|
||||
*CertSize = Length;
|
||||
|
||||
Status = TRUE;
|
||||
|
||||
_Exit:
|
||||
|
||||
BIO_free (CertBio);
|
||||
|
||||
if (!Status && (Buffer != NULL)) {
|
||||
free (Buffer);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieve the subject bytes from one X.509 certificate.
|
||||
|
||||
@ -346,7 +245,6 @@ X509GetSubjectName (
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Status = FALSE;
|
||||
X509Cert = NULL;
|
||||
|
||||
//
|
||||
@ -354,20 +252,27 @@ X509GetSubjectName (
|
||||
//
|
||||
Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **) &X509Cert);
|
||||
if ((X509Cert == NULL) || (!Status)) {
|
||||
Status = FALSE;
|
||||
goto _Exit;
|
||||
}
|
||||
|
||||
Status = FALSE;
|
||||
|
||||
//
|
||||
// Retrieve subject name from certificate object.
|
||||
//
|
||||
X509Name = X509_get_subject_name (X509Cert);
|
||||
if (X509Name == NULL) {
|
||||
goto _Exit;
|
||||
}
|
||||
|
||||
if (*SubjectSize < (UINTN) X509Name->bytes->length) {
|
||||
*SubjectSize = (UINTN) X509Name->bytes->length;
|
||||
goto _Exit;
|
||||
}
|
||||
*SubjectSize = (UINTN) X509Name->bytes->length;
|
||||
if (CertSubject != NULL) {
|
||||
CopyMem (CertSubject, (UINT8 *)X509Name->bytes->data, *SubjectSize);
|
||||
CopyMem (CertSubject, (UINT8 *) X509Name->bytes->data, *SubjectSize);
|
||||
Status = TRUE;
|
||||
}
|
||||
|
||||
@ -375,7 +280,9 @@ _Exit:
|
||||
//
|
||||
// Release Resources.
|
||||
//
|
||||
X509_free (X509Cert);
|
||||
if (X509Cert != NULL) {
|
||||
X509_free (X509Cert);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
@ -415,7 +322,6 @@ RsaGetPublicKeyFromX509 (
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Status = FALSE;
|
||||
Pkey = NULL;
|
||||
X509Cert = NULL;
|
||||
|
||||
@ -424,9 +330,12 @@ RsaGetPublicKeyFromX509 (
|
||||
//
|
||||
Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **) &X509Cert);
|
||||
if ((X509Cert == NULL) || (!Status)) {
|
||||
Status = FALSE;
|
||||
goto _Exit;
|
||||
}
|
||||
|
||||
Status = FALSE;
|
||||
|
||||
//
|
||||
// Retrieve and check EVP_PKEY data from X509 Certificate.
|
||||
//
|
||||
@ -446,8 +355,13 @@ _Exit:
|
||||
//
|
||||
// Release Resources.
|
||||
//
|
||||
X509_free (X509Cert);
|
||||
EVP_PKEY_free (Pkey);
|
||||
if (X509Cert != NULL) {
|
||||
X509_free (X509Cert);
|
||||
}
|
||||
|
||||
if (Pkey != NULL) {
|
||||
EVP_PKEY_free (Pkey);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
@ -498,15 +412,22 @@ X509VerifyCert (
|
||||
//
|
||||
// Register & Initialize necessary digest algorithms for certificate verification.
|
||||
//
|
||||
EVP_add_digest (EVP_md5());
|
||||
EVP_add_digest (EVP_sha1());
|
||||
EVP_add_digest (EVP_sha256());
|
||||
if (EVP_add_digest (EVP_md5 ()) == 0) {
|
||||
goto _Exit;
|
||||
}
|
||||
if (EVP_add_digest (EVP_sha1 ()) == 0) {
|
||||
goto _Exit;
|
||||
}
|
||||
if (EVP_add_digest (EVP_sha256 ()) == 0) {
|
||||
goto _Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Read DER-encoded certificate to be verified and Construct X509 object.
|
||||
//
|
||||
Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **) &X509Cert);
|
||||
if ((X509Cert == NULL) || (!Status)) {
|
||||
Status = FALSE;
|
||||
goto _Exit;
|
||||
}
|
||||
|
||||
@ -515,9 +436,12 @@ X509VerifyCert (
|
||||
//
|
||||
Status = X509ConstructCertificate (CACert, CACertSize, (UINT8 **) &X509CACert);
|
||||
if ((X509CACert == NULL) || (!Status)) {
|
||||
Status = FALSE;
|
||||
goto _Exit;
|
||||
}
|
||||
|
||||
Status = FALSE;
|
||||
|
||||
//
|
||||
// Set up X509 Store for trusted certificate.
|
||||
//
|
||||
@ -546,9 +470,17 @@ _Exit:
|
||||
//
|
||||
// Release Resources.
|
||||
//
|
||||
X509_free (X509Cert);
|
||||
X509_free (X509CACert);
|
||||
X509_STORE_free (CertStore);
|
||||
if (X509Cert != NULL) {
|
||||
X509_free (X509Cert);
|
||||
}
|
||||
|
||||
if (X509CACert != NULL) {
|
||||
X509_free (X509CACert);
|
||||
}
|
||||
|
||||
if (CertStore != NULL) {
|
||||
X509_STORE_free (CertStore);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@ -43,6 +43,10 @@ RandomSeed (
|
||||
IN UINTN SeedSize
|
||||
)
|
||||
{
|
||||
if (SeedSize > INT_MAX) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Seed the pseudorandom number generator with user-supplied value.
|
||||
// NOTE: A cryptographic PRNG must be seeded with unpredictable data.
|
||||
@ -82,7 +86,7 @@ RandomBytes (
|
||||
//
|
||||
// Check input parameters.
|
||||
//
|
||||
if (Output == NULL) {
|
||||
if (Output == NULL || Size > INT_MAX) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
Base Memory Allocation Routines Wrapper for Crypto library over OpenSSL
|
||||
during PEI & DXE phases.
|
||||
|
||||
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@ -22,7 +22,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
/* Allocates memory blocks */
|
||||
void *malloc (size_t size)
|
||||
{
|
||||
return AllocatePool ((UINTN)size);
|
||||
return AllocatePool ((UINTN) size);
|
||||
}
|
||||
|
||||
/* Reallocate memory blocks */
|
||||
@ -32,7 +32,7 @@ void *realloc (void *ptr, size_t size)
|
||||
// BUG: hardcode OldSize == size! We have no any knowledge about
|
||||
// memory size of original pointer ptr.
|
||||
//
|
||||
return ReallocatePool (ptr, (UINTN)size, (UINTN)size);
|
||||
return ReallocatePool (ptr, (UINTN) size, (UINTN) size);
|
||||
}
|
||||
|
||||
/* De-allocates or frees a memory block */
|
||||
|
@ -293,6 +293,16 @@ size_t fwrite (const void *buffer, size_t size, size_t count, FILE *stream)
|
||||
// -- Dummy OpenSSL Support Routines --
|
||||
//
|
||||
|
||||
int BIO_printf (void *bio, const char *format, ...)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BIO_snprintf(char *buf, size_t n, const char *format, ...)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *UI_OpenSSL(void)
|
||||
{
|
||||
return NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user