1 // Copyright 2023 Google LLC
2 //
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 #include "anonymous_tokens/cpp/crypto/crypto_utils.h"
16
17 #include <memory>
18 #include <string>
19 #include <utility>
20 #include <vector>
21
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24 #include "absl/strings/escaping.h"
25 #include "anonymous_tokens/cpp/testing/utils.h"
26 #include <openssl/base.h>
27 #include <openssl/rsa.h>
28
29
30 namespace anonymous_tokens {
31 namespace {
32
33 struct IetfNewPublicExponentWithPublicMetadataTestVector {
34 std::string rsa_modulus;
35 std::string e;
36 std::string public_metadata;
37 std::string new_e;
38 };
39
TEST(AnonymousTokensCryptoUtilsTest,BignumToStringAndBack)40 TEST(AnonymousTokensCryptoUtilsTest, BignumToStringAndBack) {
41 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(BnCtxPtr ctx, GetAndStartBigNumCtx());
42
43 // Create a new BIGNUM using the context and set it
44 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> bn_1, NewBigNum());
45 ASSERT_EQ(BN_set_u64(bn_1.get(), 0x124435435), 1);
46 EXPECT_NE(bn_1, nullptr);
47 EXPECT_EQ(BN_is_zero(bn_1.get()), 0);
48 EXPECT_EQ(BN_is_one(bn_1.get()), 0);
49
50 // Convert bn_1 to string from BIGNUM
51 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
52 const std::string converted_str,
53 BignumToString(*bn_1, BN_num_bytes(bn_1.get())));
54 // Convert the string version of bn_1 back to BIGNUM
55 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> bn_2,
56 StringToBignum(converted_str));
57 // Check whether the conversion back worked
58 EXPECT_EQ(BN_cmp(bn_1.get(), bn_2.get()), 0);
59 }
60
TEST(AnonymousTokensCryptoUtilsTest,PowerOfTwoAndRsaSqrtTwo)61 TEST(AnonymousTokensCryptoUtilsTest, PowerOfTwoAndRsaSqrtTwo) {
62 // Compute 2^(10-1/2).
63 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> sqrt2,
64 GetRsaSqrtTwo(10));
65 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> small_pow2,
66 ComputePowerOfTwo(9));
67 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> large_pow2,
68 ComputePowerOfTwo(10));
69 EXPECT_GT(BN_cmp(sqrt2.get(), small_pow2.get()), 0);
70 EXPECT_LT(BN_cmp(sqrt2.get(), large_pow2.get()), 0);
71 }
72
TEST(AnonymousTokensCryptoUtilsTest,ComputeHashAcceptsNullStringView)73 TEST(AnonymousTokensCryptoUtilsTest, ComputeHashAcceptsNullStringView) {
74 absl::StatusOr<std::string> null_hash =
75 ComputeHash(absl::string_view(nullptr, 0), *EVP_sha512());
76 absl::StatusOr<std::string> empty_hash = ComputeHash("", *EVP_sha512());
77 std::string str;
78 absl::StatusOr<std::string> empty_str_hash = ComputeHash(str, *EVP_sha512());
79
80 ASSERT_TRUE(null_hash.ok());
81 ASSERT_TRUE(empty_hash.ok());
82 ASSERT_TRUE(empty_str_hash.ok());
83
84 EXPECT_EQ(*null_hash, *empty_hash);
85 EXPECT_EQ(*null_hash, *empty_str_hash);
86 }
87
TEST(AnonymousTokensCryptoUtilsTest,ComputeCarmichaelLcm)88 TEST(AnonymousTokensCryptoUtilsTest, ComputeCarmichaelLcm) {
89 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(BnCtxPtr ctx, GetAndStartBigNumCtx());
90
91 // Suppose that N = 1019 * 1187.
92 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> phi_p, NewBigNum());
93 ASSERT_TRUE(BN_set_word(phi_p.get(), 1019 - 1));
94 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> phi_q, NewBigNum());
95 ASSERT_TRUE(BN_set_word(phi_q.get(), 1187 - 1));
96 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> expected_lcm,
97 NewBigNum());
98 ASSERT_TRUE(BN_set_word(expected_lcm.get(), (1019 - 1) * (1187 - 1) / 2));
99
100 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> lcm,
101 ComputeCarmichaelLcm(*phi_p, *phi_q, *ctx));
102 EXPECT_EQ(BN_cmp(lcm.get(), expected_lcm.get()), 0);
103 }
104
105 struct ComputeHashTestParam {
106 const EVP_MD* hasher;
107 absl::string_view input_hex;
108 absl::string_view expected_digest_hex;
109 };
110
111 using ComputeHashTest = testing::TestWithParam<ComputeHashTestParam>;
112
113 // Returns the test parameters for ComputeHashTestParam from NIST's
114 // samples.
GetComputeHashTestParams()115 std::vector<ComputeHashTestParam> GetComputeHashTestParams() {
116 std::vector<ComputeHashTestParam> params;
117 params.push_back({
118 EVP_sha256(),
119 "af397a8b8dd73ab702ce8e53aa9f",
120 "d189498a3463b18e846b8ab1b41583b0b7efc789dad8a7fb885bbf8fb5b45c5c",
121 });
122 params.push_back({
123 EVP_sha256(),
124 "59eb45bbbeb054b0b97334d53580ce03f699",
125 "32c38c54189f2357e96bd77eb00c2b9c341ebebacc2945f97804f59a93238288",
126 });
127 params.push_back({
128 EVP_sha512(),
129 "16b17074d3e3d97557f9ed77d920b4b1bff4e845b345a922",
130 "6884134582a760046433abcbd53db8ff1a89995862f305b887020f6da6c7b903a314721e"
131 "972bf438483f452a8b09596298a576c903c91df4a414c7bd20fd1d07",
132 });
133 params.push_back({
134 EVP_sha512(),
135 "7651ab491b8fa86f969d42977d09df5f8bee3e5899180b52c968b0db057a6f02a886ad61"
136 "7a84915a",
137 "f35e50e2e02b8781345f8ceb2198f068ba103476f715cfb487a452882c9f0de0c720b2a0"
138 "88a39d06a8a6b64ce4d6470dfeadc4f65ae06672c057e29f14c4daf9",
139 });
140 return params;
141 }
142
TEST_P(ComputeHashTest,ComputesHash)143 TEST_P(ComputeHashTest, ComputesHash) {
144 const ComputeHashTestParam& params = GetParam();
145 ASSERT_NE(params.hasher, nullptr);
146 std::string data = absl::HexStringToBytes(params.input_hex);
147 std::string expected_digest =
148 absl::HexStringToBytes(params.expected_digest_hex);
149 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto computed_hash,
150 ComputeHash(data, *params.hasher));
151 EXPECT_EQ(computed_hash, expected_digest);
152 }
153
154 INSTANTIATE_TEST_SUITE_P(ComputeHashTests, ComputeHashTest,
155 testing::ValuesIn(GetComputeHashTestParams()));
156
TEST(PublicMetadataCryptoUtilsInternalTest,PublicMetadataHashWithHKDF)157 TEST(PublicMetadataCryptoUtilsInternalTest, PublicMetadataHashWithHKDF) {
158 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(BnCtxPtr ctx, GetAndStartBigNumCtx());
159 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> max_value,
160 NewBigNum());
161 ASSERT_TRUE(BN_set_word(max_value.get(), 4294967295));
162 const auto [public_key, _] = GetStrongTestRsaKeyPair2048();
163 std::string input1 = "ro1";
164 std::string input2 = "ro2";
165 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
166 bssl::UniquePtr<BIGNUM> output1,
167 internal::PublicMetadataHashWithHKDF(input1, public_key.n,
168 1 + input1.size()));
169 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
170 bssl::UniquePtr<BIGNUM> another_output1,
171 internal::PublicMetadataHashWithHKDF(input1, public_key.n,
172 1 + input1.size()));
173 EXPECT_EQ(BN_cmp(output1.get(), another_output1.get()), 0);
174
175 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
176 bssl::UniquePtr<BIGNUM> output2,
177 internal::PublicMetadataHashWithHKDF(input2, public_key.n,
178 1 + input2.size()));
179 EXPECT_NE(BN_cmp(output1.get(), output2.get()), 0);
180
181 EXPECT_LE(BN_cmp(output1.get(), max_value.get()), 0);
182 EXPECT_LE(BN_cmp(output2.get(), max_value.get()), 0);
183 }
184
TEST(PublicMetadataCryptoUtilsTest,PublicExponentHashDifferentModulus)185 TEST(PublicMetadataCryptoUtilsTest, PublicExponentHashDifferentModulus) {
186 const auto public_key_1 = std::get<0>(GetStrongTestRsaKeyPair2048());
187 const auto public_key_2 = std::get<0>(GetAnotherStrongTestRsaKeyPair2048());
188 std::string metadata = "md";
189 // Check that same metadata and different modulus result in different
190 // hashes.
191 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> rsa_modulus_1,
192 StringToBignum(public_key_1.n));
193 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
194 bssl::UniquePtr<BIGNUM> exp1,
195 ComputeExponentWithPublicMetadata(*rsa_modulus_1.get(), metadata));
196 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto rsa_modulus_2,
197 StringToBignum(public_key_2.n));
198 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
199 bssl::UniquePtr<BIGNUM> exp2,
200 ComputeExponentWithPublicMetadata(*rsa_modulus_2.get(), metadata));
201 EXPECT_NE(BN_cmp(exp1.get(), exp2.get()), 0);
202 }
203
204 std::vector<IetfNewPublicExponentWithPublicMetadataTestVector>
GetIetfNewPublicExponentWithPublicMetadataTestVectors(bool use_rsa_public_exponent)205 GetIetfNewPublicExponentWithPublicMetadataTestVectors(
206 bool use_rsa_public_exponent) {
207 std::vector<IetfNewPublicExponentWithPublicMetadataTestVector> test_vectors;
208
209 std::string modulus = absl::HexStringToBytes(
210 "d6930820f71fe517bf3259d14d40209b02a5c0d3d61991c731dd7da39f8d69821552e231"
211 "8d6c9ad897e603887a476ea3162c1205da9ac96f02edf31df049bd55f142134c17d4382a"
212 "0e78e275345f165fbe8e49cdca6cf5c726c599dd39e09e75e0f330a33121e73976e4facb"
213 "a9cfa001c28b7c96f8134f9981db6750b43a41710f51da4240fe03106c12acb1e7bb53d7"
214 "5ec7256da3fddd0718b89c365410fce61bc7c99b115fb4c3c318081fa7e1b65a37774e8e"
215 "50c96e8ce2b2cc6b3b367982366a2bf9924c4bafdb3ff5e722258ab705c76d43e5f1f121"
216 "b984814e98ea2b2b8725cd9bc905c0bc3d75c2a8db70a7153213c39ae371b2b5dc1dafcb"
217 "19d6fae9");
218 std::string e = absl::HexStringToBytes("010001");
219
220 if (use_rsa_public_exponent) {
221 // Test vector 1
222 test_vectors.push_back(
223 {.rsa_modulus = modulus,
224 .e = e,
225 .public_metadata = absl::HexStringToBytes("6d65746164617461"),
226 .new_e = absl::HexStringToBytes(
227 "30584b72f5cb557085106232f051d039e23358feee9204cf30ea567620e90d79e"
228 "4a7a81388b1f390e18ea5240a1d8cc296ce1325128b445c48aa5a3b34fa07c324"
229 "bf17bc7f1b3efebaff81d7e032948f1477493bc183d2f8d94c947c984c6f07575"
230 "27615bf2a2f0ef0db5ad80ce99905beed0440b47fa5cb9a2334fea40ad88e6ef"
231 "1")});
232
233 // Test vector 2
234 test_vectors.push_back(
235 {.rsa_modulus = modulus,
236 .e = e,
237 .public_metadata = "",
238 .new_e = absl::HexStringToBytes(
239 "2ed5a8d2592a11bbeef728bb39018ef5c3cf343507dd77dd156d5eec7f06f0473"
240 "2e4be944c5d2443d244c59e52c9fa5e8de40f55ffd0e70fbe9093d3f7be2aafd7"
241 "7c14b263b71c1c6b3ca2b9629842a902128fee4878392a950906fae35d6194e0d"
242 "2548e58bbc20f841188ca2fceb20b2b1b45448da5c7d1c73fb6e83fa58867397"
243 "b")});
244 } else {
245 // Test vector 1
246 test_vectors.push_back(
247 {.rsa_modulus = modulus,
248 .e = e,
249 .public_metadata = absl::HexStringToBytes("6d65746164617461"),
250 .new_e = absl::HexStringToBytes(
251 "30581b1adab07ac00a5057e2986f37caaa68ae963ffbc4d36c16ea5f3689d6f00"
252 "db79a5bee56053adc53c8d0414d4b754b58c7cc4abef99d4f0d0b2e29cbddf746"
253 "c7d0f4ae2690d82a2757b088820c0d086a40d180b2524687060d768ad5e431732"
254 "102f4bc3572d97e01dcd6301368f255faae4606399f91fa913a6d699d6ef1")});
255
256 // Test vector 2
257 test_vectors.push_back(
258 {.rsa_modulus = modulus,
259 .e = e,
260 .public_metadata = "",
261 .new_e = absl::HexStringToBytes(
262 "2ed579fcdf2d328ebc686c52ccaec247018832acd530a2ac72c0ec2b92db5d6bd"
263 "578e91b6341c1021142b45b9e6e5bf031f3dd62226ec4a0f9ef99e45dd9ccd60a"
264 "a60a0c59aac271a8caf9ee68a9d9ff281367dae09d588d3c7bca7f18de48b6981"
265 "bbc729c4925c65e4b2a7f054facbb7e5fc6e4c6c10110c62ef0b94eec397b")});
266 }
267 return test_vectors;
268 }
269
TEST(PublicMetadataCryptoUtilsTest,IetfNewPublicExponentWithPublicMetadataTests)270 TEST(PublicMetadataCryptoUtilsTest,
271 IetfNewPublicExponentWithPublicMetadataTests) {
272 const auto test_vectors =
273 GetIetfNewPublicExponentWithPublicMetadataTestVectors(
274 /*use_rsa_public_exponent=*/true);
275 for (const IetfNewPublicExponentWithPublicMetadataTestVector& test_vector :
276 test_vectors) {
277 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> rsa_modulus,
278 StringToBignum(test_vector.rsa_modulus));
279 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> rsa_e,
280 StringToBignum(test_vector.e));
281 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> expected_new_e,
282 StringToBignum(test_vector.new_e));
283 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
284 bssl::UniquePtr<BIGNUM> modified_e,
285 ComputeExponentWithPublicMetadataAndPublicExponent(
286 *rsa_modulus.get(), *rsa_e.get(), test_vector.public_metadata));
287
288 EXPECT_EQ(BN_cmp(modified_e.get(), expected_new_e.get()), 0);
289 }
290 }
291
TEST(PublicMetadataCryptoUtilsTest,IetfNewPublicExponentWithPublicMetadataNoPublicExponentTests)292 TEST(PublicMetadataCryptoUtilsTest,
293 IetfNewPublicExponentWithPublicMetadataNoPublicExponentTests) {
294 const auto test_vectors =
295 GetIetfNewPublicExponentWithPublicMetadataTestVectors(
296 /*use_rsa_public_exponent=*/false);
297 for (const IetfNewPublicExponentWithPublicMetadataTestVector& test_vector :
298 test_vectors) {
299 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> rsa_modulus,
300 StringToBignum(test_vector.rsa_modulus));
301 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> expected_new_e,
302 StringToBignum(test_vector.new_e));
303 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
304 bssl::UniquePtr<BIGNUM> modified_e,
305 ComputeExponentWithPublicMetadata(*rsa_modulus.get(),
306 test_vector.public_metadata));
307
308 EXPECT_EQ(BN_cmp(modified_e.get(), expected_new_e.get()), 0);
309 }
310 }
311
TEST(AnonymousTokensCryptoUtilsTest,RsaPssDerEncoding)312 TEST(AnonymousTokensCryptoUtilsTest, RsaPssDerEncoding) {
313 std::string rsa_modulus = absl::HexStringToBytes(
314 "b259758bb02bc75b68b17612c9bf68c5fa05958a334c61e167bc20bcc75757c126e892"
315 "10b9df3989072cf6260e6883c7cd4af4d31dde9915b69b301fbef962de8c71bd2db5ec62"
316 "5da259712f86a8dc3d241e9688c82391b7bf1ebc358311f55c26be910b76f61fea408ed6"
317 "92f1a9578a622c82c0fcf6f69ef3670e38bfc90f63da4f3bbbd088c8ae7a3c5a55e66f64"
318 "74d562d32cce7b7edd7cf0149ca0e96cb6525e81fbba815a8f12748e34e5135f572b2e17"
319 "b7ba430081597e6fb9033c005884d5935118c60d75b010f6fece7ecdcc1cb7d58d138969"
320 "3d43377f4f3de949cb1e4105e792b96d7f04b0cd262ac33cffc5a890d267425e61c19e93"
321 "63550f2285");
322 // A hex string of 3 bytes in length is passed.
323 std::string e_not_padded = absl::HexStringToBytes("010001");
324 // A hex string of 4 bytes in length is passed.
325 std::string e_padded = absl::HexStringToBytes("00010001");
326
327 // Convert both padded and not padded rsa public keys to rsa structs.
328 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
329 bssl::UniquePtr<RSA> rsa_e_not_padded,
330 CreatePublicKeyRSA(rsa_modulus, e_not_padded));
331 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<RSA> rsa_e_padded,
332 CreatePublicKeyRSA(rsa_modulus, e_padded));
333 // Encode both padded and not padded rsa structs to DER.
334 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
335 std::string result_e_not_padded,
336 RsaSsaPssPublicKeyToDerEncoding(rsa_e_not_padded.get()));
337 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
338 std::string result_e_padded,
339 RsaSsaPssPublicKeyToDerEncoding(rsa_e_padded.get()));
340
341 std::string expected_der_encoding = absl::HexStringToBytes(
342 "30820152303d06092a864886f70d01010a3030a00d300b0609608648016503040202a11a"
343 "301806092a864886f70d010108300b0609608648016503040202a2030201300382010f00"
344 "3082010a0282010100b259758bb02bc75b68b17612c9bf68c5fa05958a334c61e167bc20"
345 "bcc75757c126e89210b9df3989072cf6260e6883c7cd4af4d31dde9915b69b301fbef962"
346 "de8c71bd2db5ec625da259712f86a8dc3d241e9688c82391b7bf1ebc358311f55c26be91"
347 "0b76f61fea408ed692f1a9578a622c82c0fcf6f69ef3670e38bfc90f63da4f3bbbd088c8"
348 "ae7a3c5a55e66f6474d562d32cce7b7edd7cf0149ca0e96cb6525e81fbba815a8f12748e"
349 "34e5135f572b2e17b7ba430081597e6fb9033c005884d5935118c60d75b010f6fece7ecd"
350 "cc1cb7d58d1389693d43377f4f3de949cb1e4105e792b96d7f04b0cd262ac33cffc5a890"
351 "d267425e61c19e9363550f22850203010001");
352
353 EXPECT_EQ(result_e_not_padded, expected_der_encoding);
354 EXPECT_EQ(result_e_padded, expected_der_encoding);
355 }
356
357 // The public key used in this test is taken from the test vectors found here:
358 // https://www.ietf.org/archive/id/draft-ietf-privacypass-protocol-10.html#name-issuance-protocol-2-blind-rs
TEST(AnonymousTokensCryptoUtilsTest,IetfPrivacyPassBlindRsaPublicKeyToDer)359 TEST(AnonymousTokensCryptoUtilsTest, IetfPrivacyPassBlindRsaPublicKeyToDer) {
360 std::string rsa_modulus = absl::HexStringToBytes(
361 "cb1aed6b6a95f5b1ce013a4cfcab25b94b2e64a23034e4250a7eab43c0df3a8c12993af1"
362 "2b111908d4b471bec31d4b6c9ad9cdda90612a2ee903523e6de5a224d6b02f09e5c374d0"
363 "cfe01d8f529c500a78a2f67908fa682b5a2b430c81eaf1af72d7b5e794fc98a313927687"
364 "9757ce453b526ef9bf6ceb99979b8423b90f4461a22af37aab0cf5733f7597abe44d31c7"
365 "32db68a181c6cbbe607d8c0e52e0655fd9996dc584eca0be87afbcd78a337d17b1dba9e8"
366 "28bbd81e291317144e7ff89f55619709b096cbb9ea474cead264c2073fe49740c01f00e1"
367 "09106066983d21e5f83f086e2e823c879cd43cef700d2a352a9babd612d03cad02db134b"
368 "7e225a5f");
369 std::string e = absl::HexStringToBytes("010001");
370 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<RSA> rsa,
371 CreatePublicKeyRSA(rsa_modulus, e));
372 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string result,
373 RsaSsaPssPublicKeyToDerEncoding(rsa.get()));
374
375 std::string expected_der_encoding = absl::HexStringToBytes(
376 "30820152303d06092a864886f70d01010a3030a00d300b0609608648016503040202a11a"
377 "301806092a864886f70d010108300b0609608648016503040202a2030201300382010f00"
378 "3082010a0282010100cb1aed6b6a95f5b1ce013a4cfcab25b94b2e64a23034e4250a7eab"
379 "43c0df3a8c12993af12b111908d4b471bec31d4b6c9ad9cdda90612a2ee903523e6de5a2"
380 "24d6b02f09e5c374d0cfe01d8f529c500a78a2f67908fa682b5a2b430c81eaf1af72d7b5"
381 "e794fc98a3139276879757ce453b526ef9bf6ceb99979b8423b90f4461a22af37aab0cf5"
382 "733f7597abe44d31c732db68a181c6cbbe607d8c0e52e0655fd9996dc584eca0be87afbc"
383 "d78a337d17b1dba9e828bbd81e291317144e7ff89f55619709b096cbb9ea474cead264c2"
384 "073fe49740c01f00e109106066983d21e5f83f086e2e823c879cd43cef700d2a352a9bab"
385 "d612d03cad02db134b7e225a5f0203010001");
386
387 EXPECT_EQ(result, expected_der_encoding);
388 }
389
390 using CreateTestKeyPairFunction = std::pair<
391 anonymous_tokens::TestRsaPublicKey, anonymous_tokens::TestRsaPrivateKey>();
392
393 class CryptoUtilsTest
394 : public testing::TestWithParam<CreateTestKeyPairFunction*> {
395 protected:
SetUp()396 void SetUp() override {
397 const auto [_, private_key] = (*GetParam())();
398 private_key_ = private_key;
399
400 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_modulus_,
401 StringToBignum(private_key_.n));
402 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_e_, StringToBignum(private_key_.e));
403 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_p_, StringToBignum(private_key_.p));
404 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_q_, StringToBignum(private_key_.q));
405 }
406
407 TestRsaPrivateKey private_key_;
408
409 bssl::UniquePtr<BIGNUM> rsa_modulus_;
410 bssl::UniquePtr<BIGNUM> rsa_e_;
411 bssl::UniquePtr<BIGNUM> rsa_p_;
412 bssl::UniquePtr<BIGNUM> rsa_q_;
413 };
414
TEST_P(CryptoUtilsTest,PublicExponentCoprime)415 TEST_P(CryptoUtilsTest, PublicExponentCoprime) {
416 std::string metadata = "md";
417 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
418 bssl::UniquePtr<BIGNUM> exp,
419 ComputeExponentWithPublicMetadata(*rsa_modulus_.get(), metadata));
420 int rsa_mod_size_bits = BN_num_bits(rsa_modulus_.get());
421 // Check that exponent is odd.
422 EXPECT_EQ(BN_is_odd(exp.get()), 1);
423 // Check that exponent is small enough.
424 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> sqrt2,
425 GetRsaSqrtTwo(rsa_mod_size_bits / 2));
426 EXPECT_LT(BN_cmp(exp.get(), sqrt2.get()), 0);
427 EXPECT_LT(BN_cmp(exp.get(), rsa_p_.get()), 0);
428 EXPECT_LT(BN_cmp(exp.get(), rsa_q_.get()), 0);
429 }
430
TEST_P(CryptoUtilsTest,PublicExponentHash)431 TEST_P(CryptoUtilsTest, PublicExponentHash) {
432 std::string metadata1 = "md1";
433 std::string metadata2 = "md2";
434 // Check that hash is deterministic.
435 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
436 bssl::UniquePtr<BIGNUM> exp1,
437 ComputeExponentWithPublicMetadata(*rsa_modulus_.get(), metadata1));
438 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
439 bssl::UniquePtr<BIGNUM> another_exp1,
440 ComputeExponentWithPublicMetadata(*rsa_modulus_.get(), metadata1));
441 EXPECT_EQ(BN_cmp(exp1.get(), another_exp1.get()), 0);
442 // Check that hashes are distinct for different metadata.
443 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
444 bssl::UniquePtr<BIGNUM> exp2,
445 ComputeExponentWithPublicMetadata(*rsa_modulus_.get(), metadata2));
446 EXPECT_NE(BN_cmp(exp1.get(), exp2.get()), 0);
447 }
448
TEST_P(CryptoUtilsTest,FinalExponentCoprime)449 TEST_P(CryptoUtilsTest, FinalExponentCoprime) {
450 std::string metadata = "md";
451 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
452 bssl::UniquePtr<BIGNUM> final_exponent,
453 ComputeExponentWithPublicMetadataAndPublicExponent(
454 *rsa_modulus_.get(), *rsa_e_.get(), metadata));
455 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(BnCtxPtr ctx, GetAndStartBigNumCtx());
456
457 // Check that exponent is odd.
458 EXPECT_EQ(BN_is_odd(final_exponent.get()), 1);
459 // Check that exponent is co-prime to factors of the rsa modulus.
460 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> gcd_p_fe,
461 NewBigNum());
462 ASSERT_EQ(
463 BN_gcd(gcd_p_fe.get(), rsa_p_.get(), final_exponent.get(), ctx.get()), 1);
464 EXPECT_EQ(BN_cmp(gcd_p_fe.get(), BN_value_one()), 0);
465 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> gcd_q_fe,
466 NewBigNum());
467 ASSERT_EQ(
468 BN_gcd(gcd_q_fe.get(), rsa_q_.get(), final_exponent.get(), ctx.get()), 1);
469 EXPECT_EQ(BN_cmp(gcd_q_fe.get(), BN_value_one()), 0);
470 }
471
TEST_P(CryptoUtilsTest,DeterministicModificationOfPublicExponentWithMetadata)472 TEST_P(CryptoUtilsTest, DeterministicModificationOfPublicExponentWithMetadata) {
473 std::string metadata = "md";
474 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
475 bssl::UniquePtr<BIGNUM> public_exp_1,
476 ComputeExponentWithPublicMetadataAndPublicExponent(
477 *rsa_modulus_.get(), *rsa_e_.get(), metadata));
478 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
479 bssl::UniquePtr<BIGNUM> public_exp_2,
480 ComputeExponentWithPublicMetadataAndPublicExponent(
481 *rsa_modulus_.get(), *rsa_e_.get(), metadata));
482
483 EXPECT_EQ(BN_cmp(public_exp_1.get(), public_exp_2.get()), 0);
484 }
485
TEST_P(CryptoUtilsTest,DifferentPublicExponentWithDifferentPublicMetadata)486 TEST_P(CryptoUtilsTest, DifferentPublicExponentWithDifferentPublicMetadata) {
487 std::string metadata_1 = "md1";
488 std::string metadata_2 = "md2";
489 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
490 bssl::UniquePtr<BIGNUM> public_exp_1,
491 ComputeExponentWithPublicMetadataAndPublicExponent(
492 *rsa_modulus_.get(), *rsa_e_.get(), metadata_1));
493 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
494 bssl::UniquePtr<BIGNUM> public_exp_2,
495 ComputeExponentWithPublicMetadataAndPublicExponent(
496 *rsa_modulus_.get(), *rsa_e_.get(), metadata_2));
497 // Check that exponent is different in all keys
498 EXPECT_NE(BN_cmp(public_exp_1.get(), public_exp_2.get()), 0);
499 EXPECT_NE(BN_cmp(public_exp_1.get(), rsa_e_.get()), 0);
500 EXPECT_NE(BN_cmp(public_exp_2.get(), rsa_e_.get()), 0);
501 }
502
TEST_P(CryptoUtilsTest,ModifiedPublicExponentWithEmptyPublicMetadata)503 TEST_P(CryptoUtilsTest, ModifiedPublicExponentWithEmptyPublicMetadata) {
504 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
505 bssl::UniquePtr<BIGNUM> new_public_exp,
506 ComputeExponentWithPublicMetadataAndPublicExponent(*rsa_modulus_.get(),
507 *rsa_e_.get(), ""));
508
509 EXPECT_NE(BN_cmp(new_public_exp.get(), rsa_e_.get()), 0);
510 }
511
TEST_P(CryptoUtilsTest,CreateRsaPublicKeyWithPublicMetadataSuccessfully)512 TEST_P(CryptoUtilsTest, CreateRsaPublicKeyWithPublicMetadataSuccessfully) {
513 std::string metadata = "md";
514 // Key derived using the public exponent, modulus and public metadata.
515 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<RSA> rsa_public_key,
516 CreatePublicKeyRSAWithPublicMetadata(
517 private_key_.n, private_key_.e, metadata,
518 /*use_rsa_public_exponent=*/true));
519 // Key derived using only the modulus and public metadata.
520 ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<RSA> rsa_public_key_2,
521 CreatePublicKeyRSAWithPublicMetadata(
522 private_key_.n, private_key_.e, metadata,
523 /*use_rsa_public_exponent=*/false));
524
525 EXPECT_EQ(BN_cmp(RSA_get0_n(rsa_public_key.get()), rsa_modulus_.get()), 0);
526 EXPECT_EQ(BN_cmp(RSA_get0_n(rsa_public_key_2.get()), rsa_modulus_.get()), 0);
527
528 EXPECT_NE(BN_cmp(RSA_get0_e(rsa_public_key.get()), rsa_e_.get()), 0);
529 EXPECT_NE(BN_cmp(RSA_get0_e(rsa_public_key_2.get()), rsa_e_.get()), 0);
530 EXPECT_NE(BN_cmp(RSA_get0_e(rsa_public_key.get()),
531 RSA_get0_e(rsa_public_key_2.get())),
532 0);
533 }
534
535 INSTANTIATE_TEST_SUITE_P(CryptoUtilsTest, CryptoUtilsTest,
536 testing::Values(&GetStrongTestRsaKeyPair2048,
537 &GetAnotherStrongTestRsaKeyPair2048,
538 &GetStrongTestRsaKeyPair3072,
539 &GetStrongTestRsaKeyPair4096));
540
541 } // namespace
542 } // namespace anonymous_tokens
543
544