From 6fdd6dab9bc63ff3840cd3998a85605fb9e1daa6 Mon Sep 17 00:00:00 2001 From: vit9696 Date: Sun, 6 Mar 2022 17:19:08 +0300 Subject: [PATCH] OcCryptoLib: Avoid memory allocation but in RsaVerifySigDataFromData --- Include/Acidanthera/Library/OcCryptoLib.h | 64 ++++++++++-------- .../OcAppleChunklistLib/OcAppleChunklistLib.c | 25 +++++-- Library/OcCryptoLib/RsaDigitalSign.c | 65 ++++++++++--------- Library/OcPeCoffExtLib/OcPeCoffExtLib.c | 16 ++++- Library/OcStorageLib/OcStorageLib.c | 18 ++++- Tests/CryptoTest/CryptoTest.c | 18 ++++- 6 files changed, 139 insertions(+), 67 deletions(-) diff --git a/Include/Acidanthera/Library/OcCryptoLib.h b/Include/Acidanthera/Library/OcCryptoLib.h index 993a5408..a418417a 100644 --- a/Include/Acidanthera/Library/OcCryptoLib.h +++ b/Include/Acidanthera/Library/OcCryptoLib.h @@ -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. diff --git a/Library/OcAppleChunklistLib/OcAppleChunklistLib.c b/Library/OcAppleChunklistLib/OcAppleChunklistLib.c index 85ff2414..9339695a 100644 --- a/Library/OcAppleChunklistLib/OcAppleChunklistLib.c +++ b/Library/OcAppleChunklistLib/OcAppleChunklistLib.c @@ -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; } diff --git a/Library/OcCryptoLib/RsaDigitalSign.c b/Library/OcCryptoLib/RsaDigitalSign.c index b758de4c..a7289814 100644 --- a/Library/OcCryptoLib/RsaDigitalSign.c +++ b/Library/OcCryptoLib/RsaDigitalSign.c @@ -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 ); } diff --git a/Library/OcPeCoffExtLib/OcPeCoffExtLib.c b/Library/OcPeCoffExtLib/OcPeCoffExtLib.c index 4ee64754..00a17873 100644 --- a/Library/OcPeCoffExtLib/OcPeCoffExtLib.c +++ b/Library/OcPeCoffExtLib/OcPeCoffExtLib.c @@ -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; } diff --git a/Library/OcStorageLib/OcStorageLib.c b/Library/OcStorageLib/OcStorageLib.c index cab03e98..596b6f4f 100644 --- a/Library/OcStorageLib/OcStorageLib.c +++ b/Library/OcStorageLib/OcStorageLib.c @@ -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)); diff --git a/Tests/CryptoTest/CryptoTest.c b/Tests/CryptoTest/CryptoTest.c index eb76b290..dbda26f1 100644 --- a/Tests/CryptoTest/CryptoTest.c +++ b/Tests/CryptoTest/CryptoTest.c @@ -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");