Skip to content

Commit

Permalink
OcCryptoLib: Avoid memory allocation but in RsaVerifySigDataFromData
Browse files Browse the repository at this point in the history
  • Loading branch information
vit9696 committed Mar 6, 2022
1 parent 19cefe6 commit 6fdd6da
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 61 deletions.
54 changes: 32 additions & 22 deletions Include/Acidanthera/Library/OcCryptoLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand All @@ -437,45 +444,46 @@ 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] Modulus The RSA modulus byte array.
@param[in] ModulusSize The size, in bytes, of Modulus.
@param[in] Exponent The RSA exponent.
@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
RsaVerifySigDataFromData (
IN CONST UINT8 *Modulus,
IN UINTN ModulusSize,
IN UINT32 Exponent,
IN CONST UINT8 *Signature,
IN UINTN SignatureSize,
IN CONST UINT8 *Data,
IN UINTN DataSize,
IN OC_SIG_HASH_TYPE Algorithm
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
);

/**
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] Modulus The RSA modulus byte array.
@param[in] ModulusSize The size, in bytes, of Modulus.
@param[in] Exponent The RSA exponent.
@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.
Expand All @@ -486,13 +494,15 @@ RsaVerifySigDataFromData (
**/
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
RsaVerifySigDataFromData (
IN CONST UINT8 *Modulus,
IN UINTN ModulusSize,
IN UINT32 Exponent,
IN CONST UINT8 *Signature,
IN UINTN SignatureSize,
IN CONST UINT8 *Data,
IN UINTN DataSize,
IN OC_SIG_HASH_TYPE Algorithm
);

/**
Expand Down
25 changes: 19 additions & 6 deletions Library/OcAppleChunklistLib/OcAppleChunklistLib.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
65 changes: 36 additions & 29 deletions Library/OcCryptoLib/RsaDigitalSign.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -170,15 +171,15 @@ 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;
INTN CmpResult;

UINTN ModulusSize;

VOID *Memory;
OC_BN_WORD *EncryptedSigNum;
OC_BN_WORD *DecryptedSigNum;
OC_BN_WORD *PowScratchNum;
Expand Down Expand Up @@ -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,
Expand All @@ -295,7 +290,6 @@ RsaVerifySigHashFromProcessed (
PowScratchNum
);
if (!Result) {
FreePool (Memory);
return FALSE;
}
//
Expand Down Expand Up @@ -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;
}
//
Expand All @@ -351,37 +343,32 @@ 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;
}

++Index;

CmpResult = CompareMem (&Signature[Index], Padding, PaddingSize);
if (CmpResult != 0) {
FreePool (Memory);
return FALSE;
}

Index += PaddingSize;

CmpResult = CompareMem (&Signature[Index], Hash, HashSize);
if (CmpResult != 0) {
FreePool (Memory);
return FALSE;
}
//
// The code above must have covered the entire Signature range.
//
ASSERT (Index + HashSize == SignatureSize);

FreePool (Memory);
return TRUE;
}

Expand All @@ -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.
Expand All @@ -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];
Expand Down Expand Up @@ -485,10 +474,13 @@ RsaVerifySigDataFromProcessed (
SignatureSize,
Hash,
HashSize,
Algorithm
Algorithm,
Scratch
);
}

#ifndef OC_CRYPTO_STATIC_MEMORY_ALLOCATION

BOOLEAN
RsaVerifySigDataFromData (
IN CONST UINT8 *Modulus,
Expand All @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -562,21 +561,26 @@ RsaVerifySigDataFromData (
SignatureSize,
Data,
DataSize,
Algorithm
Algorithm,
Scratch
);

FreePool (Scratch);
FreePool (Memory);
return Result;
}

#endif

BOOLEAN
RsaVerifySigHashFromKey (
IN CONST OC_RSA_PUBLIC_KEY *Key,
IN CONST UINT8 *Signature,
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);
Expand All @@ -603,7 +607,8 @@ RsaVerifySigHashFromKey (
SignatureSize,
Hash,
HashSize,
Algorithm
Algorithm,
Scratch
);
}

Expand All @@ -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);
Expand All @@ -641,6 +647,7 @@ RsaVerifySigDataFromKey (
SignatureSize,
Data,
DataSize,
Algorithm
Algorithm,
Scratch
);
}
Loading

0 comments on commit 6fdd6da

Please sign in to comment.