1 /* 2 * Copyright 2019 Google LLC. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * https://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef PRIVATE_JOIN_AND_COMPUTE_CRYPTO_CONTEXT_H_ 17 #define PRIVATE_JOIN_AND_COMPUTE_CRYPTO_CONTEXT_H_ 18 19 #include <stdint.h> 20 21 #include <memory> 22 #include <string> 23 24 #include "absl/log/check.h" 25 #include "absl/strings/string_view.h" 26 #include "private_join_and_compute/crypto/big_num.h" 27 #include "private_join_and_compute/crypto/openssl.inc" 28 29 #define CRYPTO_CHECK(expr) CHECK(expr) << OpenSSLErrorString(); 30 31 namespace private_join_and_compute { 32 33 std::string OpenSSLErrorString(); 34 35 // Wrapper around various contexts needed for openssl operations. It holds a 36 // BN_CTX to be reused when doing BigNum arithmetic operations and an EVP_MD_CTX 37 // to be reused when doing hashing operations. 38 // 39 // This class provides factory methods for creating BigNum objects that take 40 // advantage of the BN_CTX structure for arithmetic operations. 41 // 42 // This class is not thread-safe, so each thread needs to have a unique Context 43 // initialized. 44 class Context { 45 public: 46 // Deletes a BN_CTX. 47 class BnCtxDeleter { 48 public: operator()49 void operator()(BN_CTX* ctx) { BN_CTX_free(ctx); } 50 }; 51 typedef std::unique_ptr<BN_CTX, BnCtxDeleter> BnCtxPtr; 52 53 // Deletes an EVP_MD_CTX. 54 class EvpMdCtxDeleter { 55 public: operator()56 void operator()(EVP_MD_CTX* ctx) { EVP_MD_CTX_destroy(ctx); } 57 }; 58 typedef std::unique_ptr<EVP_MD_CTX, EvpMdCtxDeleter> EvpMdCtxPtr; 59 60 Context(); 61 62 // Context is neither copyable nor movable. 63 Context(const Context&) = delete; 64 Context& operator=(const Context&) = delete; 65 66 virtual ~Context(); 67 68 // Returns a pointer to the openssl BN_CTX that can be reused for arithmetic 69 // operations. 70 BN_CTX* GetBnCtx(); 71 72 // Creates a BigNum initialized with the given BIGNUM value. 73 BigNum CreateBigNum(BigNum::BignumPtr bn); 74 75 // Creates a BigNum initialized with the given bytes string. 76 BigNum CreateBigNum(absl::string_view bytes); 77 78 // Creates a BigNum initialized with the given number. 79 BigNum CreateBigNum(uint64_t number); 80 81 // Hashes a string using SHA-256 to a byte string. 82 virtual std::string Sha256String(absl::string_view bytes); 83 84 // Hashes a string using SHA-384 to a byte string. 85 virtual std::string Sha384String(absl::string_view bytes); 86 87 // Hashes a string using SHA-512 to a byte string. 88 virtual std::string Sha512String(absl::string_view bytes); 89 90 // A random oracle function mapping x deterministically into a large domain. 91 // 92 // The random oracle is similar to the example given in the last paragraph of 93 // Chapter 6 of [1] where the output is expanded by successively hashing the 94 // concatenation of the input with a fixed sized counter starting from 1. 95 // 96 // [1] Bellare, Mihir, and Phillip Rogaway. "Random oracles are practical: 97 // A paradigm for designing efficient protocols." Proceedings of the 1st ACM 98 // conference on Computer and communications security. ACM, 1993. 99 // 100 // Returns a long value from the set [0, max_value). 101 // 102 // Check Error: if bit length of max_value is greater than 130048. 103 // Since the counter used for expanding the output is expanded to 8 bit length 104 // (hard-coded), any counter value that is greater than 256 would cause 105 // variable length inputs passed to the underlying sha256/sha512 calls and 106 // might make this random oracle's output not uniform across the output 107 // domain. 108 // 109 // The output length is increased by a security value of 256/512 which reduces 110 // the bias of selecting certain values more often than others when max_value 111 // is not a multiple of 2. 112 virtual BigNum RandomOracleSha256(absl::string_view x, 113 const BigNum& max_value); 114 virtual BigNum RandomOracleSha384(absl::string_view x, 115 const BigNum& max_value); 116 virtual BigNum RandomOracleSha512(absl::string_view x, 117 const BigNum& max_value); 118 119 // Evaluates a PRF keyed by 'key' on the given data. The returned value is 120 // less than max_value. 121 // 122 // The maximum supported output length is 512. Causes a check failure if the 123 // bit length of max_value is > 512. 124 // 125 // Security: 126 // The security of this function is given by the length of the key. The key 127 // should be at least 80 bits long which gives 80 bit security. Fails if the 128 // key is less than 80 bits. 129 // 130 // This function is susceptible to timing attacks. 131 BigNum PRF(absl::string_view key, absl::string_view data, 132 const BigNum& max_value); 133 134 // Creates a safe prime BigNum with the given bit-length. 135 BigNum GenerateSafePrime(int prime_length); 136 137 // Creates a prime BigNum with the given bit-length. 138 // 139 // Note: In many cases, we need to use a safe prime for cryptographic security 140 // to hold. In this case, we should use GenerateSafePrime. 141 BigNum GeneratePrime(int prime_length); 142 143 // Generates a cryptographically strong pseudo-random in the range [0, 144 // max_value). 145 // Marked virtual for tests. 146 virtual BigNum GenerateRandLessThan(const BigNum& max_value); 147 148 // Generates a cryptographically strong pseudo-random in the range [start, 149 // end). 150 // Marked virtual for tests. 151 virtual BigNum GenerateRandBetween(const BigNum& start, const BigNum& end); 152 153 // Generates a cryptographically strong pseudo-random bytes of the specified 154 // length. 155 // Marked virtual for tests. 156 virtual std::string GenerateRandomBytes(int num_bytes); 157 158 // Returns a BigNum that is relatively prime to the num and less than the num. 159 virtual BigNum RelativelyPrimeRandomLessThan(const BigNum& num); 160 Zero()161 inline const BigNum& Zero() const { return zero_bn_; } One()162 inline const BigNum& One() const { return one_bn_; } Two()163 inline const BigNum& Two() const { return two_bn_; } Three()164 inline const BigNum& Three() const { return three_bn_; } 165 166 private: 167 BnCtxPtr bn_ctx_; 168 EvpMdCtxPtr evp_md_ctx_; 169 HMAC_CTX hmac_ctx_; 170 const BigNum zero_bn_; 171 const BigNum one_bn_; 172 const BigNum two_bn_; 173 const BigNum three_bn_; 174 175 enum RandomOracleHashType { 176 SHA256, 177 SHA384, 178 SHA512, 179 }; 180 181 // If hash_type is invalid, this function will default to using SHA256. 182 virtual BigNum RandomOracle(absl::string_view x, const BigNum& max_value, 183 RandomOracleHashType hash_type); 184 }; 185 186 } // namespace private_join_and_compute 187 188 #endif // PRIVATE_JOIN_AND_COMPUTE_CRYPTO_CONTEXT_H_ 189