tpm2: rev162: Refactor CryptMGF1 and rename to CryptMGF_KDF

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
Stefan Berger 2020-04-17 18:33:05 -04:00 committed by Stefan Berger
parent ed6a8d8cbf
commit b51bd9efdf
3 changed files with 36 additions and 41 deletions

View File

@ -3,7 +3,7 @@
/* Implementation of cryptographic functions for hashing. */
/* Written by Ken Goldman */
/* IBM Thomas J. Watson Research Center */
/* $Id: CryptHash_fp.h 1478 2019-06-10 21:15:14Z kgoldman $ */
/* $Id: CryptHash_fp.h 1594 2020-03-26 22:15:48Z kgoldman $ */
/* */
/* Licenses and Notices */
/* */
@ -55,7 +55,7 @@
/* arising in any way out of use or reliance upon this specification or any */
/* information herein. */
/* */
/* (c) Copyright IBM Corp. and others, 2016, 2017 */
/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
/* */
/********************************************************************************/
@ -184,12 +184,13 @@ CryptHmacEnd2B(
P2B digest // OUT: HMAC
);
LIB_EXPORT UINT16
CryptMGF1(
CryptMGF_KDF(
UINT32 mSize, // IN: length of the mask to be produced
BYTE *mask, // OUT: buffer to receive the mask
TPM_ALG_ID hashAlg, // IN: hash to use
UINT32 seedSize, // IN: size of the seed
BYTE *seed // IN: seed size
BYTE *seed, // IN: seed size
UINT32 counter // IN: counter initial value
);
LIB_EXPORT UINT16
CryptKDFa(

View File

@ -3,7 +3,7 @@
/* Implementation of cryptographic functions for hashing. */
/* Written by Ken Goldman */
/* IBM Thomas J. Watson Research Center */
/* $Id: CryptHash.c 1519 2019-11-15 20:43:51Z kgoldman $ */
/* $Id: CryptHash.c 1594 2020-03-26 22:15:48Z kgoldman $ */
/* */
/* Licenses and Notices */
/* */
@ -55,7 +55,7 @@
/* arising in any way out of use or reliance upon this specification or any */
/* information herein. */
/* */
/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
/* */
/********************************************************************************/
@ -648,50 +648,44 @@ CryptHmacEnd2B(
return CryptHmacEnd(hmacState, digest->size, digest->buffer);
}
/* 10.2.13.8 Mask and Key Generation Functions */
/* 10.2.13.8.1 CryptMGF1() */
/* This function performs MGF1 using the selected hash. MGF1 is T(n) = T(n-1) || H(seed ||
counter). This function returns the length of the mask produced which could be zero if the digest
algorithm is not supported */
/* 10.2.13.8.1 CryptMGF_KDF() */
/* This function performs MGF1/KDF1 or KDF2 using the selected hash. KDF1 and KDF2 are T(n) = T(n-1)
|| H(seed || counter) with the difference being that, with KDF1, counter starts at 0 but with
KDF2, counter starts at 1. The caller determines which version by setting the initial value of
counter to either 0 or 1. */
/* Return Value Meaning */
/* 0 hash algorithm was TPM_ALG_NULL */
/* > 0 should be the same as mSize */
LIB_EXPORT UINT16
CryptMGF1(
CryptMGF_KDF(
UINT32 mSize, // IN: length of the mask to be produced
BYTE *mask, // OUT: buffer to receive the mask
TPM_ALG_ID hashAlg, // IN: hash to use
UINT32 seedSize, // IN: size of the seed
BYTE *seed // IN: seed size
BYTE *seed, // IN: seed size
UINT32 counter // IN: counter initial value
)
{
HASH_STATE hashState;
PHASH_DEF hDef = CryptGetHashDef(hashAlg);
UINT32 remaining;
UINT32 counter = 0;
BYTE swappedCounter[4];
UINT32 hLen;
UINT32 bytes;
//
// If there is no digest to compute return
if((hashAlg == TPM_ALG_NULL) || (mSize == 0))
if((hDef->digestSize == 0) || (mSize == 0))
return 0;
for(remaining = mSize; ; remaining -= hDef->digestSize)
if(counter != 0)
counter = 1;
hLen = hDef->digestSize;
for(bytes = 0; bytes < mSize; bytes += hLen)
{
// Because the system may be either Endian...
UINT32_TO_BYTE_ARRAY(counter, swappedCounter);
// Start the hash and include the seed and counter
CryptHashStart(&hashState, hashAlg);
CryptDigestUpdate(&hashState, seedSize, seed);
CryptDigestUpdate(&hashState, 4, swappedCounter);
// Handling the completion depends on how much space remains in the mask
// buffer. If it can hold the entire digest, put it there. If not
// put the digest in a temp buffer and only copy the amount that
// will fit into the mask buffer.
HashEnd(&hashState, remaining, mask);
if(remaining <= hDef->digestSize)
break;
mask = &mask[hDef->digestSize];
CryptDigestUpdateInt(&hashState, 4, counter);
// Get as much as will fit.
CryptHashEnd(&hashState, MIN((mSize - bytes), hLen),
&mask[bytes]);
counter++;
}
return (UINT16)mSize;

View File

@ -3,7 +3,7 @@
/* Implementation of cryptographic primitives for RSA */
/* Written by Ken Goldman */
/* IBM Thomas J. Watson Research Center */
/* $Id: CryptRsa.c 1519 2019-11-15 20:43:51Z kgoldman $ */
/* $Id: CryptRsa.c 1594 2020-03-26 22:15:48Z kgoldman $ */
/* */
/* Licenses and Notices */
/* */
@ -55,7 +55,7 @@
/* arising in any way out of use or reliance upon this specification or any */
/* information herein. */
/* */
/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
/* */
/********************************************************************************/
@ -328,14 +328,14 @@ OaepEncode(
CryptRandomGenerate(hLen, mySeed);
DRBG_Generate(rand, mySeed, (UINT16)hLen);
// mask = MGF1 (seed, nSize hLen 1)
CryptMGF1(dbSize, mask, hashAlg, hLen, seed);
CryptMGF_KDF(dbSize, mask, hashAlg, hLen, seed, 0);
// Create the masked db
pm = mask;
for(i = dbSize; i > 0; i--)
*pp++ ^= *pm++;
pp = &padded->buffer[hLen + 1];
// Run the masked data through MGF1
if(CryptMGF1(hLen, &padded->buffer[1], hashAlg, dbSize, pp) != (unsigned)hLen)
if(CryptMGF_KDF(hLen, &padded->buffer[1], hashAlg, dbSize, pp, 0) != (unsigned)hLen)
ERROR_RETURN(TPM_RC_VALUE);
// Now XOR the seed to create masked seed
pp = &padded->buffer[1];
@ -377,8 +377,8 @@ OaepDecode(
ERROR_RETURN(TPM_RC_VALUE);
// Use the hash size to determine what to put through MGF1 in order
// to recover the seedMask
CryptMGF1(hLen, seedMask, hashAlg, padded->size - hLen - 1,
&padded->buffer[hLen + 1]);
CryptMGF_KDF(hLen, seedMask, hashAlg, padded->size - hLen - 1,
&padded->buffer[hLen + 1], 0);
// Recover the seed into seedMask
pAssert(hLen <= sizeof(seedMask));
pp = &padded->buffer[1];
@ -386,7 +386,7 @@ OaepDecode(
for(i = hLen; i > 0; i--)
*pm++ ^= *pp++;
// Use the seed to generate the data mask
CryptMGF1(padded->size - hLen - 1, mask, hashAlg, hLen, seedMask);
CryptMGF_KDF(padded->size - hLen - 1, mask, hashAlg, hLen, seedMask, 0);
// Use the mask generated from seed to recover the padded data
pp = &padded->buffer[hLen + 1];
pm = mask;
@ -554,7 +554,7 @@ PssEncode(
CryptDigestUpdate(&hashState, saltSize, salt);
CryptHashEnd(&hashState, hLen, &pOut[out->size - hLen - 1]);
// Create a mask
if(CryptMGF1(mLen, pOut, hashAlg, hLen, &pOut[mLen]) != mLen)
if(CryptMGF_KDF(mLen, pOut, hashAlg, hLen, &pOut[mLen], 0) != mLen)
FAIL(FATAL_ERROR_INTERNAL);
// Since this implementation uses key sizes that are all even multiples of
// 8, just need to make sure that the most significant bit is CLEAR
@ -610,7 +610,7 @@ PssDecode(
// Use the hLen bytes at the end of the buffer to generate a mask
// Doesn't start at the end which is a flag byte
mLen = eIn->size - hLen - 1;
CryptMGF1(mLen, mask, hashAlg, hLen, &pe[mLen]);
CryptMGF_KDF(mLen, mask, hashAlg, hLen, &pe[mLen], 0);
// Clear the MSO of the mask to make it consistent with the encoding.
mask[0] &= 0x7F;
pAssert(mLen <= sizeof(mask));