OcCryptoLib: Avoid memory allocation but in RsaVerifySigDataFromData

This commit is contained in:
vit9696 2022-03-06 17:19:08 +03:00
parent 19cefe626c
commit 6fdd6dab9b
6 changed files with 139 additions and 67 deletions

View File

@ -416,6 +416,12 @@ SigVerifyShaHashBySize (
IN UINTN HashSize
);
/**
@param[in] ModulusSize Modulus size in bytes.
**/
#define RSA_SCRATCH_BUFFER_SIZE(ModulusSize) \
((ModulusSize) * 3)
/**
Verify a RSA PKCS1.5 signature against an expected hash.
The exponent is always 65537 as per the format specification.
@ -426,6 +432,7 @@ SigVerifyShaHashBySize (
@param[in] Hash The Hash digest of the signed data.
@param[in] HashSize Size, in bytes, of Hash.
@param[in] Algorithm The RSA algorithm used.
@param[in] Scratch Scratch buffer 3xModulo.
@returns Whether the signature has been successfully verified as valid.
@ -437,7 +444,36 @@ RsaVerifySigHashFromKey (
IN UINTN SignatureSize,
IN CONST UINT8 *Hash,
IN UINTN HashSize,
IN OC_SIG_HASH_TYPE Algorithm
IN OC_SIG_HASH_TYPE Algorithm,
IN VOID *Scratch
);
/**
Verify RSA PKCS1.5 signed data against its signature.
The modulus' size must be a multiple of the configured BIGNUM word size.
This will be true for any conventional RSA, which use two's potencies.
The exponent is always 65537 as per the format specification.
@param[in] Key The RSA Public Key.
@param[in] Signature The RSA signature to be verified.
@param[in] SignatureSize Size, in bytes, of Signature.
@param[in] Data The signed data to verify.
@param[in] DataSize Size, in bytes, of Data.
@param[in] Algorithm The RSA algorithm used.
@param[in] Scratch Scratch buffer 3xModulo.
@returns Whether the signature has been successfully verified as valid.
**/
BOOLEAN
RsaVerifySigDataFromKey (
IN CONST OC_RSA_PUBLIC_KEY *Key,
IN CONST UINT8 *Signature,
IN UINTN SignatureSize,
IN CONST UINT8 *Data,
IN UINTN DataSize,
IN OC_SIG_HASH_TYPE Algorithm,
IN VOID *Scratch
);
/**
@ -469,32 +505,6 @@ RsaVerifySigDataFromData (
IN OC_SIG_HASH_TYPE Algorithm
);
/**
Verify RSA PKCS1.5 signed data against its signature.
The modulus' size must be a multiple of the configured BIGNUM word size.
This will be true for any conventional RSA, which use two's potencies.
The exponent is always 65537 as per the format specification.
@param[in] Key The RSA Public Key.
@param[in] Signature The RSA signature to be verified.
@param[in] SignatureSize Size, in bytes, of Signature.
@param[in] Data The signed data to verify.
@param[in] DataSize Size, in bytes, of Data.
@param[in] Algorithm The RSA algorithm used.
@returns Whether the signature has been successfully verified as valid.
**/
BOOLEAN
RsaVerifySigDataFromKey (
IN CONST OC_RSA_PUBLIC_KEY *Key,
IN CONST UINT8 *Signature,
IN UINTN SignatureSize,
IN CONST UINT8 *Data,
IN UINTN DataSize,
IN OC_SIG_HASH_TYPE Algorithm
);
/**
Performs a cryptographically secure comparison of the contents of two
buffers.

View File

@ -102,24 +102,37 @@ OcAppleChunklistVerifySignature (
IN CONST OC_RSA_PUBLIC_KEY *PublicKey
)
{
VOID *Scratch;
BOOLEAN Result;
ASSERT (Context != NULL);
ASSERT (Context->Signature != NULL);
Scratch = AllocatePool (
RSA_SCRATCH_BUFFER_SIZE (PublicKey->Hdr.NumQwords * sizeof (UINT64))
);
if (Scratch == NULL) {
return FALSE;
}
Result = RsaVerifySigHashFromKey (
PublicKey,
Context->Signature->Signature,
sizeof (Context->Signature->Signature),
Context->Hash,
sizeof (Context->Hash),
OcSigHashTypeSha256
OcSigHashTypeSha256,
Scratch
);
DEBUG_CODE (
if (Result) {
Context->Signature = NULL;
}
);
FreePool (Scratch);
DEBUG_CODE_BEGIN ();
if (Result) {
Context->Signature = NULL;
}
DEBUG_CODE_END ();
return Result;
}

View File

@ -154,6 +154,7 @@ SigVerifyShaHashBySize (
@param[in] Hash The Hash digest of the signed data.
@param[in] HashSize Size, in bytes, of Hash.
@param[in] Algorithm The RSA algorithm used.
@param[in] Scratch Scratch buffer 3xModulo.
@returns Whether the signature has been successfully verified as valid.
@ -170,7 +171,8 @@ RsaVerifySigHashFromProcessed (
IN UINTN SignatureSize,
IN CONST UINT8 *Hash,
IN UINTN HashSize,
IN OC_SIG_HASH_TYPE Algorithm
IN OC_SIG_HASH_TYPE Algorithm,
IN OC_BN_WORD *Scratch
)
{
BOOLEAN Result;
@ -178,7 +180,6 @@ RsaVerifySigHashFromProcessed (
UINTN ModulusSize;
VOID *Memory;
OC_BN_WORD *EncryptedSigNum;
OC_BN_WORD *DecryptedSigNum;
OC_BN_WORD *PowScratchNum;
@ -267,15 +268,9 @@ RsaVerifySigHashFromProcessed (
return FALSE;
}
Memory = AllocatePool (3 * ModulusSize);
if (Memory == NULL) {
DEBUG ((DEBUG_INFO, "OCCR: Memory allocation failure\n"));
return FALSE;
}
EncryptedSigNum = Memory;
DecryptedSigNum = (OC_BN_WORD *)((UINTN)EncryptedSigNum + ModulusSize);
PowScratchNum = (OC_BN_WORD *)((UINTN)DecryptedSigNum + ModulusSize);
EncryptedSigNum = Scratch;
DecryptedSigNum = EncryptedSigNum + NumWords;
PowScratchNum = DecryptedSigNum + NumWords;
BigNumParseBuffer (
EncryptedSigNum,
@ -295,7 +290,6 @@ RsaVerifySigHashFromProcessed (
PowScratchNum
);
if (!Result) {
FreePool (Memory);
return FALSE;
}
//
@ -335,12 +329,10 @@ RsaVerifySigHashFromProcessed (
//
DigestSize = PaddingSize + HashSize;
if (SignatureSize < DigestSize + 11) {
FreePool (Memory);
return FALSE;
}
if (Signature[0] != 0x00 || Signature[1] != 0x01) {
FreePool (Memory);
return FALSE;
}
//
@ -351,13 +343,11 @@ RsaVerifySigHashFromProcessed (
//
for (Index = 2; Index < SignatureSize - DigestSize - 3 + 2; ++Index) {
if (Signature[Index] != 0xFF) {
FreePool (Memory);
return FALSE;
}
}
if (Signature[Index] != 0x00) {
FreePool (Memory);
return FALSE;
}
@ -365,7 +355,6 @@ RsaVerifySigHashFromProcessed (
CmpResult = CompareMem (&Signature[Index], Padding, PaddingSize);
if (CmpResult != 0) {
FreePool (Memory);
return FALSE;
}
@ -373,7 +362,6 @@ RsaVerifySigHashFromProcessed (
CmpResult = CompareMem (&Signature[Index], Hash, HashSize);
if (CmpResult != 0) {
FreePool (Memory);
return FALSE;
}
//
@ -381,7 +369,6 @@ RsaVerifySigHashFromProcessed (
//
ASSERT (Index + HashSize == SignatureSize);
FreePool (Memory);
return TRUE;
}
@ -400,6 +387,7 @@ RsaVerifySigHashFromProcessed (
@param[in] Data The signed data to verify.
@param[in] DataSize Size, in bytes, of Data.
@param[in] Algorithm The RSA algorithm used.
@param[in] Scratch Scratch buffer 3xModulo.
@returns Whether the signature has been successfully verified as valid.
@ -416,7 +404,8 @@ RsaVerifySigDataFromProcessed (
IN UINTN SignatureSize,
IN CONST UINT8 *Data,
IN UINTN DataSize,
IN OC_SIG_HASH_TYPE Algorithm
IN OC_SIG_HASH_TYPE Algorithm,
IN OC_BN_WORD *Scratch
)
{
UINT8 Hash[OC_MAX_SHA_DIGEST_SIZE];
@ -485,10 +474,13 @@ RsaVerifySigDataFromProcessed (
SignatureSize,
Hash,
HashSize,
Algorithm
Algorithm,
Scratch
);
}
#ifndef OC_CRYPTO_STATIC_MEMORY_ALLOCATION
BOOLEAN
RsaVerifySigDataFromData (
IN CONST UINT8 *Modulus,
@ -505,9 +497,10 @@ RsaVerifySigDataFromData (
OC_BN_NUM_WORDS ModulusNumWords;
VOID *Memory;
VOID *Scratch;
VOID *Mont;
OC_BN_WORD *N;
OC_BN_WORD *RSqrMod;
VOID *Scratch;
OC_BN_WORD N0Inv;
BOOLEAN Result;
@ -542,16 +535,22 @@ RsaVerifySigDataFromData (
N = (OC_BN_WORD *)Memory;
RSqrMod = (OC_BN_WORD *)((UINTN)N + ModulusSize);
Scratch = (UINT8 *)Memory + 2 * ModulusSize;
Mont = (UINT8 *)Memory + 2 * ModulusSize;
BigNumParseBuffer (N, ModulusNumWords, Modulus, ModulusSize);
N0Inv = BigNumCalculateMontParams (RSqrMod, ModulusNumWords, N, Scratch);
N0Inv = BigNumCalculateMontParams (RSqrMod, ModulusNumWords, N, Mont);
if (N0Inv == 0) {
FreePool (Memory);
return FALSE;
}
Scratch = AllocatePool (RSA_SCRATCH_BUFFER_SIZE (ModulusSize));
if (Scratch == NULL) {
FreePool (Memory);
return FALSE;
}
Result = RsaVerifySigDataFromProcessed (
N,
ModulusNumWords,
@ -562,13 +561,17 @@ RsaVerifySigDataFromData (
SignatureSize,
Data,
DataSize,
Algorithm
Algorithm,
Scratch
);
FreePool (Scratch);
FreePool (Memory);
return Result;
}
#endif
BOOLEAN
RsaVerifySigHashFromKey (
IN CONST OC_RSA_PUBLIC_KEY *Key,
@ -576,7 +579,8 @@ RsaVerifySigHashFromKey (
IN UINTN SignatureSize,
IN CONST UINT8 *Hash,
IN UINTN HashSize,
IN OC_SIG_HASH_TYPE Algorithm
IN OC_SIG_HASH_TYPE Algorithm,
IN VOID *Scratch
)
{
ASSERT (Key != NULL);
@ -603,7 +607,8 @@ RsaVerifySigHashFromKey (
SignatureSize,
Hash,
HashSize,
Algorithm
Algorithm,
Scratch
);
}
@ -614,7 +619,8 @@ RsaVerifySigDataFromKey (
IN UINTN SignatureSize,
IN CONST UINT8 *Data,
IN UINTN DataSize,
IN OC_SIG_HASH_TYPE Algorithm
IN OC_SIG_HASH_TYPE Algorithm,
IN VOID *Scratch
)
{
ASSERT (Key != NULL);
@ -641,6 +647,7 @@ RsaVerifySigDataFromKey (
SignatureSize,
Data,
DataSize,
Algorithm
Algorithm,
Scratch
);
}

View File

@ -387,6 +387,7 @@ PeCoffVerifyAppleSignature (
APPLE_EFI_CERTIFICATE_INFO *CertInfo;
UINT32 SecDirOffset;
UINT32 SignedFileSize;
VOID *Scratch;
ImageStatus = PeCoffInitializeContext (
&ImageContext,
@ -440,6 +441,15 @@ PeCoffVerifyAppleSignature (
&Hash[0]
);
Scratch = AllocatePool (
RSA_SCRATCH_BUFFER_SIZE (
SignatureContext.PublicKey->Hdr.NumQwords * sizeof (UINT64)
)
);
if (Scratch == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Verify signature
//
@ -449,8 +459,12 @@ PeCoffVerifyAppleSignature (
sizeof (SignatureContext.Signature),
&Hash[0],
sizeof (Hash),
OcSigHashTypeSha256
OcSigHashTypeSha256,
Scratch
);
FreePool (Scratch);
if (!Success) {
return EFI_SECURITY_VIOLATION;
}

View File

@ -131,6 +131,9 @@ OcStorageInitializeVault (
IN UINT32 SignatureSize OPTIONAL
)
{
VOID *Scratch;
if (Signature != NULL && Vault == NULL) {
DEBUG ((DEBUG_ERROR, "OCST: Missing vault with signature\n"));
return EFI_SECURITY_VIOLATION;
@ -144,10 +147,21 @@ OcStorageInitializeVault (
if (Signature != NULL) {
ASSERT (StorageKey != NULL);
if (!RsaVerifySigDataFromKey (StorageKey, Signature, SignatureSize, Vault, VaultSize, OcSigHashTypeSha256)) {
DEBUG ((DEBUG_ERROR, "OCST: Invalid vault signature\n"));
Scratch = AllocatePool (
RSA_SCRATCH_BUFFER_SIZE (StorageKey->Hdr.NumQwords * sizeof (UINT64))
);
if (Scratch == NULL) {
return EFI_SECURITY_VIOLATION;
}
if (!RsaVerifySigDataFromKey (StorageKey, Signature, SignatureSize, Vault, VaultSize, OcSigHashTypeSha256, Scratch)) {
DEBUG ((DEBUG_ERROR, "OCST: Invalid vault signature\n"));
FreePool (Scratch);
return EFI_SECURITY_VIOLATION;
}
FreePool (Scratch);
}
OC_STORAGE_VAULT_CONSTRUCT (&Context->Vault, sizeof (Context->Vault));

View File

@ -47,15 +47,29 @@ TestRsa2048Sha256Verify (
SIGNED_DATA_LEN
);
CONST OC_RSA_PUBLIC_KEY *PubKey =
(CONST OC_RSA_PUBLIC_KEY *) Rsa2048Sha256Sample.PublicKey;
void *Scratch = AllocatePool (
RSA_SCRATCH_BUFFER_SIZE (PubKey->Hdr.NumQwords * sizeof (UINT64))
);
if (Scratch == NULL) {
return EFI_OUT_OF_RESOURCES;
}
SignatureVerified = RsaVerifySigHashFromKey (
(CONST OC_RSA_PUBLIC_KEY *) Rsa2048Sha256Sample.PublicKey,
PubKey,
Rsa2048Sha256Sample.Signature,
sizeof (Rsa2048Sha256Sample.Signature),
DataSha256Hash,
sizeof (DataSha256Hash),
OcSigHashTypeSha256
OcSigHashTypeSha256,
Scratch
);
FreePool (Scratch);
if (SignatureVerified) {
Status = EFI_SUCCESS;
Print(L"Rsa2048Sha256 signature verifying passed!\n");