From 42cd4619532c500dab79df07d1c36ae917dbae87 Mon Sep 17 00:00:00 2001 From: Zhao Pengfei Date: Fri, 5 Aug 2022 15:14:17 +0800 Subject: [PATCH 1/2] Add RDSEED and RDRAND instruction check in compile time --- CMakeLists.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4bdaf00..92aab59 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,6 +115,23 @@ else() endif() endif() +# check whether cpu support rdseed or rdrand instruction +set(CPU_RDSEED_FLAG "rdseed") +execute_process(COMMAND lscpu COMMAND grep ${CPU_RDSEED_FLAG} OUTPUT_VARIABLE CPU_ENABLE_RDSEED) +if("${CPU_ENABLE_RDSEED}" STREQUAL "") + set(CPU_RDRAND_FLAG "rdrand") + execute_process(COMMAND lscpu COMMAND grep ${CPU_RDRAND_FLAG} OUTPUT_VARIABLE CPU_ENABLE_RDRAND) + if("${CPU_ENABLE_RDRAND}" STREQUAL "") + message(WARNING "CPU doesn't support RDSEED and RDRAND instruction, using random generator will cause errors.") + else () + message(STATUS "Support RDRAND instruction: True") + add_compile_definitions(IPCL_RNG_INSTR_RDRAND) + endif() +else() + message(STATUS "Support RDSEED instruction: True") + add_compile_definitions(IPCL_RNG_INSTR_RDSEED) +endif() + # find package for OpenSSL and Threads set(OPENSSL_USE_STATIC_LIBS TRUE) find_package(Threads REQUIRED) From eb33d6de086e6a1fa5b034ffd45c57defc797649 Mon Sep 17 00:00:00 2001 From: Zhao Pengfei Date: Fri, 5 Aug 2022 15:29:04 +0800 Subject: [PATCH 2/2] Use RDSEED/RDRAND to produce random big number --- ipcl/CMakeLists.txt | 1 + ipcl/common.cpp | 42 +++++++++++++++++++++++++++++++++++ ipcl/include/ipcl/common.hpp | 9 ++++++++ ipcl/include/ipcl/pub_key.hpp | 14 ------------ ipcl/keygen.cpp | 24 +++++--------------- ipcl/pub_key.cpp | 38 +++---------------------------- 6 files changed, 60 insertions(+), 68 deletions(-) create mode 100644 ipcl/common.cpp diff --git a/ipcl/CMakeLists.txt b/ipcl/CMakeLists.txt index ef76656..b1388b2 100644 --- a/ipcl/CMakeLists.txt +++ b/ipcl/CMakeLists.txt @@ -10,6 +10,7 @@ set(IPCL_SRCS pri_key.cpp plaintext.cpp ciphertext.cpp util.cpp + common.cpp ) diff --git a/ipcl/common.cpp b/ipcl/common.cpp new file mode 100644 index 0000000..b4813d0 --- /dev/null +++ b/ipcl/common.cpp @@ -0,0 +1,42 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "ipcl/common.hpp" + +#include + +#include "ipcl/util.hpp" + +namespace ipcl { + +BigNumber getRandomBN(int bit_len) { + IppStatus stat; + int bn_buf_size; + + int bn_len = BITSIZE_WORD(bit_len); + stat = ippsBigNumGetSize(bn_len, &bn_buf_size); + ERROR_CHECK(stat == ippStsNoErr, + "getRandomBN: get IppsBigNumState context error."); + + IppsBigNumState* pBN = + reinterpret_cast(alloca(bn_buf_size)); + ERROR_CHECK(pBN != nullptr, "getRandomBN: big number alloca error"); + + stat = ippsBigNumInit(bn_len, pBN); + ERROR_CHECK(stat == ippStsNoErr, + "getRandomBN: init big number context error."); + +#ifdef IPCL_RNG_INSTR_RDSEED + ippsTRNGenRDSEED_BN(pBN, bit_len, NULL); +#elif defined(IPCL_RNG_INSTR_RDRAND) + ippsPRNGenRDRAND_BN(pBN, bit_len, NULL); +#else + ERROR_CHECK( + false, + "getRandomBN: CPU doest NOT support RDSEED and RDRAND instruction"); +#endif + + return BigNumber{pBN}; +} + +} // namespace ipcl diff --git a/ipcl/include/ipcl/common.hpp b/ipcl/include/ipcl/common.hpp index f954026..e83d476 100644 --- a/ipcl/include/ipcl/common.hpp +++ b/ipcl/include/ipcl/common.hpp @@ -4,9 +4,18 @@ #ifndef IPCL_INCLUDE_IPCL_COMMON_HPP_ #define IPCL_INCLUDE_IPCL_COMMON_HPP_ +#include "ipcl/bignum.h" + namespace ipcl { constexpr int IPCL_CRYPTO_MB_SIZE = 8; +/** + * Get random value + * @param[in] length bit length + * @return the random value of type BigNumber + */ +BigNumber getRandomBN(int length); + } // namespace ipcl #endif // IPCL_INCLUDE_IPCL_COMMON_HPP_ diff --git a/ipcl/include/ipcl/pub_key.hpp b/ipcl/include/ipcl/pub_key.hpp index 6938e40..1b28d19 100644 --- a/ipcl/include/ipcl/pub_key.hpp +++ b/ipcl/include/ipcl/pub_key.hpp @@ -128,13 +128,6 @@ class PublicKey { std::vector m_r; bool m_testv; - /** - * Get random value - * @param[in] size size of random - * @return addr of random of type Ipp32u vector - */ - std::vector randIpp32u(int size) const; - /** * Big number vector multi buffer encryption * @param[in] pt plaintext of BigNumber vector type @@ -144,13 +137,6 @@ class PublicKey { std::vector raw_encrypt(const std::vector& pt, bool make_secure = true) const; - /** - * Get random value - * @param[in] length bit length - * @return the random value of type BigNumber - */ - BigNumber getRandom(int length) const; - void applyDjnObfuscator(std::vector& obfuscator) const; void applyNormalObfuscator(std::vector& obfuscator) const; diff --git a/ipcl/keygen.cpp b/ipcl/keygen.cpp index efbf1d6..789bfea 100644 --- a/ipcl/keygen.cpp +++ b/ipcl/keygen.cpp @@ -3,8 +3,6 @@ #include "ipcl/keygen.hpp" -#include -#include #include #include "ipcl/util.hpp" @@ -12,14 +10,7 @@ namespace ipcl { constexpr int N_BIT_SIZE_MAX = 2048; -constexpr int N_BIT_SIZE_MIN = 16; - -static void rand32u(std::vector& addr) { - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(0, UINT_MAX); - for (auto& x : addr) x = (dist(rng) << 16) + dist(rng); -} +constexpr int N_BIT_SIZE_MIN = 200; BigNumber getPrimeBN(int maxBitSize) { int PrimeSize; @@ -27,19 +18,14 @@ BigNumber getPrimeBN(int maxBitSize) { auto primeGen = std::vector(PrimeSize); ippsPrimeInit(maxBitSize, reinterpret_cast(primeGen.data())); - // define Pseudo Random Generator (default settings) + // default seed bit size constexpr int seedBitSize = 160; - constexpr int seedSize = BITSIZE_WORD(seedBitSize); + BigNumber seed = getRandomBN(seedBitSize); - ippsPRNGGetSize(&PrimeSize); auto rand = std::vector(PrimeSize); ippsPRNGInit(seedBitSize, reinterpret_cast(rand.data())); - auto seed = std::vector(seedSize); - rand32u(seed); - BigNumber bseed(seed.data(), seedSize, IppsBigNumPOS); - - ippsPRNGSetSeed(BN(bseed), reinterpret_cast(rand.data())); + ippsPRNGSetSeed(seed, reinterpret_cast(rand.data())); // generate maxBit prime BigNumber pBN(0, maxBitSize / 8); @@ -111,7 +97,7 @@ keyPair generateKeypair(int64_t n_length, bool enable_DJN) { "generateKeyPair: modulus size in bits should belong to either 1Kb, 2Kb, " "3Kb or 4Kb range only, key size exceed the range!!!"); ERROR_CHECK((n_length >= N_BIT_SIZE_MIN) && (n_length % 4 == 0), - "generateKeyPair: key size should >=16, and divisible by 4"); + "generateKeyPair: key size should >=200, and divisible by 4"); BigNumber ref_dist = getPrimeDistance(n_length); diff --git a/ipcl/pub_key.cpp b/ipcl/pub_key.cpp index d19c915..0968691 100644 --- a/ipcl/pub_key.cpp +++ b/ipcl/pub_key.cpp @@ -35,44 +35,12 @@ PublicKey::PublicKey(const BigNumber& n, int bits, bool enableDJN_) if (enableDJN_) this->enableDJN(); // sets m_enable_DJN } -// array of 32-bit random, using rand() from stdlib -std::vector PublicKey::randIpp32u(int size) const { - std::vector addr(size); - // TODO(skmono): check if copy of m_init_seed is needed for const - unsigned int init_seed = m_init_seed; - for (auto& a : addr) a = (rand_r(&init_seed) << 16) + rand_r(&init_seed); - return addr; -} - -// length is arbitrary -BigNumber PublicKey::getRandom(int bit_len) const { - IppStatus stat; - int bn_buf_size; - - // define length Big Numbers - int bn_len = BITSIZE_WORD(bit_len); - stat = ippsBigNumGetSize(bn_len, &bn_buf_size); - ERROR_CHECK(stat == ippStsNoErr, - "getRandom: get IppsBigNumState context error."); - - IppsBigNumState* pBN = - reinterpret_cast(alloca(bn_buf_size)); - ERROR_CHECK(pBN != nullptr, "getRandom: big number alloca error"); - - stat = ippsBigNumInit(bn_len, pBN); - ERROR_CHECK(stat == ippStsNoErr, "getRandom: init big number context error."); - - ippsPRNGenRDRAND_BN(pBN, bit_len, NULL); - - return BigNumber{pBN}; -} - void PublicKey::enableDJN() { BigNumber gcd; BigNumber rmod; do { int rand_bit = m_n.BitSize(); - BigNumber rand = getRandom(rand_bit + 128); + BigNumber rand = getRandomBN(rand_bit + 128); rmod = rand % m_n; gcd = rand.gcd(m_n); } while (gcd.compare(1)); @@ -96,7 +64,7 @@ void PublicKey::applyDjnObfuscator(std::vector& obfuscator) const { r = m_r; } else { for (auto& r_ : r) { - r_ = getRandom(m_randbits); + r_ = getRandomBN(m_randbits); } } obfuscator = ipcl::ippModExp(base, r, sq); @@ -113,7 +81,7 @@ void PublicKey::applyNormalObfuscator( r = m_r; } else { for (int i = 0; i < obf_size; i++) { - r[i] = getRandom(m_bits); + r[i] = getRandomBN(m_bits); r[i] = r[i] % (m_n - 1) + 1; } }