/* Microsoft Reference Implementation for TPM 2.0 * * The copyright in this software is being made available under the BSD License, * included below. This software may be subject to other third party and * contributor rights, including patent rights, and no such rights are granted * under this license. * * Copyright (c) Microsoft Corporation * * All rights reserved. * * BSD License * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this list * of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this * list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS"" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ //** Introduction // This file contains constant definition shared by CryptUtil and the parts // of the Crypto Engine. // #ifndef _CRYPT_RAND_H #define _CRYPT_RAND_H //** DRBG Structures and Defines // Values and structures for the random number generator. These values are defined // in this header file so that the size of the RNG state can be known to TPM.lib. // This allows the allocation of some space in NV memory for the state to // be stored on an orderly shutdown. // The DRBG based on a symmetric block cipher is defined by three values, // 1) the key size // 2) the block size (the IV size) // 3) the symmetric algorithm #define DRBG_KEY_SIZE_BITS AES_MAX_KEY_SIZE_BITS #define DRBG_IV_SIZE_BITS (AES_MAX_BLOCK_SIZE * 8) #define DRBG_ALGORITHM TPM_ALG_AES typedef tpmKeyScheduleAES DRBG_KEY_SCHEDULE; #define DRBG_ENCRYPT_SETUP(key, keySizeInBits, schedule) \ TpmCryptSetEncryptKeyAES(key, keySizeInBits, schedule) #define DRBG_ENCRYPT(keySchedule, in, out) \ TpmCryptEncryptAES(SWIZZLE(keySchedule, in, out)) #if ((DRBG_KEY_SIZE_BITS % RADIX_BITS) != 0) \ || ((DRBG_IV_SIZE_BITS % RADIX_BITS) != 0) #error "Key size and IV for DRBG must be even multiples of the radix" #endif #if (DRBG_KEY_SIZE_BITS % DRBG_IV_SIZE_BITS) != 0 #error "Key size for DRBG must be even multiple of the cypher block size" #endif // Derived values #define DRBG_MAX_REQUESTS_PER_RESEED (1 << 48) #define DRBG_MAX_REQEST_SIZE (1 << 32) #define pDRBG_KEY(seed) ((DRBG_KEY *)&(((BYTE *)(seed))[0])) #define pDRBG_IV(seed) ((DRBG_IV *)&(((BYTE *)(seed))[DRBG_KEY_SIZE_BYTES])) #define DRBG_KEY_SIZE_WORDS (BITS_TO_CRYPT_WORDS(DRBG_KEY_SIZE_BITS)) #define DRBG_KEY_SIZE_BYTES (DRBG_KEY_SIZE_WORDS * RADIX_BYTES) #define DRBG_IV_SIZE_WORDS (BITS_TO_CRYPT_WORDS(DRBG_IV_SIZE_BITS)) #define DRBG_IV_SIZE_BYTES (DRBG_IV_SIZE_WORDS * RADIX_BYTES) #define DRBG_SEED_SIZE_WORDS (DRBG_KEY_SIZE_WORDS + DRBG_IV_SIZE_WORDS) #define DRBG_SEED_SIZE_BYTES (DRBG_KEY_SIZE_BYTES + DRBG_IV_SIZE_BYTES) typedef union { BYTE bytes[DRBG_KEY_SIZE_BYTES]; crypt_uword_t words[DRBG_KEY_SIZE_WORDS]; } DRBG_KEY; typedef union { BYTE bytes[DRBG_IV_SIZE_BYTES]; crypt_uword_t words[DRBG_IV_SIZE_WORDS]; } DRBG_IV; typedef union { BYTE bytes[DRBG_SEED_SIZE_BYTES]; crypt_uword_t words[DRBG_SEED_SIZE_WORDS]; } DRBG_SEED; #define CTR_DRBG_MAX_REQUESTS_PER_RESEED ((UINT64)1 << 20) #define CTR_DRBG_MAX_BYTES_PER_REQUEST (1 << 16) # define CTR_DRBG_MIN_ENTROPY_INPUT_LENGTH DRBG_SEED_SIZE_BYTES # define CTR_DRBG_MAX_ENTROPY_INPUT_LENGTH DRBG_SEED_SIZE_BYTES # define CTR_DRBG_MAX_ADDITIONAL_INPUT_LENGTH DRBG_SEED_SIZE_BYTES #define TESTING (1 << 0) #define ENTROPY (1 << 1) #define TESTED (1 << 2) #define IsTestStateSet(BIT) ((g_cryptoSelfTestState.rng & BIT) != 0) #define SetTestStateBit(BIT) (g_cryptoSelfTestState.rng |= BIT) #define ClearTestStateBit(BIT) (g_cryptoSelfTestState.rng &= ~BIT) #define IsSelfTest() IsTestStateSet(TESTING) #define SetSelfTest() SetTestStateBit(TESTING) #define ClearSelfTest() ClearTestStateBit(TESTING) #define IsEntropyBad() IsTestStateSet(ENTROPY) #define SetEntropyBad() SetTestStateBit(ENTROPY) #define ClearEntropyBad() ClearTestStateBit(ENTROPY) #define IsDrbgTested() IsTestStateSet(TESTED) #define SetDrbgTested() SetTestStateBit(TESTED) #define ClearDrbgTested() ClearTestStateBit(TESTED) typedef struct { UINT64 reseedCounter; UINT32 magic; DRBG_SEED seed; // contains the key and IV for the counter mode DRBG UINT32 lastValue[4]; // used when the TPM does continuous self-test // for FIPS compliance of DRBG } DRBG_STATE, *pDRBG_STATE; #define DRBG_MAGIC ((UINT32) 0x47425244) // "DRBG" backwards so that it displays typedef struct KDF_STATE { UINT64 counter; UINT32 magic; UINT32 limit; TPM2B *seed; const TPM2B *label; TPM2B *context; TPM_ALG_ID hash; TPM_ALG_ID kdf; UINT16 digestSize; TPM2B_DIGEST residual; } KDF_STATE, *pKDR_STATE; #define KDF_MAGIC ((UINT32) 0x4048444a) // "KDF " backwards // Make sure that any other structures added to this union start with a 64-bit // counter and a 32-bit magic number typedef union { DRBG_STATE drbg; KDF_STATE kdf; } RAND_STATE; // This is the state used when the library uses a random number generator. // A special function is installed for the library to call. That function // picks up the state from this location and uses it for the generation // of the random number. extern RAND_STATE *s_random; // When instrumenting RSA key sieve #if RSA_INSTRUMENT #define PRIME_INDEX(x) ((x) == 512 ? 0 : (x) == 1024 ? 1 : 2) # define INSTRUMENT_SET(a, b) ((a) = (b)) # define INSTRUMENT_ADD(a, b) (a) = (a) + (b) # define INSTRUMENT_INC(a) (a) = (a) + 1 extern UINT32 PrimeIndex; extern UINT32 failedAtIteration[10]; extern UINT32 PrimeCounts[3]; extern UINT32 MillerRabinTrials[3]; extern UINT32 totalFieldsSieved[3]; extern UINT32 bitsInFieldAfterSieve[3]; extern UINT32 emptyFieldsSieved[3]; extern UINT32 noPrimeFields[3]; extern UINT32 primesChecked[3]; extern UINT16 lastSievePrime; #else # define INSTRUMENT_SET(a, b) # define INSTRUMENT_ADD(a, b) # define INSTRUMENT_INC(a) #endif #endif // _CRYPT_RAND_H