From b51bd9efdfba74c03ad8426e5bef524e863a5de6 Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Fri, 17 Apr 2020 18:33:05 -0400 Subject: [PATCH] tpm2: rev162: Refactor CryptMGF1 and rename to CryptMGF_KDF Signed-off-by: Stefan Berger --- src/tpm2/crypto/CryptHash_fp.h | 9 +++--- src/tpm2/crypto/openssl/CryptHash.c | 50 +++++++++++++---------------- src/tpm2/crypto/openssl/CryptRsa.c | 18 +++++------ 3 files changed, 36 insertions(+), 41 deletions(-) diff --git a/src/tpm2/crypto/CryptHash_fp.h b/src/tpm2/crypto/CryptHash_fp.h index 8bfd205b..adf1ba9f 100644 --- a/src/tpm2/crypto/CryptHash_fp.h +++ b/src/tpm2/crypto/CryptHash_fp.h @@ -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( diff --git a/src/tpm2/crypto/openssl/CryptHash.c b/src/tpm2/crypto/openssl/CryptHash.c index 3d8bcfbd..4b6cb992 100644 --- a/src/tpm2/crypto/openssl/CryptHash.c +++ b/src/tpm2/crypto/openssl/CryptHash.c @@ -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; diff --git a/src/tpm2/crypto/openssl/CryptRsa.c b/src/tpm2/crypto/openssl/CryptRsa.c index 7c3cb367..0d267c6a 100644 --- a/src/tpm2/crypto/openssl/CryptRsa.c +++ b/src/tpm2/crypto/openssl/CryptRsa.c @@ -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));