xref: /aosp_15_r20/external/boringssl/src/crypto/fipsmodule/ec/ec_test.cc (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1 /* Copyright (c) 2014, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 
19 #include <vector>
20 
21 #include <gtest/gtest.h>
22 
23 #include <openssl/bn.h>
24 #include <openssl/bytestring.h>
25 #include <openssl/crypto.h>
26 #include <openssl/ec_key.h>
27 #include <openssl/err.h>
28 #include <openssl/mem.h>
29 #include <openssl/nid.h>
30 #include <openssl/obj.h>
31 #include <openssl/span.h>
32 
33 #include "../../ec_extra/internal.h"
34 #include "../../test/file_test.h"
35 #include "../../test/test_util.h"
36 #include "../bn/internal.h"
37 #include "internal.h"
38 
39 
40 // kECKeyWithoutPublic is an ECPrivateKey with the optional publicKey field
41 // omitted.
42 static const uint8_t kECKeyWithoutPublic[] = {
43   0x30, 0x31, 0x02, 0x01, 0x01, 0x04, 0x20, 0xc6, 0xc1, 0xaa, 0xda, 0x15, 0xb0,
44   0x76, 0x61, 0xf8, 0x14, 0x2c, 0x6c, 0xaf, 0x0f, 0xdb, 0x24, 0x1a, 0xff, 0x2e,
45   0xfe, 0x46, 0xc0, 0x93, 0x8b, 0x74, 0xf2, 0xbc, 0xc5, 0x30, 0x52, 0xb0, 0x77,
46   0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07,
47 };
48 
49 // kECKeySpecifiedCurve is the above key with P-256's parameters explicitly
50 // spelled out rather than using a named curve.
51 static const uint8_t kECKeySpecifiedCurve[] = {
52     0x30, 0x82, 0x01, 0x22, 0x02, 0x01, 0x01, 0x04, 0x20, 0xc6, 0xc1, 0xaa,
53     0xda, 0x15, 0xb0, 0x76, 0x61, 0xf8, 0x14, 0x2c, 0x6c, 0xaf, 0x0f, 0xdb,
54     0x24, 0x1a, 0xff, 0x2e, 0xfe, 0x46, 0xc0, 0x93, 0x8b, 0x74, 0xf2, 0xbc,
55     0xc5, 0x30, 0x52, 0xb0, 0x77, 0xa0, 0x81, 0xfa, 0x30, 0x81, 0xf7, 0x02,
56     0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
57     0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
58     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
60     0x30, 0x5b, 0x04, 0x20, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
61     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
63     0x04, 0x20, 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb,
64     0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
65     0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b, 0x03, 0x15,
66     0x00, 0xc4, 0x9d, 0x36, 0x08, 0x86, 0xe7, 0x04, 0x93, 0x6a, 0x66, 0x78,
67     0xe1, 0x13, 0x9d, 0x26, 0xb7, 0x81, 0x9f, 0x7e, 0x90, 0x04, 0x41, 0x04,
68     0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5,
69     0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
70     0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42, 0xe2,
71     0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
72     0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68,
73     0x37, 0xbf, 0x51, 0xf5, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
74     0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc,
75     0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc,
76     0x63, 0x25, 0x51, 0x02, 0x01, 0x01,
77 };
78 
79 // kECKeyMissingZeros is an ECPrivateKey containing a degenerate P-256 key where
80 // the private key is one. The private key is incorrectly encoded without zero
81 // padding.
82 static const uint8_t kECKeyMissingZeros[] = {
83   0x30, 0x58, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0xa0, 0x0a, 0x06, 0x08, 0x2a,
84   0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04,
85   0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5, 0x63,
86   0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1,
87   0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f,
88   0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57,
89   0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
90 };
91 
92 // kECKeyMissingZeros is an ECPrivateKey containing a degenerate P-256 key where
93 // the private key is one. The private key is encoded with the required zero
94 // padding.
95 static const uint8_t kECKeyWithZeros[] = {
96   0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
99   0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0xa1,
100   0x44, 0x03, 0x42, 0x00, 0x04, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47,
101   0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d,
102   0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3,
103   0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e,
104   0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68,
105   0x37, 0xbf, 0x51, 0xf5,
106 };
107 
108 static const uint8_t kECKeyWithZerosPublic[] = {
109     0x04, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc,
110     0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d,
111     0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96,
112     0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb,
113     0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31,
114     0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
115 };
116 
117 static const uint8_t kECKeyWithZerosRawPrivate[] = {
118     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
121 
122 // DecodeECPrivateKey decodes |in| as an ECPrivateKey structure and returns the
123 // result or nullptr on error.
DecodeECPrivateKey(const uint8_t * in,size_t in_len)124 static bssl::UniquePtr<EC_KEY> DecodeECPrivateKey(const uint8_t *in,
125                                                   size_t in_len) {
126   CBS cbs;
127   CBS_init(&cbs, in, in_len);
128   bssl::UniquePtr<EC_KEY> ret(EC_KEY_parse_private_key(&cbs, NULL));
129   if (!ret || CBS_len(&cbs) != 0) {
130     return nullptr;
131   }
132   return ret;
133 }
134 
135 // EncodeECPrivateKey encodes |key| as an ECPrivateKey structure into |*out|. It
136 // returns true on success or false on error.
EncodeECPrivateKey(std::vector<uint8_t> * out,const EC_KEY * key)137 static bool EncodeECPrivateKey(std::vector<uint8_t> *out, const EC_KEY *key) {
138   bssl::ScopedCBB cbb;
139   uint8_t *der;
140   size_t der_len;
141   if (!CBB_init(cbb.get(), 0) ||
142       !EC_KEY_marshal_private_key(cbb.get(), key, EC_KEY_get_enc_flags(key)) ||
143       !CBB_finish(cbb.get(), &der, &der_len)) {
144     return false;
145   }
146   out->assign(der, der + der_len);
147   OPENSSL_free(der);
148   return true;
149 }
150 
EncodeECPoint(std::vector<uint8_t> * out,const EC_GROUP * group,const EC_POINT * p,point_conversion_form_t form)151 static bool EncodeECPoint(std::vector<uint8_t> *out, const EC_GROUP *group,
152                           const EC_POINT *p, point_conversion_form_t form) {
153   size_t len = EC_POINT_point2oct(group, p, form, nullptr, 0, nullptr);
154   if (len == 0) {
155     return false;
156   }
157 
158   out->resize(len);
159   len = EC_POINT_point2oct(group, p, form, out->data(), out->size(), nullptr);
160   if (len != out->size()) {
161     return false;
162   }
163 
164   return true;
165 }
166 
TEST(ECTest,Encoding)167 TEST(ECTest, Encoding) {
168   bssl::UniquePtr<EC_KEY> key =
169       DecodeECPrivateKey(kECKeyWithoutPublic, sizeof(kECKeyWithoutPublic));
170   ASSERT_TRUE(key);
171 
172   // Test that the encoding round-trips.
173   std::vector<uint8_t> out;
174   ASSERT_TRUE(EncodeECPrivateKey(&out, key.get()));
175   EXPECT_EQ(Bytes(kECKeyWithoutPublic), Bytes(out.data(), out.size()));
176 
177   const EC_POINT *pub_key = EC_KEY_get0_public_key(key.get());
178   ASSERT_TRUE(pub_key) << "Public key missing";
179 
180   bssl::UniquePtr<BIGNUM> x(BN_new());
181   bssl::UniquePtr<BIGNUM> y(BN_new());
182   ASSERT_TRUE(x);
183   ASSERT_TRUE(y);
184   ASSERT_TRUE(EC_POINT_get_affine_coordinates_GFp(
185       EC_KEY_get0_group(key.get()), pub_key, x.get(), y.get(), NULL));
186   bssl::UniquePtr<char> x_hex(BN_bn2hex(x.get()));
187   bssl::UniquePtr<char> y_hex(BN_bn2hex(y.get()));
188   ASSERT_TRUE(x_hex);
189   ASSERT_TRUE(y_hex);
190 
191   EXPECT_STREQ(
192       "c81561ecf2e54edefe6617db1c7a34a70744ddb261f269b83dacfcd2ade5a681",
193       x_hex.get());
194   EXPECT_STREQ(
195       "e0e2afa3f9b6abe4c698ef6495f1be49a3196c5056acb3763fe4507eec596e88",
196       y_hex.get());
197 }
198 
TEST(ECTest,ZeroPadding)199 TEST(ECTest, ZeroPadding) {
200   // Check that the correct encoding round-trips.
201   bssl::UniquePtr<EC_KEY> key =
202       DecodeECPrivateKey(kECKeyWithZeros, sizeof(kECKeyWithZeros));
203   ASSERT_TRUE(key);
204   std::vector<uint8_t> out;
205   EXPECT_TRUE(EncodeECPrivateKey(&out, key.get()));
206   EXPECT_EQ(Bytes(kECKeyWithZeros), Bytes(out.data(), out.size()));
207 
208   // Check the private key encodes correctly, including with the leading zeros.
209   EXPECT_EQ(32u, EC_KEY_priv2oct(key.get(), nullptr, 0));
210   uint8_t buf[32];
211   ASSERT_EQ(32u, EC_KEY_priv2oct(key.get(), buf, sizeof(buf)));
212   EXPECT_EQ(Bytes(buf), Bytes(kECKeyWithZerosRawPrivate));
213 
214   // Buffer too small.
215   EXPECT_EQ(0u, EC_KEY_priv2oct(key.get(), buf, sizeof(buf) - 1));
216 
217   // Extra space in buffer.
218   uint8_t large_buf[33];
219   ASSERT_EQ(32u, EC_KEY_priv2oct(key.get(), large_buf, sizeof(large_buf)));
220   EXPECT_EQ(Bytes(buf), Bytes(kECKeyWithZerosRawPrivate));
221 
222   // Allocating API.
223   uint8_t *buf_alloc;
224   size_t len = EC_KEY_priv2buf(key.get(), &buf_alloc);
225   ASSERT_GT(len, 0u);
226   bssl::UniquePtr<uint8_t> free_buf_alloc(buf_alloc);
227   EXPECT_EQ(Bytes(buf_alloc, len), Bytes(kECKeyWithZerosRawPrivate));
228 
229   // Keys without leading zeros also parse, but they encode correctly.
230   key = DecodeECPrivateKey(kECKeyMissingZeros, sizeof(kECKeyMissingZeros));
231   ASSERT_TRUE(key);
232   EXPECT_TRUE(EncodeECPrivateKey(&out, key.get()));
233   EXPECT_EQ(Bytes(kECKeyWithZeros), Bytes(out.data(), out.size()));
234 
235   // Test the key can be constructed with |EC_KEY_oct2*|.
236   key.reset(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
237   ASSERT_TRUE(key);
238   ASSERT_TRUE(EC_KEY_oct2key(key.get(), kECKeyWithZerosPublic,
239                              sizeof(kECKeyWithZerosPublic), nullptr));
240   ASSERT_TRUE(EC_KEY_oct2priv(key.get(), kECKeyWithZerosRawPrivate,
241                               sizeof(kECKeyWithZerosRawPrivate)));
242   EXPECT_TRUE(EncodeECPrivateKey(&out, key.get()));
243   EXPECT_EQ(Bytes(kECKeyWithZeros), Bytes(out.data(), out.size()));
244 
245   // |EC_KEY_oct2priv|'s format is fixed-width and must match the group order.
246   key.reset(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
247   ASSERT_TRUE(key);
248   EXPECT_FALSE(EC_KEY_oct2priv(key.get(), kECKeyWithZerosRawPrivate + 1,
249                                sizeof(kECKeyWithZerosRawPrivate) - 1));
250   uint8_t padded[sizeof(kECKeyWithZerosRawPrivate) + 1] = {0};
251   memcpy(padded + 1, kECKeyWithZerosRawPrivate,
252          sizeof(kECKeyWithZerosRawPrivate));
253   EXPECT_FALSE(EC_KEY_oct2priv(key.get(), padded, sizeof(padded)));
254 }
255 
TEST(ECTest,SpecifiedCurve)256 TEST(ECTest, SpecifiedCurve) {
257   // Test keys with specified curves may be decoded.
258   bssl::UniquePtr<EC_KEY> key =
259       DecodeECPrivateKey(kECKeySpecifiedCurve, sizeof(kECKeySpecifiedCurve));
260   ASSERT_TRUE(key);
261 
262   // The group should have been interpreted as P-256.
263   EXPECT_EQ(NID_X9_62_prime256v1,
264             EC_GROUP_get_curve_name(EC_KEY_get0_group(key.get())));
265 
266   // Encoding the key should still use named form.
267   std::vector<uint8_t> out;
268   EXPECT_TRUE(EncodeECPrivateKey(&out, key.get()));
269   EXPECT_EQ(Bytes(kECKeyWithoutPublic), Bytes(out.data(), out.size()));
270 }
271 
TEST(ECTest,ArbitraryCurve)272 TEST(ECTest, ArbitraryCurve) {
273   // Make a P-256 key and extract the affine coordinates.
274   bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
275   ASSERT_TRUE(key);
276   ASSERT_TRUE(EC_KEY_generate_key(key.get()));
277 
278   // Make an arbitrary curve which is identical to P-256.
279   static const uint8_t kP[] = {
280       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
281       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
282       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
283   };
284   static const uint8_t kA[] = {
285       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
286       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
287       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
288   };
289   static const uint8_t kB[] = {
290       0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb, 0xbd,
291       0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
292       0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b,
293   };
294   static const uint8_t kX[] = {
295       0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6,
296       0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb,
297       0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96,
298   };
299   static const uint8_t kY[] = {
300       0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb,
301       0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31,
302       0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
303   };
304   static const uint8_t kOrder[] = {
305       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
306       0xff, 0xff, 0xff, 0xff, 0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17,
307       0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51,
308   };
309   bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
310   ASSERT_TRUE(ctx);
311   bssl::UniquePtr<BIGNUM> p(BN_bin2bn(kP, sizeof(kP), nullptr));
312   ASSERT_TRUE(p);
313   bssl::UniquePtr<BIGNUM> a(BN_bin2bn(kA, sizeof(kA), nullptr));
314   ASSERT_TRUE(a);
315   bssl::UniquePtr<BIGNUM> b(BN_bin2bn(kB, sizeof(kB), nullptr));
316   ASSERT_TRUE(b);
317   bssl::UniquePtr<BIGNUM> gx(BN_bin2bn(kX, sizeof(kX), nullptr));
318   ASSERT_TRUE(gx);
319   bssl::UniquePtr<BIGNUM> gy(BN_bin2bn(kY, sizeof(kY), nullptr));
320   ASSERT_TRUE(gy);
321   bssl::UniquePtr<BIGNUM> order(BN_bin2bn(kOrder, sizeof(kOrder), nullptr));
322   ASSERT_TRUE(order);
323 
324   bssl::UniquePtr<EC_GROUP> group(
325       EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), ctx.get()));
326   ASSERT_TRUE(group);
327   bssl::UniquePtr<EC_POINT> generator(EC_POINT_new(group.get()));
328   ASSERT_TRUE(generator);
329   ASSERT_TRUE(EC_POINT_set_affine_coordinates_GFp(
330       group.get(), generator.get(), gx.get(), gy.get(), ctx.get()));
331   ASSERT_TRUE(EC_GROUP_set_generator(group.get(), generator.get(), order.get(),
332                                      BN_value_one()));
333 
334   // |group| should not have a curve name.
335   EXPECT_EQ(NID_undef, EC_GROUP_get_curve_name(group.get()));
336 
337   // Copy |key| to |key2| using |group|.
338   bssl::UniquePtr<EC_KEY> key2(EC_KEY_new());
339   ASSERT_TRUE(key2);
340   bssl::UniquePtr<EC_POINT> point(EC_POINT_new(group.get()));
341   ASSERT_TRUE(point);
342   bssl::UniquePtr<BIGNUM> x(BN_new()), y(BN_new());
343   ASSERT_TRUE(x);
344   ASSERT_TRUE(EC_KEY_set_group(key2.get(), group.get()));
345   ASSERT_TRUE(
346       EC_KEY_set_private_key(key2.get(), EC_KEY_get0_private_key(key.get())));
347   ASSERT_TRUE(EC_POINT_get_affine_coordinates_GFp(
348       EC_KEY_get0_group(key.get()), EC_KEY_get0_public_key(key.get()), x.get(),
349       y.get(), nullptr));
350   ASSERT_TRUE(EC_POINT_set_affine_coordinates_GFp(group.get(), point.get(),
351                                                   x.get(), y.get(), nullptr));
352   ASSERT_TRUE(EC_KEY_set_public_key(key2.get(), point.get()));
353 
354   // The key must be valid according to the new group too.
355   EXPECT_TRUE(EC_KEY_check_key(key2.get()));
356 
357   // Make a second instance of |group|.
358   bssl::UniquePtr<EC_GROUP> group2(
359       EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), ctx.get()));
360   ASSERT_TRUE(group2);
361   bssl::UniquePtr<EC_POINT> generator2(EC_POINT_new(group2.get()));
362   ASSERT_TRUE(generator2);
363   ASSERT_TRUE(EC_POINT_set_affine_coordinates_GFp(
364       group2.get(), generator2.get(), gx.get(), gy.get(), ctx.get()));
365   ASSERT_TRUE(EC_GROUP_set_generator(group2.get(), generator2.get(),
366                                      order.get(), BN_value_one()));
367 
368   EXPECT_EQ(0, EC_GROUP_cmp(group.get(), group.get(), NULL));
369   EXPECT_EQ(0, EC_GROUP_cmp(group2.get(), group.get(), NULL));
370 
371   // group3 uses the wrong generator.
372   bssl::UniquePtr<EC_GROUP> group3(
373       EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), ctx.get()));
374   ASSERT_TRUE(group3);
375   bssl::UniquePtr<EC_POINT> generator3(EC_POINT_new(group3.get()));
376   ASSERT_TRUE(generator3);
377   ASSERT_TRUE(EC_POINT_set_affine_coordinates_GFp(
378       group3.get(), generator3.get(), x.get(), y.get(), ctx.get()));
379   ASSERT_TRUE(EC_GROUP_set_generator(group3.get(), generator3.get(),
380                                      order.get(), BN_value_one()));
381 
382   EXPECT_NE(0, EC_GROUP_cmp(group.get(), group3.get(), NULL));
383 
384 #if !defined(BORINGSSL_SHARED_LIBRARY)
385   // group4 has non-minimal components that do not fit in |EC_SCALAR| and the
386   // future |EC_FELEM|.
387   ASSERT_TRUE(bn_resize_words(p.get(), 32));
388   ASSERT_TRUE(bn_resize_words(a.get(), 32));
389   ASSERT_TRUE(bn_resize_words(b.get(), 32));
390   ASSERT_TRUE(bn_resize_words(gx.get(), 32));
391   ASSERT_TRUE(bn_resize_words(gy.get(), 32));
392   ASSERT_TRUE(bn_resize_words(order.get(), 32));
393 
394   bssl::UniquePtr<EC_GROUP> group4(
395       EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), ctx.get()));
396   ASSERT_TRUE(group4);
397   bssl::UniquePtr<EC_POINT> generator4(EC_POINT_new(group4.get()));
398   ASSERT_TRUE(generator4);
399   ASSERT_TRUE(EC_POINT_set_affine_coordinates_GFp(
400       group4.get(), generator4.get(), gx.get(), gy.get(), ctx.get()));
401   ASSERT_TRUE(EC_GROUP_set_generator(group4.get(), generator4.get(),
402                                      order.get(), BN_value_one()));
403 
404   EXPECT_EQ(0, EC_GROUP_cmp(group.get(), group4.get(), NULL));
405 #endif
406 
407   // group5 is the same group, but the curve coefficients are passed in
408   // unreduced and the caller does not pass in a |BN_CTX|.
409   ASSERT_TRUE(BN_sub(a.get(), a.get(), p.get()));
410   ASSERT_TRUE(BN_add(b.get(), b.get(), p.get()));
411   bssl::UniquePtr<EC_GROUP> group5(
412       EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), NULL));
413   ASSERT_TRUE(group5);
414   bssl::UniquePtr<EC_POINT> generator5(EC_POINT_new(group5.get()));
415   ASSERT_TRUE(generator5);
416   ASSERT_TRUE(EC_POINT_set_affine_coordinates_GFp(
417       group5.get(), generator5.get(), gx.get(), gy.get(), ctx.get()));
418   ASSERT_TRUE(EC_GROUP_set_generator(group5.get(), generator5.get(),
419                                      order.get(), BN_value_one()));
420 
421   EXPECT_EQ(0, EC_GROUP_cmp(group.get(), group.get(), NULL));
422   EXPECT_EQ(0, EC_GROUP_cmp(group5.get(), group.get(), NULL));
423 }
424 
TEST(ECTest,SetKeyWithoutGroup)425 TEST(ECTest, SetKeyWithoutGroup) {
426   bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
427   ASSERT_TRUE(key);
428 
429   // Private keys may not be configured without a group.
430   EXPECT_FALSE(EC_KEY_set_private_key(key.get(), BN_value_one()));
431 
432   // Public keys may not be configured without a group.
433   EXPECT_FALSE(EC_KEY_set_public_key(key.get(),
434                                      EC_GROUP_get0_generator(EC_group_p256())));
435 }
436 
TEST(ECTest,SetNULLKey)437 TEST(ECTest, SetNULLKey) {
438   bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
439   ASSERT_TRUE(key);
440 
441   EXPECT_TRUE(EC_KEY_set_public_key(
442       key.get(), EC_GROUP_get0_generator(EC_KEY_get0_group(key.get()))));
443   EXPECT_TRUE(EC_KEY_get0_public_key(key.get()));
444 
445   // Setting a NULL public-key should clear the public-key and return zero, in
446   // order to match OpenSSL behaviour exactly.
447   EXPECT_FALSE(EC_KEY_set_public_key(key.get(), nullptr));
448   EXPECT_FALSE(EC_KEY_get0_public_key(key.get()));
449 }
450 
TEST(ECTest,GroupMismatch)451 TEST(ECTest, GroupMismatch) {
452   bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(NID_secp384r1));
453   ASSERT_TRUE(key);
454 
455   // Changing a key's group is invalid.
456   EXPECT_FALSE(EC_KEY_set_group(key.get(), EC_group_p256()));
457 
458   // Configuring a public key with the wrong group is invalid.
459   EXPECT_FALSE(EC_KEY_set_public_key(key.get(),
460                                      EC_GROUP_get0_generator(EC_group_p256())));
461 }
462 
TEST(ECTest,EmptyKey)463 TEST(ECTest, EmptyKey) {
464   bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
465   ASSERT_TRUE(key);
466   EXPECT_FALSE(EC_KEY_get0_group(key.get()));
467   EXPECT_FALSE(EC_KEY_get0_public_key(key.get()));
468   EXPECT_FALSE(EC_KEY_get0_private_key(key.get()));
469 }
470 
HexToBIGNUM(const char * hex)471 static bssl::UniquePtr<BIGNUM> HexToBIGNUM(const char *hex) {
472   BIGNUM *bn = nullptr;
473   BN_hex2bn(&bn, hex);
474   return bssl::UniquePtr<BIGNUM>(bn);
475 }
476 
477 // Test that point arithmetic works with custom curves using an arbitrary |a|,
478 // rather than -3, as is common (and more efficient).
TEST(ECTest,BrainpoolP256r1)479 TEST(ECTest, BrainpoolP256r1) {
480   static const char kP[] =
481       "a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377";
482   static const char kA[] =
483       "7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9";
484   static const char kB[] =
485       "26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6";
486   static const char kX[] =
487       "8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262";
488   static const char kY[] =
489       "547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997";
490   static const char kN[] =
491       "a9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7";
492   static const char kD[] =
493       "0da21d76fed40dd82ac3314cce91abb585b5c4246e902b238a839609ea1e7ce1";
494   static const char kQX[] =
495       "3a55e0341cab50452fe27b8a87e4775dec7a9daca94b0d84ad1e9f85b53ea513";
496   static const char kQY[] =
497       "40088146b33bbbe81b092b41146774b35dd478cf056437cfb35ef0df2d269339";
498 
499   bssl::UniquePtr<BIGNUM> p = HexToBIGNUM(kP), a = HexToBIGNUM(kA),
500                           b = HexToBIGNUM(kB), x = HexToBIGNUM(kX),
501                           y = HexToBIGNUM(kY), n = HexToBIGNUM(kN),
502                           d = HexToBIGNUM(kD), qx = HexToBIGNUM(kQX),
503                           qy = HexToBIGNUM(kQY);
504   ASSERT_TRUE(p && a && b && x && y && n && d && qx && qy);
505 
506   bssl::UniquePtr<EC_GROUP> group(
507       EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), nullptr));
508   ASSERT_TRUE(group);
509   bssl::UniquePtr<EC_POINT> g(EC_POINT_new(group.get()));
510   ASSERT_TRUE(g);
511   ASSERT_TRUE(EC_POINT_set_affine_coordinates_GFp(group.get(), g.get(), x.get(),
512                                                   y.get(), nullptr));
513   ASSERT_TRUE(
514       EC_GROUP_set_generator(group.get(), g.get(), n.get(), BN_value_one()));
515 
516   bssl::UniquePtr<EC_POINT> q(EC_POINT_new(group.get()));
517   ASSERT_TRUE(q);
518   ASSERT_TRUE(
519       EC_POINT_mul(group.get(), q.get(), d.get(), nullptr, nullptr, nullptr));
520   ASSERT_TRUE(EC_POINT_get_affine_coordinates_GFp(group.get(), q.get(), x.get(),
521                                                   y.get(), nullptr));
522   EXPECT_EQ(0, BN_cmp(x.get(), qx.get()));
523   EXPECT_EQ(0, BN_cmp(y.get(), qy.get()));
524 }
525 
526 class ECCurveTest : public testing::TestWithParam<int> {
527  public:
group() const528   const EC_GROUP *group() const { return group_; }
529 
SetUp()530   void SetUp() override {
531     group_ = EC_GROUP_new_by_curve_name(GetParam());
532     ASSERT_TRUE(group_);
533   }
534 
535  private:
536   const EC_GROUP *group_;
537 };
538 
TEST_P(ECCurveTest,SetAffine)539 TEST_P(ECCurveTest, SetAffine) {
540   // Generate an EC_KEY.
541   bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(GetParam()));
542   ASSERT_TRUE(key);
543   ASSERT_TRUE(EC_KEY_generate_key(key.get()));
544 
545   // Get the public key's coordinates.
546   bssl::UniquePtr<BIGNUM> x(BN_new());
547   ASSERT_TRUE(x);
548   bssl::UniquePtr<BIGNUM> y(BN_new());
549   ASSERT_TRUE(y);
550   bssl::UniquePtr<BIGNUM> p(BN_new());
551   ASSERT_TRUE(p);
552   EXPECT_TRUE(EC_POINT_get_affine_coordinates_GFp(
553       group(), EC_KEY_get0_public_key(key.get()), x.get(), y.get(), nullptr));
554   EXPECT_TRUE(
555       EC_GROUP_get_curve_GFp(group(), p.get(), nullptr, nullptr, nullptr));
556 
557   // Points on the curve should be accepted.
558   auto point = bssl::UniquePtr<EC_POINT>(EC_POINT_new(group()));
559   ASSERT_TRUE(point);
560   EXPECT_TRUE(EC_POINT_set_affine_coordinates_GFp(group(), point.get(), x.get(),
561                                                   y.get(), nullptr));
562 
563   // Subtract one from |y| to make the point no longer on the curve.
564   EXPECT_TRUE(BN_sub(y.get(), y.get(), BN_value_one()));
565 
566   // Points not on the curve should be rejected.
567   bssl::UniquePtr<EC_POINT> invalid_point(EC_POINT_new(group()));
568   ASSERT_TRUE(invalid_point);
569   EXPECT_FALSE(EC_POINT_set_affine_coordinates_GFp(group(), invalid_point.get(),
570                                                    x.get(), y.get(), nullptr));
571 
572   // Coordinates out of range should be rejected.
573   EXPECT_TRUE(BN_add(y.get(), y.get(), BN_value_one()));
574   EXPECT_TRUE(BN_add(y.get(), y.get(), p.get()));
575 
576   EXPECT_FALSE(EC_POINT_set_affine_coordinates_GFp(group(), invalid_point.get(),
577                                                    x.get(), y.get(), nullptr));
578   EXPECT_FALSE(
579       EC_KEY_set_public_key_affine_coordinates(key.get(), x.get(), y.get()));
580 }
581 
TEST_P(ECCurveTest,IsOnCurve)582 TEST_P(ECCurveTest, IsOnCurve) {
583   bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(GetParam()));
584   ASSERT_TRUE(key);
585   ASSERT_TRUE(EC_KEY_generate_key(key.get()));
586 
587   // The generated point is on the curve.
588   EXPECT_TRUE(EC_POINT_is_on_curve(group(), EC_KEY_get0_public_key(key.get()),
589                                    nullptr));
590 
591   bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group()));
592   ASSERT_TRUE(p);
593   ASSERT_TRUE(EC_POINT_copy(p.get(), EC_KEY_get0_public_key(key.get())));
594 
595   // This should never happen outside of a bug, but |EC_POINT_is_on_curve|
596   // rejects points not on the curve.
597   OPENSSL_memset(&p->raw.X, 0, sizeof(p->raw.X));
598   EXPECT_FALSE(EC_POINT_is_on_curve(group(), p.get(), nullptr));
599 
600   // The point at infinity is always on the curve.
601   ASSERT_TRUE(EC_POINT_copy(p.get(), EC_KEY_get0_public_key(key.get())));
602   OPENSSL_memset(&p->raw.Z, 0, sizeof(p->raw.Z));
603   EXPECT_TRUE(EC_POINT_is_on_curve(group(), p.get(), nullptr));
604 }
605 
TEST_P(ECCurveTest,Compare)606 TEST_P(ECCurveTest, Compare) {
607   bssl::UniquePtr<EC_KEY> key1(EC_KEY_new_by_curve_name(GetParam()));
608   ASSERT_TRUE(key1);
609   ASSERT_TRUE(EC_KEY_generate_key(key1.get()));
610   const EC_POINT *pub1 = EC_KEY_get0_public_key(key1.get());
611 
612   bssl::UniquePtr<EC_KEY> key2(EC_KEY_new_by_curve_name(GetParam()));
613   ASSERT_TRUE(key2);
614   ASSERT_TRUE(EC_KEY_generate_key(key2.get()));
615   const EC_POINT *pub2 = EC_KEY_get0_public_key(key2.get());
616 
617   // Two different points should not compare as equal.
618   EXPECT_EQ(1, EC_POINT_cmp(group(), pub1, pub2, nullptr));
619 
620   // Serialize |pub1| and parse it back out. This gives a point in affine
621   // coordinates.
622   std::vector<uint8_t> serialized;
623   ASSERT_TRUE(
624       EncodeECPoint(&serialized, group(), pub1, POINT_CONVERSION_UNCOMPRESSED));
625   bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group()));
626   ASSERT_TRUE(p);
627   ASSERT_TRUE(EC_POINT_oct2point(group(), p.get(), serialized.data(),
628                                  serialized.size(), nullptr));
629 
630   // The points should be equal.
631   EXPECT_EQ(0, EC_POINT_cmp(group(), p.get(), pub1, nullptr));
632 
633   // Add something to the point. It no longer compares as equal.
634   ASSERT_TRUE(EC_POINT_add(group(), p.get(), p.get(), pub2, nullptr));
635   EXPECT_EQ(1, EC_POINT_cmp(group(), p.get(), pub1, nullptr));
636 
637   // Negate |pub2|. It should no longer compare as equal. This tests that we
638   // check both x and y coordinate.
639   bssl::UniquePtr<EC_POINT> q(EC_POINT_new(group()));
640   ASSERT_TRUE(q);
641   ASSERT_TRUE(EC_POINT_copy(q.get(), pub2));
642   ASSERT_TRUE(EC_POINT_invert(group(), q.get(), nullptr));
643   EXPECT_EQ(1, EC_POINT_cmp(group(), q.get(), pub2, nullptr));
644 
645   // Return |p| to the original value. It should be equal to |pub1| again.
646   ASSERT_TRUE(EC_POINT_add(group(), p.get(), p.get(), q.get(), nullptr));
647   EXPECT_EQ(0, EC_POINT_cmp(group(), p.get(), pub1, nullptr));
648 
649   // Infinity compares as equal to itself, but not other points.
650   bssl::UniquePtr<EC_POINT> inf1(EC_POINT_new(group())),
651       inf2(EC_POINT_new(group()));
652   ASSERT_TRUE(inf1);
653   ASSERT_TRUE(inf2);
654   ASSERT_TRUE(EC_POINT_set_to_infinity(group(), inf1.get()));
655   // |q| is currently -|pub2|.
656   ASSERT_TRUE(EC_POINT_add(group(), inf2.get(), pub2, q.get(), nullptr));
657   EXPECT_EQ(0, EC_POINT_cmp(group(), inf1.get(), inf2.get(), nullptr));
658   EXPECT_EQ(1, EC_POINT_cmp(group(), inf1.get(), p.get(), nullptr));
659 }
660 
TEST_P(ECCurveTest,GenerateFIPS)661 TEST_P(ECCurveTest, GenerateFIPS) {
662   // Generate an EC_KEY.
663   bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(GetParam()));
664   ASSERT_TRUE(key);
665   ASSERT_TRUE(EC_KEY_generate_key_fips(key.get()));
666 }
667 
TEST_P(ECCurveTest,AddingEqualPoints)668 TEST_P(ECCurveTest, AddingEqualPoints) {
669   bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(GetParam()));
670   ASSERT_TRUE(key);
671   ASSERT_TRUE(EC_KEY_generate_key(key.get()));
672 
673   bssl::UniquePtr<EC_POINT> p1(EC_POINT_new(group()));
674   ASSERT_TRUE(p1);
675   ASSERT_TRUE(EC_POINT_copy(p1.get(), EC_KEY_get0_public_key(key.get())));
676 
677   bssl::UniquePtr<EC_POINT> p2(EC_POINT_new(group()));
678   ASSERT_TRUE(p2);
679   ASSERT_TRUE(EC_POINT_copy(p2.get(), EC_KEY_get0_public_key(key.get())));
680 
681   bssl::UniquePtr<EC_POINT> double_p1(EC_POINT_new(group()));
682   ASSERT_TRUE(double_p1);
683   bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
684   ASSERT_TRUE(ctx);
685   ASSERT_TRUE(EC_POINT_dbl(group(), double_p1.get(), p1.get(), ctx.get()));
686 
687   bssl::UniquePtr<EC_POINT> p1_plus_p2(EC_POINT_new(group()));
688   ASSERT_TRUE(p1_plus_p2);
689   ASSERT_TRUE(
690       EC_POINT_add(group(), p1_plus_p2.get(), p1.get(), p2.get(), ctx.get()));
691 
692   EXPECT_EQ(0,
693             EC_POINT_cmp(group(), double_p1.get(), p1_plus_p2.get(), ctx.get()))
694       << "A+A != 2A";
695 }
696 
TEST_P(ECCurveTest,MulZero)697 TEST_P(ECCurveTest, MulZero) {
698   bssl::UniquePtr<EC_POINT> point(EC_POINT_new(group()));
699   ASSERT_TRUE(point);
700   bssl::UniquePtr<BIGNUM> zero(BN_new());
701   ASSERT_TRUE(zero);
702   BN_zero(zero.get());
703   ASSERT_TRUE(EC_POINT_mul(group(), point.get(), zero.get(), nullptr, nullptr,
704                            nullptr));
705 
706   EXPECT_TRUE(EC_POINT_is_at_infinity(group(), point.get()))
707       << "g * 0 did not return point at infinity.";
708 
709   // Test that zero times an arbitrary point is also infinity. The generator is
710   // used as the arbitrary point.
711   bssl::UniquePtr<EC_POINT> generator(EC_POINT_new(group()));
712   ASSERT_TRUE(generator);
713   ASSERT_TRUE(EC_POINT_mul(group(), generator.get(), BN_value_one(), nullptr,
714                            nullptr, nullptr));
715   ASSERT_TRUE(EC_POINT_mul(group(), point.get(), nullptr, generator.get(),
716                            zero.get(), nullptr));
717 
718   EXPECT_TRUE(EC_POINT_is_at_infinity(group(), point.get()))
719       << "p * 0 did not return point at infinity.";
720 }
721 
722 // Test that multiplying by the order produces ∞ and, moreover, that callers may
723 // do so. |EC_POINT_mul| is almost exclusively used with reduced scalars, with
724 // this exception. This comes from consumers following NIST SP 800-56A section
725 // 5.6.2.3.2. (Though all our curves have cofactor one, so this check isn't
726 // useful.)
TEST_P(ECCurveTest,MulOrder)727 TEST_P(ECCurveTest, MulOrder) {
728   // Test that g × order = ∞.
729   bssl::UniquePtr<EC_POINT> point(EC_POINT_new(group()));
730   ASSERT_TRUE(point);
731   ASSERT_TRUE(EC_POINT_mul(group(), point.get(), EC_GROUP_get0_order(group()),
732                            nullptr, nullptr, nullptr));
733 
734   EXPECT_TRUE(EC_POINT_is_at_infinity(group(), point.get()))
735       << "g * order did not return point at infinity.";
736 
737   // Test that p × order = ∞, for some arbitrary p.
738   bssl::UniquePtr<BIGNUM> forty_two(BN_new());
739   ASSERT_TRUE(forty_two);
740   ASSERT_TRUE(BN_set_word(forty_two.get(), 42));
741   ASSERT_TRUE(EC_POINT_mul(group(), point.get(), forty_two.get(), nullptr,
742                            nullptr, nullptr));
743   ASSERT_TRUE(EC_POINT_mul(group(), point.get(), nullptr, point.get(),
744                            EC_GROUP_get0_order(group()), nullptr));
745 
746   EXPECT_TRUE(EC_POINT_is_at_infinity(group(), point.get()))
747       << "p * order did not return point at infinity.";
748 }
749 
750 // Test that |EC_POINT_mul| works with out-of-range scalars. The operation will
751 // not be constant-time, but we'll compute the right answer.
TEST_P(ECCurveTest,MulOutOfRange)752 TEST_P(ECCurveTest, MulOutOfRange) {
753   bssl::UniquePtr<BIGNUM> n_minus_one(BN_dup(EC_GROUP_get0_order(group())));
754   ASSERT_TRUE(n_minus_one);
755   ASSERT_TRUE(BN_sub_word(n_minus_one.get(), 1));
756 
757   bssl::UniquePtr<BIGNUM> minus_one(BN_new());
758   ASSERT_TRUE(minus_one);
759   ASSERT_TRUE(BN_one(minus_one.get()));
760   BN_set_negative(minus_one.get(), 1);
761 
762   bssl::UniquePtr<BIGNUM> seven(BN_new());
763   ASSERT_TRUE(seven);
764   ASSERT_TRUE(BN_set_word(seven.get(), 7));
765 
766   bssl::UniquePtr<BIGNUM> ten_n_plus_seven(
767       BN_dup(EC_GROUP_get0_order(group())));
768   ASSERT_TRUE(ten_n_plus_seven);
769   ASSERT_TRUE(BN_mul_word(ten_n_plus_seven.get(), 10));
770   ASSERT_TRUE(BN_add_word(ten_n_plus_seven.get(), 7));
771 
772   bssl::UniquePtr<EC_POINT> point1(EC_POINT_new(group())),
773       point2(EC_POINT_new(group()));
774   ASSERT_TRUE(point1);
775   ASSERT_TRUE(point2);
776 
777   ASSERT_TRUE(EC_POINT_mul(group(), point1.get(), n_minus_one.get(), nullptr,
778                            nullptr, nullptr));
779   ASSERT_TRUE(EC_POINT_mul(group(), point2.get(), minus_one.get(), nullptr,
780                            nullptr, nullptr));
781   EXPECT_EQ(0, EC_POINT_cmp(group(), point1.get(), point2.get(), nullptr))
782       << "-1 * G and (n-1) * G did not give the same result";
783 
784   ASSERT_TRUE(EC_POINT_mul(group(), point1.get(), seven.get(), nullptr, nullptr,
785                            nullptr));
786   ASSERT_TRUE(EC_POINT_mul(group(), point2.get(), ten_n_plus_seven.get(),
787                            nullptr, nullptr, nullptr));
788   EXPECT_EQ(0, EC_POINT_cmp(group(), point1.get(), point2.get(), nullptr))
789       << "7 * G and (10n + 7) * G did not give the same result";
790 }
791 
792 // Test that 10×∞ + G = G.
TEST_P(ECCurveTest,Mul)793 TEST_P(ECCurveTest, Mul) {
794   bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group()));
795   ASSERT_TRUE(p);
796   bssl::UniquePtr<EC_POINT> result(EC_POINT_new(group()));
797   ASSERT_TRUE(result);
798   bssl::UniquePtr<BIGNUM> n(BN_new());
799   ASSERT_TRUE(n);
800   ASSERT_TRUE(EC_POINT_set_to_infinity(group(), p.get()));
801   ASSERT_TRUE(BN_set_word(n.get(), 10));
802 
803   // First check that 10×∞ = ∞.
804   ASSERT_TRUE(
805       EC_POINT_mul(group(), result.get(), nullptr, p.get(), n.get(), nullptr));
806   EXPECT_TRUE(EC_POINT_is_at_infinity(group(), result.get()));
807 
808   // Now check that 10×∞ + G = G.
809   const EC_POINT *generator = EC_GROUP_get0_generator(group());
810   ASSERT_TRUE(EC_POINT_mul(group(), result.get(), BN_value_one(), p.get(),
811                            n.get(), nullptr));
812   EXPECT_EQ(0, EC_POINT_cmp(group(), result.get(), generator, nullptr));
813 }
814 
TEST_P(ECCurveTest,MulNonMinimal)815 TEST_P(ECCurveTest, MulNonMinimal) {
816   bssl::UniquePtr<BIGNUM> forty_two(BN_new());
817   ASSERT_TRUE(forty_two);
818   ASSERT_TRUE(BN_set_word(forty_two.get(), 42));
819 
820   // Compute g × 42.
821   bssl::UniquePtr<EC_POINT> point(EC_POINT_new(group()));
822   ASSERT_TRUE(point);
823   ASSERT_TRUE(EC_POINT_mul(group(), point.get(), forty_two.get(), nullptr,
824                            nullptr, nullptr));
825 
826   // Compute it again with a non-minimal 42, much larger than the scalar.
827   ASSERT_TRUE(bn_resize_words(forty_two.get(), 64));
828 
829   bssl::UniquePtr<EC_POINT> point2(EC_POINT_new(group()));
830   ASSERT_TRUE(point2);
831   ASSERT_TRUE(EC_POINT_mul(group(), point2.get(), forty_two.get(), nullptr,
832                            nullptr, nullptr));
833   EXPECT_EQ(0, EC_POINT_cmp(group(), point.get(), point2.get(), nullptr));
834 }
835 
836 // Test that EC_KEY_set_private_key rejects invalid values.
TEST_P(ECCurveTest,SetInvalidPrivateKey)837 TEST_P(ECCurveTest, SetInvalidPrivateKey) {
838   bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(GetParam()));
839   ASSERT_TRUE(key);
840 
841   bssl::UniquePtr<BIGNUM> bn(BN_dup(BN_value_one()));
842   ASSERT_TRUE(bn);
843   BN_set_negative(bn.get(), 1);
844   EXPECT_FALSE(EC_KEY_set_private_key(key.get(), bn.get()))
845       << "Unexpectedly set a key of -1";
846   ERR_clear_error();
847 
848   ASSERT_TRUE(
849       BN_copy(bn.get(), EC_GROUP_get0_order(EC_KEY_get0_group(key.get()))));
850   EXPECT_FALSE(EC_KEY_set_private_key(key.get(), bn.get()))
851       << "Unexpectedly set a key of the group order.";
852   ERR_clear_error();
853 
854   BN_zero(bn.get());
855   EXPECT_FALSE(EC_KEY_set_private_key(key.get(), bn.get()))
856       << "Unexpectedly set a key of 0";
857   ERR_clear_error();
858 }
859 
TEST_P(ECCurveTest,IgnoreOct2PointReturnValue)860 TEST_P(ECCurveTest, IgnoreOct2PointReturnValue) {
861   bssl::UniquePtr<BIGNUM> forty_two(BN_new());
862   ASSERT_TRUE(forty_two);
863   ASSERT_TRUE(BN_set_word(forty_two.get(), 42));
864 
865   // Compute g × 42.
866   bssl::UniquePtr<EC_POINT> point(EC_POINT_new(group()));
867   ASSERT_TRUE(point);
868   ASSERT_TRUE(EC_POINT_mul(group(), point.get(), forty_two.get(), nullptr,
869                            nullptr, nullptr));
870 
871   // Serialize the point.
872   std::vector<uint8_t> serialized;
873   ASSERT_TRUE(EncodeECPoint(&serialized, group(), point.get(),
874                             POINT_CONVERSION_UNCOMPRESSED));
875 
876   // Create a serialized point that is not on the curve.
877   serialized[serialized.size() - 1]++;
878 
879   ASSERT_FALSE(EC_POINT_oct2point(group(), point.get(), serialized.data(),
880                                   serialized.size(), nullptr));
881   // After a failure, |point| should have been set to the generator to defend
882   // against code that doesn't check the return value.
883   ASSERT_EQ(0, EC_POINT_cmp(group(), point.get(),
884                             EC_GROUP_get0_generator(group()), nullptr));
885 }
886 
TEST_P(ECCurveTest,DoubleSpecialCase)887 TEST_P(ECCurveTest, DoubleSpecialCase) {
888   const EC_POINT *g = EC_GROUP_get0_generator(group());
889 
890   bssl::UniquePtr<EC_POINT> two_g(EC_POINT_new(group()));
891   ASSERT_TRUE(two_g);
892   ASSERT_TRUE(EC_POINT_dbl(group(), two_g.get(), g, nullptr));
893 
894   bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group()));
895   ASSERT_TRUE(p);
896   ASSERT_TRUE(EC_POINT_mul(group(), p.get(), BN_value_one(), g, BN_value_one(),
897                            nullptr));
898   EXPECT_EQ(0, EC_POINT_cmp(group(), p.get(), two_g.get(), nullptr));
899 
900   EC_SCALAR one;
901   ASSERT_TRUE(ec_bignum_to_scalar(group(), &one, BN_value_one()));
902   ASSERT_TRUE(
903       ec_point_mul_scalar_public(group(), &p->raw, &one, &g->raw, &one));
904   EXPECT_EQ(0, EC_POINT_cmp(group(), p.get(), two_g.get(), nullptr));
905 }
906 
907 // This a regression test for a P-224 bug, but we may as well run it for all
908 // curves.
TEST_P(ECCurveTest,P224Bug)909 TEST_P(ECCurveTest, P224Bug) {
910   // P = -G
911   const EC_POINT *g = EC_GROUP_get0_generator(group());
912   bssl::UniquePtr<EC_POINT> p(EC_POINT_dup(g, group()));
913   ASSERT_TRUE(p);
914   ASSERT_TRUE(EC_POINT_invert(group(), p.get(), nullptr));
915 
916   // Compute 31 * P + 32 * G = G
917   bssl::UniquePtr<EC_POINT> ret(EC_POINT_new(group()));
918   ASSERT_TRUE(ret);
919   bssl::UniquePtr<BIGNUM> bn31(BN_new()), bn32(BN_new());
920   ASSERT_TRUE(bn31);
921   ASSERT_TRUE(bn32);
922   ASSERT_TRUE(BN_set_word(bn31.get(), 31));
923   ASSERT_TRUE(BN_set_word(bn32.get(), 32));
924   ASSERT_TRUE(EC_POINT_mul(group(), ret.get(), bn32.get(), p.get(), bn31.get(),
925                            nullptr));
926   EXPECT_EQ(0, EC_POINT_cmp(group(), ret.get(), g, nullptr));
927 
928   // Repeat the computation with |ec_point_mul_scalar_public|, which ties the
929   // additions together.
930   EC_SCALAR sc31, sc32;
931   ASSERT_TRUE(ec_bignum_to_scalar(group(), &sc31, bn31.get()));
932   ASSERT_TRUE(ec_bignum_to_scalar(group(), &sc32, bn32.get()));
933   ASSERT_TRUE(
934       ec_point_mul_scalar_public(group(), &ret->raw, &sc32, &p->raw, &sc31));
935   EXPECT_EQ(0, EC_POINT_cmp(group(), ret.get(), g, nullptr));
936 }
937 
TEST_P(ECCurveTest,GPlusMinusG)938 TEST_P(ECCurveTest, GPlusMinusG) {
939   const EC_POINT *g = EC_GROUP_get0_generator(group());
940 
941   bssl::UniquePtr<EC_POINT> p(EC_POINT_dup(g, group()));
942   ASSERT_TRUE(p);
943   ASSERT_TRUE(EC_POINT_invert(group(), p.get(), nullptr));
944 
945   bssl::UniquePtr<EC_POINT> sum(EC_POINT_new(group()));
946   ASSERT_TRUE(sum);
947   ASSERT_TRUE(EC_POINT_add(group(), sum.get(), g, p.get(), nullptr));
948   EXPECT_TRUE(EC_POINT_is_at_infinity(group(), sum.get()));
949 }
950 
951 // Test that we refuse to encode or decode the point at infinity.
TEST_P(ECCurveTest,EncodeInfinity)952 TEST_P(ECCurveTest, EncodeInfinity) {
953   // The point at infinity is encoded as a single zero byte, but we do not
954   // support it.
955   static const uint8_t kInfinity[] = {0};
956   bssl::UniquePtr<EC_POINT> inf(EC_POINT_new(group()));
957   ASSERT_TRUE(inf);
958   EXPECT_FALSE(EC_POINT_oct2point(group(), inf.get(), kInfinity,
959                                   sizeof(kInfinity), nullptr));
960 
961   // Encoding it also fails.
962   ASSERT_TRUE(EC_POINT_set_to_infinity(group(), inf.get()));
963   uint8_t buf[128];
964   EXPECT_EQ(
965       0u, EC_POINT_point2oct(group(), inf.get(), POINT_CONVERSION_UNCOMPRESSED,
966                              buf, sizeof(buf), nullptr));
967 
968   // Measuring the length of the encoding also fails.
969   EXPECT_EQ(
970       0u, EC_POINT_point2oct(group(), inf.get(), POINT_CONVERSION_UNCOMPRESSED,
971                              nullptr, 0, nullptr));
972 }
973 
AllCurves()974 static std::vector<int> AllCurves() {
975   const size_t num_curves = EC_get_builtin_curves(nullptr, 0);
976   std::vector<EC_builtin_curve> curves(num_curves);
977   EC_get_builtin_curves(curves.data(), num_curves);
978   std::vector<int> nids;
979   for (const auto& curve : curves) {
980     nids.push_back(curve.nid);
981   }
982   return nids;
983 }
984 
CurveToString(const testing::TestParamInfo<int> & params)985 static std::string CurveToString(const testing::TestParamInfo<int> &params) {
986   return OBJ_nid2sn(params.param);
987 }
988 
989 INSTANTIATE_TEST_SUITE_P(All, ECCurveTest, testing::ValuesIn(AllCurves()),
990                          CurveToString);
991 
GetCurve(FileTest * t,const char * key)992 static const EC_GROUP *GetCurve(FileTest *t, const char *key) {
993   std::string curve_name;
994   if (!t->GetAttribute(&curve_name, key)) {
995     return nullptr;
996   }
997 
998   if (curve_name == "P-224") {
999     return EC_group_p224();
1000   }
1001   if (curve_name == "P-256") {
1002     return EC_group_p256();
1003   }
1004   if (curve_name == "P-384") {
1005     return EC_group_p384();
1006   }
1007   if (curve_name == "P-521") {
1008     return EC_group_p521();
1009   }
1010 
1011   t->PrintLine("Unknown curve '%s'", curve_name.c_str());
1012   return nullptr;
1013 }
1014 
GetBIGNUM(FileTest * t,const char * key)1015 static bssl::UniquePtr<BIGNUM> GetBIGNUM(FileTest *t, const char *key) {
1016   std::vector<uint8_t> bytes;
1017   if (!t->GetBytes(&bytes, key)) {
1018     return nullptr;
1019   }
1020 
1021   return bssl::UniquePtr<BIGNUM>(
1022       BN_bin2bn(bytes.data(), bytes.size(), nullptr));
1023 }
1024 
TEST(ECTest,ScalarBaseMultVectors)1025 TEST(ECTest, ScalarBaseMultVectors) {
1026   bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
1027   ASSERT_TRUE(ctx);
1028 
1029   FileTestGTest("crypto/fipsmodule/ec/ec_scalar_base_mult_tests.txt",
1030                 [&](FileTest *t) {
1031     const EC_GROUP *group = GetCurve(t, "Curve");
1032     ASSERT_TRUE(group);
1033     bssl::UniquePtr<BIGNUM> n = GetBIGNUM(t, "N");
1034     ASSERT_TRUE(n);
1035     bssl::UniquePtr<BIGNUM> x = GetBIGNUM(t, "X");
1036     ASSERT_TRUE(x);
1037     bssl::UniquePtr<BIGNUM> y = GetBIGNUM(t, "Y");
1038     ASSERT_TRUE(y);
1039     bool is_infinity = BN_is_zero(x.get()) && BN_is_zero(y.get());
1040 
1041     bssl::UniquePtr<BIGNUM> px(BN_new());
1042     ASSERT_TRUE(px);
1043     bssl::UniquePtr<BIGNUM> py(BN_new());
1044     ASSERT_TRUE(py);
1045     auto check_point = [&](const EC_POINT *p) {
1046       if (is_infinity) {
1047         EXPECT_TRUE(EC_POINT_is_at_infinity(group, p));
1048       } else {
1049         ASSERT_TRUE(EC_POINT_get_affine_coordinates_GFp(
1050             group, p, px.get(), py.get(), ctx.get()));
1051         EXPECT_EQ(0, BN_cmp(x.get(), px.get()));
1052         EXPECT_EQ(0, BN_cmp(y.get(), py.get()));
1053       }
1054     };
1055 
1056     const EC_POINT *g = EC_GROUP_get0_generator(group);
1057     bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group));
1058     ASSERT_TRUE(p);
1059     // Test single-point multiplication.
1060     ASSERT_TRUE(EC_POINT_mul(group, p.get(), n.get(), nullptr, nullptr,
1061                              ctx.get()));
1062     check_point(p.get());
1063 
1064     ASSERT_TRUE(EC_POINT_mul(group, p.get(), nullptr, g, n.get(), ctx.get()));
1065     check_point(p.get());
1066   });
1067 }
1068 
1069 // These tests take a very long time, but are worth running when we make
1070 // non-trivial changes to the EC code.
TEST(ECTest,DISABLED_ScalarBaseMultVectorsTwoPoint)1071 TEST(ECTest, DISABLED_ScalarBaseMultVectorsTwoPoint) {
1072   bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
1073   ASSERT_TRUE(ctx);
1074 
1075   FileTestGTest("crypto/fipsmodule/ec/ec_scalar_base_mult_tests.txt",
1076                 [&](FileTest *t) {
1077     const EC_GROUP *group = GetCurve(t, "Curve");
1078     ASSERT_TRUE(group);
1079     bssl::UniquePtr<BIGNUM> n = GetBIGNUM(t, "N");
1080     ASSERT_TRUE(n);
1081     bssl::UniquePtr<BIGNUM> x = GetBIGNUM(t, "X");
1082     ASSERT_TRUE(x);
1083     bssl::UniquePtr<BIGNUM> y = GetBIGNUM(t, "Y");
1084     ASSERT_TRUE(y);
1085     bool is_infinity = BN_is_zero(x.get()) && BN_is_zero(y.get());
1086 
1087     bssl::UniquePtr<BIGNUM> px(BN_new());
1088     ASSERT_TRUE(px);
1089     bssl::UniquePtr<BIGNUM> py(BN_new());
1090     ASSERT_TRUE(py);
1091     auto check_point = [&](const EC_POINT *p) {
1092       if (is_infinity) {
1093         EXPECT_TRUE(EC_POINT_is_at_infinity(group, p));
1094       } else {
1095         ASSERT_TRUE(EC_POINT_get_affine_coordinates_GFp(
1096             group, p, px.get(), py.get(), ctx.get()));
1097         EXPECT_EQ(0, BN_cmp(x.get(), px.get()));
1098         EXPECT_EQ(0, BN_cmp(y.get(), py.get()));
1099       }
1100     };
1101 
1102     const EC_POINT *g = EC_GROUP_get0_generator(group);
1103     bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group));
1104     ASSERT_TRUE(p);
1105     bssl::UniquePtr<BIGNUM> a(BN_new()), b(BN_new());
1106     for (int i = -64; i < 64; i++) {
1107       SCOPED_TRACE(i);
1108       ASSERT_TRUE(BN_set_word(a.get(), abs(i)));
1109       if (i < 0) {
1110         ASSERT_TRUE(BN_sub(a.get(), EC_GROUP_get0_order(group), a.get()));
1111       }
1112 
1113       ASSERT_TRUE(BN_copy(b.get(), n.get()));
1114       ASSERT_TRUE(BN_sub(b.get(), b.get(), a.get()));
1115       if (BN_is_negative(b.get())) {
1116         ASSERT_TRUE(BN_add(b.get(), b.get(), EC_GROUP_get0_order(group)));
1117       }
1118 
1119       ASSERT_TRUE(EC_POINT_mul(group, p.get(), a.get(), g, b.get(), ctx.get()));
1120       check_point(p.get());
1121 
1122       EC_SCALAR a_scalar, b_scalar;
1123       ASSERT_TRUE(ec_bignum_to_scalar(group, &a_scalar, a.get()));
1124       ASSERT_TRUE(ec_bignum_to_scalar(group, &b_scalar, b.get()));
1125       ASSERT_TRUE(ec_point_mul_scalar_public(group, &p->raw, &a_scalar, &g->raw,
1126                                              &b_scalar));
1127       check_point(p.get());
1128     }
1129   });
1130 }
1131 
HexToBytes(const char * str)1132 static std::vector<uint8_t> HexToBytes(const char *str) {
1133   std::vector<uint8_t> ret;
1134   if (!DecodeHex(&ret, str)) {
1135     abort();
1136   }
1137   return ret;
1138 }
1139 
TEST(ECTest,DeriveFromSecret)1140 TEST(ECTest, DeriveFromSecret) {
1141   struct DeriveTest {
1142     const EC_GROUP *group;
1143     std::vector<uint8_t> secret;
1144     std::vector<uint8_t> expected_priv;
1145     std::vector<uint8_t> expected_pub;
1146   };
1147   const DeriveTest kDeriveTests[] = {
1148       {EC_group_p256(), HexToBytes(""),
1149        HexToBytes(
1150            "b98a86a71efb51ebdac4759937b977e9b0c05224675bb2b6a58ba306e237f4b8"),
1151        HexToBytes(
1152            "04fbe6cab439918e00231a2ff073cdc25823998864a9eb36f809095a1a919ece875"
1153            "a145803fbe89a6cde53936e3c6d9c253ed3d38f5f58cae455c27e95645ceda9")},
1154       {EC_group_p256(), HexToBytes("123456"),
1155        HexToBytes(
1156            "44a72bc62087b88e5ab7126766177ed0d8f1ed09ad066cd746527fc201105a7e"),
1157        HexToBytes(
1158            "04ec0555cd76e991fef7f5504343937d0f38696db3360a4854052cb0d84a377a5a0"
1159            "ff64c352755c28692b4ae085c2b817db9a1eddbd22e9cf39c12751e0870791b")},
1160       {EC_group_p256(), HexToBytes("00000000000000000000000000000000"),
1161        HexToBytes(
1162            "7ca1e2c83e6a5f2c1b3e7d58180226f269930c4b9fbe2a275096079630b7c57d"),
1163        HexToBytes(
1164            "0442ef70c8fc0fbe383ed0a0da36f39f9a590f3feebc07863cc858c9a8ef0465731"
1165            "0408c249bd4d61929c54b71ffe056e6b4fa1eb537039b43d1c175f0ceab0f89")},
1166       {EC_group_p256(),
1167        HexToBytes(
1168            "de9c9b35543aaa0fba039e34e8ca9695da3225c7161c9e3a8c70356cac28c780"),
1169        HexToBytes(
1170            "659f5abf3b62b9931c29d6ed0722efd2349fa56f54e708cf3272f620f1bc44d0"),
1171        HexToBytes(
1172            "046741f806b593bf3a3d4a9d76bdcb9b0d7874633cbea8f42c05e78561f7e8ec362"
1173            "b9b6f1913ded796fbdafe7f210cea897ac22a4e580c06a60f2659fd09f1830f")},
1174       {EC_group_p384(), HexToBytes("123456"),
1175        HexToBytes("95cd90d548997de090c7622708eccb7edc1b1bd78d2422235ad97406dada"
1176                   "076555309da200096f6e4b36c46002beee89"),
1177        HexToBytes(
1178            "04007b2d026aa7636fa912c3f970d62bb6c10fa81c8f3290ed90b2d701696d1c6b9"
1179            "5af88ce13e962996a7ac37e16527cb5d69bd081b8641d07634cf84b438600ec9434"
1180            "15ac6bd7a0236f7ab0ea31ece67df03fa11646ea2b75e73d1b5e45b75c18")},
1181   };
1182 
1183   for (const auto &test : kDeriveTests) {
1184     SCOPED_TRACE(Bytes(test.secret));
1185 
1186     bssl::UniquePtr<EC_KEY> key(EC_KEY_derive_from_secret(
1187         test.group, test.secret.data(), test.secret.size()));
1188     ASSERT_TRUE(key);
1189 
1190     std::vector<uint8_t> priv(BN_num_bytes(EC_GROUP_get0_order(test.group)));
1191     ASSERT_TRUE(BN_bn2bin_padded(priv.data(), priv.size(),
1192                                  EC_KEY_get0_private_key(key.get())));
1193     EXPECT_EQ(Bytes(priv), Bytes(test.expected_priv));
1194 
1195     uint8_t *pub = nullptr;
1196     size_t pub_len =
1197         EC_KEY_key2buf(key.get(), POINT_CONVERSION_UNCOMPRESSED, &pub, nullptr);
1198     bssl::UniquePtr<uint8_t> free_pub(pub);
1199     EXPECT_NE(pub_len, 0u);
1200     EXPECT_EQ(Bytes(pub, pub_len), Bytes(test.expected_pub));
1201   }
1202 }
1203 
TEST(ECTest,HashToCurve)1204 TEST(ECTest, HashToCurve) {
1205   auto hash_to_curve_p384_sha512_draft07 =
1206       [](const EC_GROUP *group, EC_POINT *out, const uint8_t *dst,
1207          size_t dst_len, const uint8_t *msg, size_t msg_len) -> int {
1208     if (EC_GROUP_cmp(group, out->group, NULL) != 0) {
1209       return 0;
1210     }
1211     return ec_hash_to_curve_p384_xmd_sha512_sswu_draft07(group, &out->raw, dst,
1212                                                          dst_len, msg, msg_len);
1213   };
1214 
1215   struct HashToCurveTest {
1216     int (*hash_to_curve)(const EC_GROUP *group, EC_POINT *out,
1217                          const uint8_t *dst, size_t dst_len, const uint8_t *msg,
1218                          size_t msg_len);
1219     const EC_GROUP *group;
1220     const char *dst;
1221     const char *msg;
1222     const char *x_hex;
1223     const char *y_hex;
1224   };
1225   const HashToCurveTest kTests[] = {
1226       // See RFC 9380, appendix J.1.1.
1227       {&EC_hash_to_curve_p256_xmd_sha256_sswu, EC_group_p256(),
1228        "QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_", "",
1229        "2c15230b26dbc6fc9a37051158c95b79656e17a1a920b11394ca91"
1230        "c44247d3e4",
1231        "8a7a74985cc5c776cdfe4b1f19884970453912e9d31528c060be9a"
1232        "b5c43e8415"},
1233       {&EC_hash_to_curve_p256_xmd_sha256_sswu, EC_group_p256(),
1234        "QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_", "abc",
1235        "0bb8b87485551aa43ed54f009230450b492fead5f1cc91658775da"
1236        "c4a3388a0f",
1237        "5c41b3d0731a27a7b14bc0bf0ccded2d8751f83493404c84a88e71"
1238        "ffd424212e"},
1239       {&EC_hash_to_curve_p256_xmd_sha256_sswu, EC_group_p256(),
1240        "QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_", "abcdef0123456789",
1241        "65038ac8f2b1def042a5df0b33b1f4eca6bff7cb0f9c6c15268118"
1242        "64e544ed80",
1243        "cad44d40a656e7aff4002a8de287abc8ae0482b5ae825822bb870d"
1244        "6df9b56ca3"},
1245       {&EC_hash_to_curve_p256_xmd_sha256_sswu, EC_group_p256(),
1246        "QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_",
1247        "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"
1248        "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"
1249        "qqqqqqqqqqqqqqqqqqqqqqqqq",
1250        "4be61ee205094282ba8a2042bcb48d88dfbb609301c49aa8b07853"
1251        "3dc65a0b5d",
1252        "98f8df449a072c4721d241a3b1236d3caccba603f916ca680f4539"
1253        "d2bfb3c29e"},
1254       {&EC_hash_to_curve_p256_xmd_sha256_sswu, EC_group_p256(),
1255        "QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_",
1256        "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1257        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1258        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1259        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1260        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1261        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1262        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1263        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1264        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1265        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
1266        "457ae2981f70ca85d8e24c308b14db22f3e3862c5ea0f652ca38b5"
1267        "e49cd64bc5",
1268        "ecb9f0eadc9aeed232dabc53235368c1394c78de05dd96893eefa6"
1269        "2b0f4757dc"},
1270 
1271       // See draft-irtf-cfrg-hash-to-curve-07, appendix G.2.1.
1272       {hash_to_curve_p384_sha512_draft07, EC_group_p384(),
1273        "P384_XMD:SHA-512_SSWU_RO_TESTGEN", "",
1274        "2fc0b9efdd63a8e43b4db88dc12f03c798f6fd91bccac0c9096185"
1275        "4386e58fdc54fc2a01f0f358759054ce1f9b762025",
1276        "949b936fabb72cdb02cd7980b86cb6a3adf286658e81301648851d"
1277        "b8a49d9bec00ccb57698d559fc5960fa5030a8e54b"},
1278       {hash_to_curve_p384_sha512_draft07, EC_group_p384(),
1279        "P384_XMD:SHA-512_SSWU_RO_TESTGEN", "abc",
1280        "4f3338035391e8ce8ce40c974136f0edc97f392ffd44a643338741"
1281        "8ed1b8c2603487e1688ec151f048fbc6b2c138c92f",
1282        "152b90aef6558be328a3168855fb1906452e7167b0f7c8a56ff9d4"
1283        "fa87d6fb522cdf8e409db54418b2c764fd26260757"},
1284       {hash_to_curve_p384_sha512_draft07, EC_group_p384(),
1285        "P384_XMD:SHA-512_SSWU_RO_TESTGEN", "abcdef0123456789",
1286        "e9e5d7ac397e123d060ad44301cbc8eb972f6e64ebcff29dcc9b9a"
1287        "10357902aace2240c580fec85e5b427d98b4e80703",
1288        "916cb8963521ad75105be43cc4148e5a5bbb4fcf107f1577e4f7fa"
1289        "3ca58cd786aa76890c8e687d2353393bc16c78ec4d"},
1290       {hash_to_curve_p384_sha512_draft07, EC_group_p384(),
1291        "P384_XMD:SHA-512_SSWU_RO_TESTGEN",
1292        "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1293        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1294        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1295        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1296        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1297        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1298        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1299        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1300        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1301        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
1302        "41941db59a7b8b633bd5bfa462f1e29a9f18e5a341445d90fc6eb9"
1303        "37f2913224287b9dfb64742851f760eb14ca115ff9",
1304        "1510e764f1be968d661b7aaecb26a6d38c98e5205ca150f0ae426d"
1305        "2c3983c68e3a9ffb283c6ae4891d891b5705500475"},
1306   };
1307 
1308   for (const auto &test : kTests) {
1309     SCOPED_TRACE(test.dst);
1310     SCOPED_TRACE(test.msg);
1311 
1312     bssl::UniquePtr<EC_POINT> p(EC_POINT_new(test.group));
1313     ASSERT_TRUE(p);
1314     ASSERT_TRUE(test.hash_to_curve(
1315         test.group, p.get(), reinterpret_cast<const uint8_t *>(test.dst),
1316         strlen(test.dst), reinterpret_cast<const uint8_t *>(test.msg),
1317         strlen(test.msg)));
1318 
1319     std::vector<uint8_t> buf;
1320     ASSERT_TRUE(EncodeECPoint(&buf, test.group, p.get(),
1321                               POINT_CONVERSION_UNCOMPRESSED));
1322     size_t field_len = (buf.size() - 1) / 2;
1323     EXPECT_EQ(test.x_hex,
1324               EncodeHex(bssl::MakeConstSpan(buf).subspan(1, field_len)));
1325     EXPECT_EQ(test.y_hex, EncodeHex(bssl::MakeConstSpan(buf).subspan(
1326                               1 + field_len, field_len)));
1327   }
1328 
1329   // hash-to-curve functions should check for the wrong group.
1330   EC_JACOBIAN raw;
1331   bssl::UniquePtr<EC_POINT> p_p384(EC_POINT_new(EC_group_p384()));
1332   ASSERT_TRUE(p_p384);
1333   bssl::UniquePtr<EC_POINT> p_p224(EC_POINT_new(EC_group_p224()));
1334   ASSERT_TRUE(p_p224);
1335   static const uint8_t kDST[] = {0, 1, 2, 3};
1336   static const uint8_t kMessage[] = {4, 5, 6, 7};
1337   EXPECT_FALSE(ec_hash_to_curve_p384_xmd_sha384_sswu(
1338       EC_group_p224(), &raw, kDST, sizeof(kDST), kMessage, sizeof(kMessage)));
1339   EXPECT_FALSE(EC_hash_to_curve_p384_xmd_sha384_sswu(
1340       EC_group_p224(), p_p224.get(), kDST, sizeof(kDST), kMessage,
1341       sizeof(kMessage)));
1342   EXPECT_FALSE(EC_hash_to_curve_p384_xmd_sha384_sswu(
1343       EC_group_p224(), p_p384.get(), kDST, sizeof(kDST), kMessage,
1344       sizeof(kMessage)));
1345   EXPECT_FALSE(EC_hash_to_curve_p384_xmd_sha384_sswu(
1346       EC_group_p384(), p_p224.get(), kDST, sizeof(kDST), kMessage,
1347       sizeof(kMessage)));
1348 
1349   // Zero-length DSTs are not allowed.
1350   EXPECT_FALSE(ec_hash_to_curve_p384_xmd_sha384_sswu(
1351       EC_group_p384(), &raw, nullptr, 0, kMessage, sizeof(kMessage)));
1352 }
1353 
TEST(ECTest,HashToScalar)1354 TEST(ECTest, HashToScalar) {
1355   struct HashToScalarTest {
1356     int (*hash_to_scalar)(const EC_GROUP *group, EC_SCALAR *out,
1357                           const uint8_t *dst, size_t dst_len,
1358                           const uint8_t *msg, size_t msg_len);
1359     const EC_GROUP *group;
1360     const char *dst;
1361     const char *msg;
1362     const char *result_hex;
1363   };
1364   const HashToScalarTest kTests[] = {
1365       {&ec_hash_to_scalar_p384_xmd_sha512_draft07, EC_group_p384(),
1366        "P384_XMD:SHA-512_SCALAR_TEST", "",
1367        "9687acc2de56c3cf94c0e05b6811a21aa480092254ec0532bdce63"
1368        "140ecd340f09dc2d45d77e21fb0aa76f7707b8a676"},
1369       {&ec_hash_to_scalar_p384_xmd_sha512_draft07, EC_group_p384(),
1370        "P384_XMD:SHA-512_SCALAR_TEST", "abcdef0123456789",
1371        "8f8076022a68233cbcecaceae68c2068f132724f001caa78619eff"
1372        "1ffc58fa871db73fe9034fc9cf853c384ed34b5666"},
1373       {&ec_hash_to_scalar_p384_xmd_sha512_draft07, EC_group_p384(),
1374        "P384_XMD:SHA-512_SCALAR_TEST",
1375        "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1376        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1377        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1378        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1379        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1380        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1381        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1382        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1383        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1384        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
1385        "750f2fae7d2b2f41ac737d180c1d4363d85a1504798b4976d40921"
1386        "1ddb3651c13a5b4daba9975cdfce18336791131915"},
1387   };
1388 
1389   for (const auto &test : kTests) {
1390     SCOPED_TRACE(test.dst);
1391     SCOPED_TRACE(test.msg);
1392 
1393     EC_SCALAR scalar;
1394     ASSERT_TRUE(test.hash_to_scalar(
1395         test.group, &scalar, reinterpret_cast<const uint8_t *>(test.dst),
1396         strlen(test.dst), reinterpret_cast<const uint8_t *>(test.msg),
1397         strlen(test.msg)));
1398     uint8_t buf[EC_MAX_BYTES];
1399     size_t len;
1400     ec_scalar_to_bytes(test.group, buf, &len, &scalar);
1401     EXPECT_EQ(test.result_hex, EncodeHex(bssl::MakeConstSpan(buf, len)));
1402   }
1403 
1404   // hash-to-scalar functions should check for the wrong group.
1405   EC_SCALAR scalar;
1406   static const uint8_t kDST[] = {0, 1, 2, 3};
1407   static const uint8_t kMessage[] = {4, 5, 6, 7};
1408   EXPECT_FALSE(ec_hash_to_scalar_p384_xmd_sha512_draft07(
1409       EC_group_p224(), &scalar, kDST, sizeof(kDST), kMessage,
1410       sizeof(kMessage)));
1411 }
1412