1 // Copyright 2023 The BoringSSL Authors
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 <vector>
16 
17 #include <string.h>
18 
19 #include <gtest/gtest.h>
20 
21 #include <openssl/bytestring.h>
22 #include <openssl/ctrdrbg.h>
23 
24 #include "../fipsmodule/keccak/internal.h"
25 #include "../test/file_test.h"
26 #include "../test/test_util.h"
27 #include "./internal.h"
28 
29 
30 template <typename T>
Marshal(int (* marshal_func)(CBB *,const T *),const T * t)31 static std::vector<uint8_t> Marshal(int (*marshal_func)(CBB *, const T *),
32                                     const T *t) {
33   bssl::ScopedCBB cbb;
34   uint8_t *encoded;
35   size_t encoded_len;
36   if (!CBB_init(cbb.get(), 1) ||      //
37       !marshal_func(cbb.get(), t) ||  //
38       !CBB_finish(cbb.get(), &encoded, &encoded_len)) {
39     abort();
40   }
41 
42   std::vector<uint8_t> ret(encoded, encoded + encoded_len);
43   OPENSSL_free(encoded);
44   return ret;
45 }
46 
TEST(KyberTest,Basic)47 TEST(KyberTest, Basic) {
48   // This function makes several Kyber keys, which runs up against stack limits.
49   // Heap-allocate them instead.
50 
51   uint8_t encoded_public_key[KYBER_PUBLIC_KEY_BYTES];
52   auto priv = std::make_unique<KYBER_private_key>();
53   KYBER_generate_key(encoded_public_key, priv.get());
54 
55   uint8_t first_two_bytes[2];
56   OPENSSL_memcpy(first_two_bytes, encoded_public_key, sizeof(first_two_bytes));
57   OPENSSL_memset(encoded_public_key, 0xff, sizeof(first_two_bytes));
58   CBS encoded_public_key_cbs;
59   CBS_init(&encoded_public_key_cbs, encoded_public_key,
60            sizeof(encoded_public_key));
61   auto pub = std::make_unique<KYBER_public_key>();
62   // Parsing should fail because the first coefficient is >= kPrime;
63   ASSERT_FALSE(KYBER_parse_public_key(pub.get(), &encoded_public_key_cbs));
64 
65   OPENSSL_memcpy(encoded_public_key, first_two_bytes, sizeof(first_two_bytes));
66   CBS_init(&encoded_public_key_cbs, encoded_public_key,
67            sizeof(encoded_public_key));
68   ASSERT_TRUE(KYBER_parse_public_key(pub.get(), &encoded_public_key_cbs));
69   EXPECT_EQ(CBS_len(&encoded_public_key_cbs), 0u);
70 
71   EXPECT_EQ(Bytes(encoded_public_key),
72             Bytes(Marshal(KYBER_marshal_public_key, pub.get())));
73 
74   auto pub2 = std::make_unique<KYBER_public_key>();
75   KYBER_public_from_private(pub2.get(), priv.get());
76   EXPECT_EQ(Bytes(encoded_public_key),
77             Bytes(Marshal(KYBER_marshal_public_key, pub2.get())));
78 
79   std::vector<uint8_t> encoded_private_key(
80       Marshal(KYBER_marshal_private_key, priv.get()));
81   EXPECT_EQ(encoded_private_key.size(), size_t{KYBER_PRIVATE_KEY_BYTES});
82 
83   OPENSSL_memcpy(first_two_bytes, encoded_private_key.data(),
84                  sizeof(first_two_bytes));
85   OPENSSL_memset(encoded_private_key.data(), 0xff, sizeof(first_two_bytes));
86   CBS cbs;
87   CBS_init(&cbs, encoded_private_key.data(), encoded_private_key.size());
88   auto priv2 = std::make_unique<KYBER_private_key>();
89   // Parsing should fail because the first coefficient is >= kPrime.
90   ASSERT_FALSE(KYBER_parse_private_key(priv2.get(), &cbs));
91 
92   OPENSSL_memcpy(encoded_private_key.data(), first_two_bytes,
93                  sizeof(first_two_bytes));
94   CBS_init(&cbs, encoded_private_key.data(), encoded_private_key.size());
95   ASSERT_TRUE(KYBER_parse_private_key(priv2.get(), &cbs));
96   EXPECT_EQ(
97       Bytes(Declassified(encoded_private_key)),
98       Bytes(Declassified((Marshal(KYBER_marshal_private_key, priv2.get())))));
99 
100   uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES];
101   uint8_t shared_secret1[KYBER_SHARED_SECRET_BYTES];
102   uint8_t shared_secret2[KYBER_SHARED_SECRET_BYTES];
103   KYBER_encap(ciphertext, shared_secret1, pub.get());
104   KYBER_decap(shared_secret2, ciphertext, priv.get());
105   EXPECT_EQ(Bytes(Declassified(shared_secret1)),
106             Bytes(Declassified(shared_secret2)));
107   KYBER_decap(shared_secret2, ciphertext, priv2.get());
108   EXPECT_EQ(Bytes(Declassified(shared_secret1)),
109             Bytes(Declassified(shared_secret2)));
110 }
111 
KyberFileTest(FileTest * t)112 static void KyberFileTest(FileTest *t) {
113   std::vector<uint8_t> public_key_expected, private_key_expected,
114       ciphertext_expected, shared_secret_expected, generate_entropy,
115       encap_entropy_pre_hash;
116   t->IgnoreAttribute("count");
117   ASSERT_TRUE(t->GetBytes(&public_key_expected, "pk"));
118   ASSERT_TRUE(t->GetBytes(&private_key_expected, "sk"));
119   ASSERT_TRUE(t->GetBytes(&ciphertext_expected, "ct"));
120   ASSERT_TRUE(t->GetBytes(&shared_secret_expected, "ss"));
121   ASSERT_TRUE(t->GetBytes(&generate_entropy, "generateEntropy"));
122   ASSERT_TRUE(t->GetBytes(&encap_entropy_pre_hash, "encapEntropyPreHash"));
123 
124   KYBER_private_key priv;
125   uint8_t encoded_private_key[KYBER_PRIVATE_KEY_BYTES];
126   KYBER_public_key pub;
127   uint8_t encoded_public_key[KYBER_PUBLIC_KEY_BYTES];
128   uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES];
129   uint8_t encap_entropy[KYBER_ENCAP_ENTROPY];
130   uint8_t encapsulated_key[KYBER_SHARED_SECRET_BYTES];
131   uint8_t decapsulated_key[KYBER_SHARED_SECRET_BYTES];
132 
133   BORINGSSL_keccak(encap_entropy, sizeof(encap_entropy),
134                    encap_entropy_pre_hash.data(), encap_entropy_pre_hash.size(),
135                    boringssl_sha3_256);
136 
137   KYBER_generate_key_external_entropy(encoded_public_key, &priv,
138                                       generate_entropy.data());
139   CBB cbb;
140   CBB_init_fixed(&cbb, encoded_private_key, sizeof(encoded_private_key));
141   ASSERT_TRUE(KYBER_marshal_private_key(&cbb, &priv));
142   CBS encoded_public_key_cbs;
143   CBS_init(&encoded_public_key_cbs, encoded_public_key,
144            sizeof(encoded_public_key));
145   ASSERT_TRUE(KYBER_parse_public_key(&pub, &encoded_public_key_cbs));
146   KYBER_encap_external_entropy(ciphertext, encapsulated_key, &pub,
147                                encap_entropy);
148   KYBER_decap(decapsulated_key, ciphertext, &priv);
149 
150   EXPECT_EQ(Bytes(Declassified(encapsulated_key)),
151             Bytes(Declassified(decapsulated_key)));
152   EXPECT_EQ(Bytes(private_key_expected),
153             Bytes(Declassified(encoded_private_key)));
154   EXPECT_EQ(Bytes(public_key_expected), Bytes(encoded_public_key));
155   EXPECT_EQ(Bytes(ciphertext_expected), Bytes(ciphertext));
156   EXPECT_EQ(Bytes(shared_secret_expected),
157             Bytes(Declassified(encapsulated_key)));
158 
159   uint8_t corrupted_ciphertext[KYBER_CIPHERTEXT_BYTES];
160   OPENSSL_memcpy(corrupted_ciphertext, ciphertext, KYBER_CIPHERTEXT_BYTES);
161   corrupted_ciphertext[3] ^= 0x40;
162   uint8_t corrupted_decapsulated_key[KYBER_SHARED_SECRET_BYTES];
163   KYBER_decap(corrupted_decapsulated_key, corrupted_ciphertext, &priv);
164   // It would be nice to have actual test vectors for the failure case, but the
165   // NIST submission currently does not include those, so we are just testing
166   // for inequality.
167   EXPECT_NE(Bytes(Declassified(encapsulated_key)),
168             Bytes(Declassified(corrupted_decapsulated_key)));
169 }
170 
TEST(KyberTest,TestVectors)171 TEST(KyberTest, TestVectors) {
172   FileTestGTest("crypto/kyber/kyber_tests.txt", KyberFileTest);
173 }
174