xref: /aosp_15_r20/external/private-join-and-compute/private_join_and_compute/crypto/context.h (revision a6aa18fbfbf9cb5cd47356a9d1b057768998488c)
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