From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f66.google.com (mail-wr1-f66.google.com [209.85.221.66]) by mx.groups.io with SMTP id smtpd.web10.983.1573717334691250463 for ; Wed, 13 Nov 2019 23:42:15 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@linaro.org header.s=google header.b=P/gBtT9N; spf=pass (domain: linaro.org, ip: 209.85.221.66, mailfrom: ard.biesheuvel@linaro.org) Received: by mail-wr1-f66.google.com with SMTP id b3so5211353wrs.13 for ; Wed, 13 Nov 2019 23:42:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=tkEnD5TmhfeQs3wIP/LZdu+6FVK48GW/dVLsrxl+o2M=; b=P/gBtT9NrxrBk0fCAAll9UEI4B1lTyoaBLk8niR2dHiSPKI7567mL5gVMqCyMU0Rpb RiOY9zTVKbiVvjxOpbF+8emAD2mq+UzcxhgGAB5BhvK88DA58vXyWsjeU45wfDC0mFQg xjpphjKZkV7tkQpyjz7UqFIWyG4hXgrK4aH1PhE1g3riCwDOOXXr5FR9qm4EhyW1vbo5 9qv6TwRkso9A8jlrZWtKmMQgTQMSdWNJnksI9efGXTkDEfN07QfNYfX1QW7i/gAR8M0d QKIaXMAxq66NxDsGKyZoo/dDboMta24hWszfw1MXPRXwCYtsSb0qk7+KJAmr60V0dX/S cSBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=tkEnD5TmhfeQs3wIP/LZdu+6FVK48GW/dVLsrxl+o2M=; b=eh3/jbDPd2cCCy8MpK/ySiNIg6OlJ6c4YqMPdbW7o9grN728nY4BXOSRIXoIBrey+Q 4b3SefzmG2RThaNy5Ka6tUTserFPwTVWBN14e3bXUCfaGAzT/VXz0HsJfTtpu5CKUzkg fRCTyabhjJdZYgQie/GiZQlWGDInnfsm64jfc9Tls1S+A94UGQxYhDQs8YZeVVFFXaLH HVQdZO8cNHL4tuHPyf5n8isITmw7TpLdlSQZEq75ocWwCGlZmePSb/7JfWX8o8bbhGML 5MFBvwdPgJnZx7bnh9rboJRa2OT1N6E0xs1DlS+4GYxFZihTGLxTd106PFeceteVNXvS SxVw== X-Gm-Message-State: APjAAAW74q/cPSOymn+cx+s02D9LUug4A7uIAjeHkX99tdxcONJz6N8g GlTarSGqASZIcZbUqTxou+ylr2teXrQLPBYqcBjNpA== X-Google-Smtp-Source: APXvYqxN3m8Tou/H04nGl9Y9Fk1Waul4guWJymG+e+VZfgRZyJyUiUdOzimYD/9xzu8kxUFlyylYdb7oqZm+wcj1GC4= X-Received: by 2002:adf:f743:: with SMTP id z3mr6504249wrp.200.1573717332991; Wed, 13 Nov 2019 23:42:12 -0800 (PST) MIME-Version: 1.0 References: <20191114021743.3876-1-jian.j.wang@intel.com> <20191114021743.3876-11-jian.j.wang@intel.com> In-Reply-To: <20191114021743.3876-11-jian.j.wang@intel.com> From: "Ard Biesheuvel" Date: Thu, 14 Nov 2019 07:42:03 +0000 Message-ID: Subject: Re: [PATCH 10/11] CryptoPkg/OpensslLib: use RngLib to get high quality random entropy To: Jian J Wang Cc: edk2-devel-groups-io , Xiaoyu Lu , Laszlo Ersek , Jiewen Yao , Chao Zhang , Liming Gao , Ray Ni Content-Type: text/plain; charset="UTF-8" On Thu, 14 Nov 2019 at 02:18, Jian J Wang wrote: > > Per BZ1871, OpensslLib should use RngLib to get high quality of random > entropy. This patch remove all code depending on TimerLib for this job, > and add RngLib interface to implement the rand interface required by > openssl. > > Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871 > Cc: Xiaoyu Lu > Cc: Laszlo Ersek > Cc: Ard Biesheuvel > Cc: Jiewen Yao > Cc: Chao Zhang > Cc: Liming Gao > Cc: Ray Ni > Signed-off-by: Jian J Wang Acked-by: Ard Biesheuvel > --- > CryptoPkg/CryptoPkg.dsc | 1 + > CryptoPkg/Library/OpensslLib/OpensslLib.inf | 15 +- > .../Library/OpensslLib/OpensslLibCrypto.inf | 15 +- > CryptoPkg/Library/OpensslLib/rand_pool.c | 253 ++---------------- > .../Library/OpensslLib/rand_pool_noise.c | 29 -- > .../Library/OpensslLib/rand_pool_noise.h | 29 -- > .../Library/OpensslLib/rand_pool_noise_tsc.c | 43 --- > 7 files changed, 32 insertions(+), 353 deletions(-) > delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise.c > delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise.h > delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c > > diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc > index ec43c1f0a4..54f892996a 100644 > --- a/CryptoPkg/CryptoPkg.dsc > +++ b/CryptoPkg/CryptoPkg.dsc > @@ -44,6 +44,7 @@ > > IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf > OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf > + RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf > > [LibraryClasses.ARM, LibraryClasses.AARCH64] > # > diff --git a/CryptoPkg/Library/OpensslLib/OpensslLib.inf b/CryptoPkg/Library/OpensslLib/OpensslLib.inf > index b28dd9e480..4c535dc1e6 100644 > --- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf > +++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf > @@ -23,7 +23,6 @@ > > [Sources] > buildinf.h > - rand_pool_noise.h > $(OPENSSL_PATH)/e_os.h > # Autogenerated files list starts here > $(OPENSSL_PATH)/crypto/aes/aes_cbc.c > @@ -602,18 +601,6 @@ > ossl_store.c > rand_pool.c > > -[Sources.Ia32] > - rand_pool_noise_tsc.c > - > -[Sources.X64] > - rand_pool_noise_tsc.c > - > -[Sources.ARM] > - rand_pool_noise.c > - > -[Sources.AARCH64] > - rand_pool_noise.c > - > [Packages] > MdePkg/MdePkg.dec > CryptoPkg/CryptoPkg.dec > @@ -621,7 +608,7 @@ > [LibraryClasses] > BaseLib > DebugLib > - TimerLib > + RngLib > PrintLib > > [LibraryClasses.ARM] > diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf > index 1b6ff5ed54..51159a6f2d 100644 > --- a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf > +++ b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf > @@ -547,22 +547,9 @@ > $(OPENSSL_PATH)/crypto/objects/obj_xref.h > # Autogenerated files list ends here > buildinf.h > - rand_pool_noise.h > ossl_store.c > rand_pool.c > > -[Sources.Ia32] > - rand_pool_noise_tsc.c > - > -[Sources.X64] > - rand_pool_noise_tsc.c > - > -[Sources.ARM] > - rand_pool_noise.c > - > -[Sources.AARCH64] > - rand_pool_noise.c > - > [Packages] > MdePkg/MdePkg.dec > CryptoPkg/CryptoPkg.dec > @@ -570,7 +557,7 @@ > [LibraryClasses] > BaseLib > DebugLib > - TimerLib > + RngLib > PrintLib > > [LibraryClasses.ARM] > diff --git a/CryptoPkg/Library/OpensslLib/rand_pool.c b/CryptoPkg/Library/OpensslLib/rand_pool.c > index 9d2a4ad138..f57c238fc4 100644 > --- a/CryptoPkg/Library/OpensslLib/rand_pool.c > +++ b/CryptoPkg/Library/OpensslLib/rand_pool.c > @@ -11,213 +11,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent > #include > > #include > -#include > - > -#include "rand_pool_noise.h" > - > -/** > - Get some randomness from low-order bits of GetPerformanceCounter results. > - And combine them to the 64-bit value > - > - @param[out] Rand Buffer pointer to store the 64-bit random value. > - > - @retval TRUE Random number generated successfully. > - @retval FALSE Failed to generate. > -**/ > -STATIC > -BOOLEAN > -EFIAPI > -GetRandNoise64FromPerformanceCounter( > - OUT UINT64 *Rand > - ) > -{ > - UINT32 Index; > - UINT32 *RandPtr; > - > - if (NULL == Rand) { > - return FALSE; > - } > - > - RandPtr = (UINT32 *) Rand; > - > - for (Index = 0; Index < 2; Index ++) { > - *RandPtr = (UINT32) (GetPerformanceCounter () & 0xFF); > - MicroSecondDelay (10); > - RandPtr++; > - } > - > - return TRUE; > -} > - > -/** > - Calls RandomNumber64 to fill > - a buffer of arbitrary size with random bytes. > - > - @param[in] Length Size of the buffer, in bytes, to fill with. > - @param[out] RandBuffer Pointer to the buffer to store the random result. > - > - @retval EFI_SUCCESS Random bytes generation succeeded. > - @retval EFI_NOT_READY Failed to request random bytes. > - > -**/ > -STATIC > -BOOLEAN > -EFIAPI > -RandGetBytes ( > - IN UINTN Length, > - OUT UINT8 *RandBuffer > - ) > -{ > - BOOLEAN Ret; > - UINT64 TempRand; > - > - Ret = FALSE; > - > - while (Length > 0) { > - // > - // Get random noise from platform. > - // If it failed, fallback to PerformanceCounter > - // If you really care about security, you must override > - // GetRandomNoise64FromPlatform. > - // > - Ret = GetRandomNoise64 (&TempRand); > - if (Ret == FALSE) { > - Ret = GetRandNoise64FromPerformanceCounter (&TempRand); > - } > - if (!Ret) { > - return Ret; > - } > - if (Length >= sizeof (TempRand)) { > - *((UINT64*) RandBuffer) = TempRand; > - RandBuffer += sizeof (UINT64); > - Length -= sizeof (TempRand); > - } else { > - CopyMem (RandBuffer, &TempRand, Length); > - Length = 0; > - } > - } > - > - return Ret; > -} > - > -/** > - Creates a 128bit random value that is fully forward and backward prediction resistant, > - suitable for seeding a NIST SP800-90 Compliant. > - This function takes multiple random numbers from PerformanceCounter to ensure reseeding > - and performs AES-CBC-MAC over the data to compute the seed value. > - > - @param[out] SeedBuffer Pointer to a 128bit buffer to store the random seed. > - > - @retval TRUE Random seed generation succeeded. > - @retval FALSE Failed to request random bytes. > - > -**/ > -STATIC > -BOOLEAN > -EFIAPI > -RandGetSeed128 ( > - OUT UINT8 *SeedBuffer > - ) > -{ > - BOOLEAN Ret; > - UINT8 RandByte[16]; > - UINT8 Key[16]; > - UINT8 Ffv[16]; > - UINT8 Xored[16]; > - UINT32 Index; > - UINT32 Index2; > - AES_KEY AESKey; > - > - // > - // Chose an arbitary key and zero the feed_forward_value (FFV) > - // > - for (Index = 0; Index < 16; Index++) { > - Key[Index] = (UINT8) Index; > - Ffv[Index] = 0; > - } > - > - AES_set_encrypt_key (Key, 16 * 8, &AESKey); > - > - // > - // Perform CBC_MAC over 32 * 128 bit values, with 10us gaps between 128 bit value > - // The 10us gaps will ensure multiple reseeds within the system time with a large > - // design margin. > - // > - for (Index = 0; Index < 32; Index++) { > - MicroSecondDelay (10); > - Ret = RandGetBytes (16, RandByte); > - if (!Ret) { > - return Ret; > - } > - > - // > - // Perform XOR operations on two 128-bit value. > - // > - for (Index2 = 0; Index2 < 16; Index2++) { > - Xored[Index2] = RandByte[Index2] ^ Ffv[Index2]; > - } > - > - AES_encrypt (Xored, Ffv, &AESKey); > - } > - > - for (Index = 0; Index < 16; Index++) { > - SeedBuffer[Index] = Ffv[Index]; > - } > - > - return Ret; > -} > - > -/** > - Generate high-quality entropy source. > - > - @param[in] Length Size of the buffer, in bytes, to fill with. > - @param[out] Entropy Pointer to the buffer to store the entropy data. > - > - @retval EFI_SUCCESS Entropy generation succeeded. > - @retval EFI_NOT_READY Failed to request random data. > - > -**/ > -STATIC > -BOOLEAN > -EFIAPI > -RandGenerateEntropy ( > - IN UINTN Length, > - OUT UINT8 *Entropy > - ) > -{ > - BOOLEAN Ret; > - UINTN BlockCount; > - UINT8 Seed[16]; > - UINT8 *Ptr; > - > - BlockCount = Length / 16; > - Ptr = (UINT8 *) Entropy; > - > - // > - // Generate high-quality seed for DRBG Entropy > - // > - while (BlockCount > 0) { > - Ret = RandGetSeed128 (Seed); > - if (!Ret) { > - return Ret; > - } > - CopyMem (Ptr, Seed, 16); > - > - BlockCount--; > - Ptr = Ptr + 16; > - } > - > - // > - // Populate the remained data as request. > - // > - Ret = RandGetSeed128 (Seed); > - if (!Ret) { > - return Ret; > - } > - CopyMem (Ptr, Seed, (Length % 16)); > - > - return Ret; > -} > +#include > +#include > +#include > > /* > * Add random bytes to the pool to acquire requested amount of entropy > @@ -229,17 +25,30 @@ RandGenerateEntropy ( > */ > size_t rand_pool_acquire_entropy(RAND_POOL *pool) > { > - BOOLEAN Ret; > - size_t bytes_needed; > - unsigned char * buffer; > + BOOLEAN ret; > + size_t bytes_needed; > + size_t len; > + unsigned char *buffer; > + UINT64 data[2]; > > bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); > if (bytes_needed > 0) { > buffer = rand_pool_add_begin(pool, bytes_needed); > > if (buffer != NULL) { > - Ret = RandGenerateEntropy(bytes_needed, buffer); > - if (FALSE == Ret) { > + ret = TRUE; > + while (bytes_needed > 0 && ret) { > + ret = GetRandomNumber128 (data); > + if (ret) { > + len = MIN (bytes_needed, sizeof(data)); > + CopyMem (buffer, data, len); > + > + bytes_needed -= len; > + buffer += len; > + } > + } > + > + if (FALSE == ret) { > rand_pool_add_end(pool, 0, 0); > } else { > rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed); > @@ -257,13 +66,11 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool) > */ > int rand_pool_add_nonce_data(RAND_POOL *pool) > { > - struct { > - UINT64 Rand; > - UINT64 TimerValue; > - } data = { 0 }; > + UINT64 data[2]; > > - RandGetBytes(8, (UINT8 *)&(data.Rand)); > - data.TimerValue = GetPerformanceCounter(); > + if (!GetRandomNumber128 (data)) { > + return 0; > + } > > return rand_pool_add(pool, (unsigned char*)&data, sizeof(data), 0); > } > @@ -275,13 +82,11 @@ int rand_pool_add_nonce_data(RAND_POOL *pool) > */ > int rand_pool_add_additional_data(RAND_POOL *pool) > { > - struct { > - UINT64 Rand; > - UINT64 TimerValue; > - } data = { 0 }; > + UINT64 data[2]; > > - RandGetBytes(8, (UINT8 *)&(data.Rand)); > - data.TimerValue = GetPerformanceCounter(); > + if (!GetRandomNumber128 (data)) { > + return 0; > + } > > return rand_pool_add(pool, (unsigned char*)&data, sizeof(data), 0); > } > diff --git a/CryptoPkg/Library/OpensslLib/rand_pool_noise.c b/CryptoPkg/Library/OpensslLib/rand_pool_noise.c > deleted file mode 100644 > index c16ed8b454..0000000000 > --- a/CryptoPkg/Library/OpensslLib/rand_pool_noise.c > +++ /dev/null > @@ -1,29 +0,0 @@ > -/** @file > - Provide rand noise source. > - > -Copyright (c) 2019, Intel Corporation. All rights reserved.
> -SPDX-License-Identifier: BSD-2-Clause-Patent > - > -**/ > - > -#include > - > -/** > - Get 64-bit noise source > - > - @param[out] Rand Buffer pointer to store 64-bit noise source > - > - @retval FALSE Failed to generate > -**/ > -BOOLEAN > -EFIAPI > -GetRandomNoise64 ( > - OUT UINT64 *Rand > - ) > -{ > - // > - // Return FALSE will fallback to use PerformaceCounter to > - // generate noise. > - // > - return FALSE; > -} > diff --git a/CryptoPkg/Library/OpensslLib/rand_pool_noise.h b/CryptoPkg/Library/OpensslLib/rand_pool_noise.h > deleted file mode 100644 > index 75acc686a9..0000000000 > --- a/CryptoPkg/Library/OpensslLib/rand_pool_noise.h > +++ /dev/null > @@ -1,29 +0,0 @@ > -/** @file > - Provide rand noise source. > - > -Copyright (c) 2019, Intel Corporation. All rights reserved.
> -SPDX-License-Identifier: BSD-2-Clause-Patent > - > -**/ > - > -#ifndef __RAND_POOL_NOISE_H__ > -#define __RAND_POOL_NOISE_H__ > - > -#include > - > -/** > - Get 64-bit noise source. > - > - @param[out] Rand Buffer pointer to store 64-bit noise source > - > - @retval TRUE Get randomness successfully. > - @retval FALSE Failed to generate > -**/ > -BOOLEAN > -EFIAPI > -GetRandomNoise64 ( > - OUT UINT64 *Rand > - ); > - > - > -#endif // __RAND_POOL_NOISE_H__ > diff --git a/CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c b/CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c > deleted file mode 100644 > index 4158106231..0000000000 > --- a/CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c > +++ /dev/null > @@ -1,43 +0,0 @@ > -/** @file > - Provide rand noise source. > - > -Copyright (c) 2019, Intel Corporation. All rights reserved.
> -SPDX-License-Identifier: BSD-2-Clause-Patent > - > -**/ > - > -#include > -#include > -#include > - > -/** > - Get 64-bit noise source > - > - @param[out] Rand Buffer pointer to store 64-bit noise source > - > - @retval TRUE Get randomness successfully. > - @retval FALSE Failed to generate > -**/ > -BOOLEAN > -EFIAPI > -GetRandomNoise64 ( > - OUT UINT64 *Rand > - ) > -{ > - UINT32 Index; > - UINT32 *RandPtr; > - > - if (NULL == Rand) { > - return FALSE; > - } > - > - RandPtr = (UINT32 *)Rand; > - > - for (Index = 0; Index < 2; Index ++) { > - *RandPtr = (UINT32) ((AsmReadTsc ()) & 0xFF); > - RandPtr++; > - MicroSecondDelay (10); > - } > - > - return TRUE; > -} > -- > 2.17.1.windows.2 >