Coverage Report

Created: 2025-09-05 06:13

/src/boringssl/crypto/fipsmodule/ec/ec.cc.inc
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
2
// Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
3
//
4
// Licensed under the Apache License, Version 2.0 (the "License");
5
// you may not use this file except in compliance with the License.
6
// You may obtain a copy of the License at
7
//
8
//     https://www.apache.org/licenses/LICENSE-2.0
9
//
10
// Unless required by applicable law or agreed to in writing, software
11
// distributed under the License is distributed on an "AS IS" BASIS,
12
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
// See the License for the specific language governing permissions and
14
// limitations under the License.
15
16
#include <openssl/ec.h>
17
18
#include <assert.h>
19
#include <string.h>
20
21
#include <iterator>
22
23
#include <openssl/bn.h>
24
#include <openssl/err.h>
25
#include <openssl/mem.h>
26
#include <openssl/nid.h>
27
28
#include "../../internal.h"
29
#include "../bn/internal.h"
30
#include "../delocate.h"
31
#include "internal.h"
32
33
#include "builtin_curves.h"
34
35
36
static void ec_point_free(EC_POINT *point, int free_group);
37
38
static void ec_group_init_static_mont(BN_MONT_CTX *mont, size_t num_words,
39
                                      const BN_ULONG *modulus,
40
120
                                      const BN_ULONG *rr, uint64_t n0) {
41
120
  bn_set_static_words(&mont->N, modulus, num_words);
42
120
  bn_set_static_words(&mont->RR, rr, num_words);
43
120
#if defined(OPENSSL_64_BIT)
44
120
  mont->n0[0] = n0;
45
#elif defined(OPENSSL_32_BIT)
46
  mont->n0[0] = (uint32_t)n0;
47
  mont->n0[1] = (uint32_t)(n0 >> 32);
48
#else
49
#error "unknown word length"
50
#endif
51
120
}
52
53
60
static void ec_group_set_a_minus3(EC_GROUP *group) {
54
60
  const EC_FELEM *one = ec_felem_one(group);
55
60
  group->a_is_minus3 = 1;
56
60
  ec_felem_neg(group, &group->a, one);
57
60
  ec_felem_sub(group, &group->a, &group->a, one);
58
60
  ec_felem_sub(group, &group->a, &group->a, one);
59
60
}
60
61
18
DEFINE_METHOD_FUNCTION(EC_GROUP, EC_group_p224) {
62
18
  out->curve_name = NID_secp224r1;
63
18
  out->comment = "NIST P-224";
64
  // 1.3.132.0.33
65
18
  static const uint8_t kOIDP224[] = {0x2b, 0x81, 0x04, 0x00, 0x21};
66
18
  OPENSSL_memcpy(out->oid, kOIDP224, sizeof(kOIDP224));
67
18
  out->oid_len = sizeof(kOIDP224);
68
69
18
  ec_group_init_static_mont(&out->field, std::size(kP224Field), kP224Field,
70
18
                            kP224FieldRR, kP224FieldN0);
71
18
  ec_group_init_static_mont(&out->order, std::size(kP224Order), kP224Order,
72
18
                            kP224OrderRR, kP224OrderN0);
73
74
18
#if defined(BORINGSSL_HAS_UINT128) && !defined(OPENSSL_SMALL)
75
18
  out->meth = EC_GFp_nistp224_method();
76
18
  OPENSSL_memcpy(out->generator.raw.X.words, kP224GX, sizeof(kP224GX));
77
18
  OPENSSL_memcpy(out->generator.raw.Y.words, kP224GY, sizeof(kP224GY));
78
18
  out->generator.raw.Z.words[0] = 1;
79
18
  OPENSSL_memcpy(out->b.words, kP224B, sizeof(kP224B));
80
#else
81
  out->meth = EC_GFp_mont_method();
82
  OPENSSL_memcpy(out->generator.raw.X.words, kP224MontGX, sizeof(kP224MontGX));
83
  OPENSSL_memcpy(out->generator.raw.Y.words, kP224MontGY, sizeof(kP224MontGY));
84
  OPENSSL_memcpy(out->generator.raw.Z.words, kP224FieldR, sizeof(kP224FieldR));
85
  OPENSSL_memcpy(out->b.words, kP224MontB, sizeof(kP224MontB));
86
#endif
87
18
  out->generator.group = out;
88
89
18
  ec_group_set_a_minus3(out);
90
18
  out->has_order = 1;
91
18
  out->field_greater_than_order = 1;
92
18
}
93
94
18
DEFINE_METHOD_FUNCTION(EC_GROUP, EC_group_p256) {
95
18
  out->curve_name = NID_X9_62_prime256v1;
96
18
  out->comment = "NIST P-256";
97
  // 1.2.840.10045.3.1.7
98
18
  static const uint8_t kOIDP256[] = {0x2a, 0x86, 0x48, 0xce,
99
18
                                     0x3d, 0x03, 0x01, 0x07};
100
18
  OPENSSL_memcpy(out->oid, kOIDP256, sizeof(kOIDP256));
101
18
  out->oid_len = sizeof(kOIDP256);
102
103
18
  ec_group_init_static_mont(&out->field, std::size(kP256Field), kP256Field,
104
18
                            kP256FieldRR, kP256FieldN0);
105
18
  ec_group_init_static_mont(&out->order, std::size(kP256Order), kP256Order,
106
18
                            kP256OrderRR, kP256OrderN0);
107
108
18
#if !defined(OPENSSL_NO_ASM) &&                              \
109
18
    (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \
110
18
    !defined(OPENSSL_SMALL)
111
18
  out->meth = EC_GFp_nistz256_method();
112
#else
113
  out->meth = EC_GFp_nistp256_method();
114
#endif
115
18
  out->generator.group = out;
116
18
  OPENSSL_memcpy(out->generator.raw.X.words, kP256MontGX, sizeof(kP256MontGX));
117
18
  OPENSSL_memcpy(out->generator.raw.Y.words, kP256MontGY, sizeof(kP256MontGY));
118
18
  OPENSSL_memcpy(out->generator.raw.Z.words, kP256FieldR, sizeof(kP256FieldR));
119
18
  OPENSSL_memcpy(out->b.words, kP256MontB, sizeof(kP256MontB));
120
121
18
  ec_group_set_a_minus3(out);
122
18
  out->has_order = 1;
123
18
  out->field_greater_than_order = 1;
124
18
}
125
126
12
DEFINE_METHOD_FUNCTION(EC_GROUP, EC_group_p384) {
127
12
  out->curve_name = NID_secp384r1;
128
12
  out->comment = "NIST P-384";
129
  // 1.3.132.0.34
130
12
  static const uint8_t kOIDP384[] = {0x2b, 0x81, 0x04, 0x00, 0x22};
131
12
  OPENSSL_memcpy(out->oid, kOIDP384, sizeof(kOIDP384));
132
12
  out->oid_len = sizeof(kOIDP384);
133
134
12
  ec_group_init_static_mont(&out->field, std::size(kP384Field), kP384Field,
135
12
                            kP384FieldRR, kP384FieldN0);
136
12
  ec_group_init_static_mont(&out->order, std::size(kP384Order), kP384Order,
137
12
                            kP384OrderRR, kP384OrderN0);
138
139
12
  out->meth = EC_GFp_mont_method();
140
12
  out->generator.group = out;
141
12
  OPENSSL_memcpy(out->generator.raw.X.words, kP384MontGX, sizeof(kP384MontGX));
142
12
  OPENSSL_memcpy(out->generator.raw.Y.words, kP384MontGY, sizeof(kP384MontGY));
143
12
  OPENSSL_memcpy(out->generator.raw.Z.words, kP384FieldR, sizeof(kP384FieldR));
144
12
  OPENSSL_memcpy(out->b.words, kP384MontB, sizeof(kP384MontB));
145
146
12
  ec_group_set_a_minus3(out);
147
12
  out->has_order = 1;
148
12
  out->field_greater_than_order = 1;
149
12
}
150
151
12
DEFINE_METHOD_FUNCTION(EC_GROUP, EC_group_p521) {
152
12
  out->curve_name = NID_secp521r1;
153
12
  out->comment = "NIST P-521";
154
  // 1.3.132.0.35
155
12
  static const uint8_t kOIDP521[] = {0x2b, 0x81, 0x04, 0x00, 0x23};
156
12
  OPENSSL_memcpy(out->oid, kOIDP521, sizeof(kOIDP521));
157
12
  out->oid_len = sizeof(kOIDP521);
158
159
12
  ec_group_init_static_mont(&out->field, std::size(kP521Field), kP521Field,
160
12
                            kP521FieldRR, kP521FieldN0);
161
12
  ec_group_init_static_mont(&out->order, std::size(kP521Order), kP521Order,
162
12
                            kP521OrderRR, kP521OrderN0);
163
164
12
  out->meth = EC_GFp_mont_method();
165
12
  out->generator.group = out;
166
12
  OPENSSL_memcpy(out->generator.raw.X.words, kP521MontGX, sizeof(kP521MontGX));
167
12
  OPENSSL_memcpy(out->generator.raw.Y.words, kP521MontGY, sizeof(kP521MontGY));
168
12
  OPENSSL_memcpy(out->generator.raw.Z.words, kP521FieldR, sizeof(kP521FieldR));
169
12
  OPENSSL_memcpy(out->b.words, kP521MontB, sizeof(kP521MontB));
170
171
12
  ec_group_set_a_minus3(out);
172
12
  out->has_order = 1;
173
12
  out->field_greater_than_order = 1;
174
12
}
175
176
EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
177
0
                                 const BIGNUM *b, BN_CTX *ctx) {
178
0
  if (BN_num_bytes(p) > EC_MAX_BYTES) {
179
0
    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD);
180
0
    return nullptr;
181
0
  }
182
183
0
  bssl::UniquePtr<BN_CTX> new_ctx;
184
0
  if (ctx == nullptr) {
185
0
    new_ctx.reset(BN_CTX_new());
186
0
    if (new_ctx == nullptr) {
187
0
      return nullptr;
188
0
    }
189
0
    ctx = new_ctx.get();
190
0
  }
191
192
  // Historically, |a| and |b| were not required to be fully reduced.
193
  // TODO(davidben): Can this be removed?
194
0
  bssl::BN_CTXScope scope(ctx);
195
0
  BIGNUM *a_reduced = BN_CTX_get(ctx);
196
0
  BIGNUM *b_reduced = BN_CTX_get(ctx);
197
0
  if (a_reduced == nullptr || b_reduced == nullptr ||
198
0
      !BN_nnmod(a_reduced, a, p, ctx) ||  //
199
0
      !BN_nnmod(b_reduced, b, p, ctx)) {
200
0
    return nullptr;
201
0
  }
202
203
0
  bssl::UniquePtr<EC_GROUP> ret(
204
0
      reinterpret_cast<EC_GROUP *>(OPENSSL_zalloc(sizeof(EC_GROUP))));
205
0
  if (ret == nullptr) {
206
0
    return nullptr;
207
0
  }
208
0
  ret->references = 1;
209
0
  ret->meth = EC_GFp_mont_method();
210
0
  bn_mont_ctx_init(&ret->field);
211
0
  bn_mont_ctx_init(&ret->order);
212
0
  ret->generator.group = ret.get();
213
0
  if (!ec_GFp_simple_group_set_curve(ret.get(), p, a_reduced, b_reduced, ctx)) {
214
0
    return nullptr;
215
0
  }
216
217
0
  return ret.release();
218
0
}
219
220
int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
221
0
                           const BIGNUM *order, const BIGNUM *cofactor) {
222
0
  if (group->curve_name != NID_undef || group->has_order ||
223
0
      generator->group != group) {
224
    // |EC_GROUP_set_generator| may only be used with |EC_GROUP|s returned by
225
    // |EC_GROUP_new_curve_GFp| and may only used once on each group.
226
    // |generator| must have been created from |EC_GROUP_new_curve_GFp|, not a
227
    // copy, so that |generator->group->generator| is set correctly.
228
0
    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
229
0
    return 0;
230
0
  }
231
232
0
  if (BN_num_bytes(order) > EC_MAX_BYTES) {
233
0
    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER);
234
0
    return 0;
235
0
  }
236
237
  // Require a cofactor of one for custom curves, which implies prime order.
238
0
  if (!BN_is_one(cofactor)) {
239
0
    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COFACTOR);
240
0
    return 0;
241
0
  }
242
243
  // Require that p < 2×order. This simplifies some ECDSA operations.
244
  //
245
  // Note any curve which did not satisfy this must have been invalid or use a
246
  // tiny prime (less than 17). See the proof in |field_element_to_scalar| in
247
  // the ECDSA implementation.
248
0
  bssl::UniquePtr<BIGNUM> tmp(BN_new());
249
0
  if (tmp == nullptr || !BN_lshift1(tmp.get(), order)) {
250
0
    return 0;
251
0
  }
252
0
  if (BN_cmp(tmp.get(), &group->field.N) <= 0) {
253
0
    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER);
254
0
    return 0;
255
0
  }
256
257
0
  EC_AFFINE affine;
258
0
  if (!ec_jacobian_to_affine(group, &affine, &generator->raw) ||
259
0
      !BN_MONT_CTX_set(&group->order, order, NULL)) {
260
0
    return 0;
261
0
  }
262
263
0
  group->field_greater_than_order = BN_cmp(&group->field.N, order) > 0;
264
0
  group->generator.raw.X = affine.X;
265
0
  group->generator.raw.Y = affine.Y;
266
  // |raw.Z| was set to 1 by |EC_GROUP_new_curve_GFp|.
267
0
  group->has_order = 1;
268
0
  return 1;
269
0
}
270
271
0
EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
272
0
  switch (nid) {
273
0
    case NID_secp224r1:
274
0
      return (EC_GROUP *)EC_group_p224();
275
0
    case NID_X9_62_prime256v1:
276
0
      return (EC_GROUP *)EC_group_p256();
277
0
    case NID_secp384r1:
278
0
      return (EC_GROUP *)EC_group_p384();
279
0
    case NID_secp521r1:
280
0
      return (EC_GROUP *)EC_group_p521();
281
0
    default:
282
0
      OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
283
0
      return NULL;
284
0
  }
285
0
}
286
287
288k
void EC_GROUP_free(EC_GROUP *group) {
288
288k
  if (group == NULL ||
289
      // Built-in curves are static.
290
288k
      group->curve_name != NID_undef ||
291
288k
      !CRYPTO_refcount_dec_and_test_zero(&group->references)) {
292
288k
    return;
293
288k
  }
294
295
0
  bn_mont_ctx_cleanup(&group->order);
296
0
  bn_mont_ctx_cleanup(&group->field);
297
0
  OPENSSL_free(group);
298
0
}
299
300
232k
EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) {
301
232k
  if (a == NULL ||
302
      // Built-in curves are static.
303
232k
      a->curve_name != NID_undef) {
304
232k
    return (EC_GROUP *)a;
305
232k
  }
306
307
  // Groups are logically immutable (but for |EC_GROUP_set_generator| which must
308
  // be called early on), so we simply take a reference.
309
0
  EC_GROUP *group = (EC_GROUP *)a;
310
0
  CRYPTO_refcount_inc(&group->references);
311
0
  return group;
312
232k
}
313
314
337k
int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
315
  // Note this function returns 0 if equal and non-zero otherwise.
316
337k
  if (a == b) {
317
337k
    return 0;
318
337k
  }
319
0
  if (a->curve_name != b->curve_name) {
320
0
    return 1;
321
0
  }
322
0
  if (a->curve_name != NID_undef) {
323
    // Built-in curves may be compared by curve name alone.
324
0
    return 0;
325
0
  }
326
327
  // |a| and |b| are both custom curves. We compare the entire curve
328
  // structure. If |a| or |b| is incomplete (due to legacy OpenSSL mistakes,
329
  // custom curve construction is sadly done in two parts) but otherwise not the
330
  // same object, we consider them always unequal.
331
0
  return a->meth != b->meth ||  //
332
0
         !a->has_order || !b->has_order ||
333
0
         BN_cmp(&a->order.N, &b->order.N) != 0 ||
334
0
         BN_cmp(&a->field.N, &b->field.N) != 0 ||
335
0
         !ec_felem_equal(a, &a->a, &b->a) ||  //
336
0
         !ec_felem_equal(a, &a->b, &b->b) ||
337
0
         !ec_GFp_simple_points_equal(a, &a->generator.raw, &b->generator.raw);
338
0
}
339
340
89
const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
341
89
  return group->has_order ? &group->generator : NULL;
342
89
}
343
344
50.2k
const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) {
345
50.2k
  assert(group->has_order);
346
50.2k
  return &group->order.N;
347
50.2k
}
348
349
0
int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
350
0
  if (BN_copy(order, EC_GROUP_get0_order(group)) == NULL) {
351
0
    return 0;
352
0
  }
353
0
  return 1;
354
0
}
355
356
55.0k
int EC_GROUP_order_bits(const EC_GROUP *group) {
357
55.0k
  return BN_num_bits(&group->order.N);
358
55.0k
}
359
360
int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
361
0
                          BN_CTX *ctx) {
362
  // All |EC_GROUP|s have cofactor 1.
363
0
  return BN_set_word(cofactor, 1);
364
0
}
365
366
int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
367
3.20k
                           BIGNUM *out_b, BN_CTX *ctx) {
368
3.20k
  return ec_GFp_simple_group_get_curve(group, out_p, out_a, out_b);
369
3.20k
}
370
371
16.0k
int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
372
373
28.8k
unsigned EC_GROUP_get_degree(const EC_GROUP *group) {
374
28.8k
  return BN_num_bits(&group->field.N);
375
28.8k
}
376
377
2.77k
const char *EC_curve_nid2nist(int nid) {
378
2.77k
  switch (nid) {
379
1.61k
    case NID_secp224r1:
380
1.61k
      return "P-224";
381
141
    case NID_X9_62_prime256v1:
382
141
      return "P-256";
383
769
    case NID_secp384r1:
384
769
      return "P-384";
385
250
    case NID_secp521r1:
386
250
      return "P-521";
387
2.77k
  }
388
0
  return NULL;
389
2.77k
}
390
391
0
int EC_curve_nist2nid(const char *name) {
392
0
  if (strcmp(name, "P-224") == 0) {
393
0
    return NID_secp224r1;
394
0
  }
395
0
  if (strcmp(name, "P-256") == 0) {
396
0
    return NID_X9_62_prime256v1;
397
0
  }
398
0
  if (strcmp(name, "P-384") == 0) {
399
0
    return NID_secp384r1;
400
0
  }
401
0
  if (strcmp(name, "P-521") == 0) {
402
0
    return NID_secp521r1;
403
0
  }
404
0
  return NID_undef;
405
0
}
406
407
175k
EC_POINT *EC_POINT_new(const EC_GROUP *group) {
408
175k
  if (group == NULL) {
409
0
    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
410
0
    return NULL;
411
0
  }
412
413
175k
  EC_POINT *ret = reinterpret_cast<EC_POINT *>(OPENSSL_malloc(sizeof *ret));
414
175k
  if (ret == NULL) {
415
0
    return NULL;
416
0
  }
417
418
175k
  ret->group = EC_GROUP_dup(group);
419
175k
  ec_GFp_simple_point_init(&ret->raw);
420
175k
  return ret;
421
175k
}
422
423
228k
static void ec_point_free(EC_POINT *point, int free_group) {
424
228k
  if (!point) {
425
52.7k
    return;
426
52.7k
  }
427
175k
  if (free_group) {
428
175k
    EC_GROUP_free(point->group);
429
175k
  }
430
175k
  OPENSSL_free(point);
431
175k
}
432
433
228k
void EC_POINT_free(EC_POINT *point) {
434
228k
  ec_point_free(point, 1 /* free group */);
435
228k
}
436
437
0
void EC_POINT_clear_free(EC_POINT *point) { EC_POINT_free(point); }
438
439
31.7k
int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
440
31.7k
  if (EC_GROUP_cmp(dest->group, src->group, NULL) != 0) {
441
0
    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
442
0
    return 0;
443
0
  }
444
31.7k
  if (dest == src) {
445
0
    return 1;
446
0
  }
447
31.7k
  ec_GFp_simple_point_copy(&dest->raw, &src->raw);
448
31.7k
  return 1;
449
31.7k
}
450
451
31.7k
EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
452
31.7k
  if (a == NULL) {
453
0
    return NULL;
454
0
  }
455
456
31.7k
  EC_POINT *ret = EC_POINT_new(group);
457
31.7k
  if (ret == NULL || !EC_POINT_copy(ret, a)) {
458
0
    EC_POINT_free(ret);
459
0
    return NULL;
460
0
  }
461
462
31.7k
  return ret;
463
31.7k
}
464
465
0
int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
466
0
  if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
467
0
    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
468
0
    return 0;
469
0
  }
470
0
  ec_GFp_simple_point_set_to_infinity(group, &point->raw);
471
0
  return 1;
472
0
}
473
474
1.72k
int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
475
1.72k
  if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
476
0
    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
477
0
    return 0;
478
0
  }
479
1.72k
  return ec_GFp_simple_is_at_infinity(group, &point->raw);
480
1.72k
}
481
482
int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
483
1.72k
                         BN_CTX *ctx) {
484
1.72k
  if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
485
0
    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
486
0
    return 0;
487
0
  }
488
1.72k
  return ec_GFp_simple_is_on_curve(group, &point->raw);
489
1.72k
}
490
491
int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
492
0
                 BN_CTX *ctx) {
493
0
  if (EC_GROUP_cmp(group, a->group, NULL) != 0 ||
494
0
      EC_GROUP_cmp(group, b->group, NULL) != 0) {
495
0
    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
496
0
    return -1;
497
0
  }
498
499
  // Note |EC_POINT_cmp| returns zero for equality and non-zero for inequality.
500
0
  return ec_GFp_simple_points_equal(group, &a->raw, &b->raw) ? 0 : 1;
501
0
}
502
503
int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
504
                                        const EC_POINT *point, BIGNUM *x,
505
28.9k
                                        BIGNUM *y, BN_CTX *ctx) {
506
28.9k
  if (group->meth->point_get_affine_coordinates == 0) {
507
0
    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
508
0
    return 0;
509
0
  }
510
28.9k
  if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
511
0
    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
512
0
    return 0;
513
0
  }
514
28.9k
  EC_FELEM x_felem, y_felem;
515
28.9k
  if (!group->meth->point_get_affine_coordinates(group, &point->raw,
516
28.9k
                                                 x == NULL ? NULL : &x_felem,
517
28.9k
                                                 y == NULL ? NULL : &y_felem) ||
518
28.9k
      (x != NULL && !ec_felem_to_bignum(group, x, &x_felem)) ||
519
28.9k
      (y != NULL && !ec_felem_to_bignum(group, y, &y_felem))) {
520
4
    return 0;
521
4
  }
522
28.9k
  return 1;
523
28.9k
}
524
525
int EC_POINT_get_affine_coordinates(const EC_GROUP *group,
526
                                    const EC_POINT *point, BIGNUM *x, BIGNUM *y,
527
0
                                    BN_CTX *ctx) {
528
0
  return EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx);
529
0
}
530
531
void ec_affine_to_jacobian(const EC_GROUP *group, EC_JACOBIAN *out,
532
61.9k
                           const EC_AFFINE *p) {
533
61.9k
  out->X = p->X;
534
61.9k
  out->Y = p->Y;
535
61.9k
  out->Z = *ec_felem_one(group);
536
61.9k
}
537
538
int ec_jacobian_to_affine(const EC_GROUP *group, EC_AFFINE *out,
539
32.4k
                          const EC_JACOBIAN *p) {
540
32.4k
  return group->meth->point_get_affine_coordinates(group, p, &out->X, &out->Y);
541
32.4k
}
542
543
int ec_jacobian_to_affine_batch(const EC_GROUP *group, EC_AFFINE *out,
544
0
                                const EC_JACOBIAN *in, size_t num) {
545
0
  if (group->meth->jacobian_to_affine_batch == NULL) {
546
0
    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
547
0
    return 0;
548
0
  }
549
0
  return group->meth->jacobian_to_affine_batch(group, out, in, num);
550
0
}
551
552
int ec_point_set_affine_coordinates(const EC_GROUP *group, EC_AFFINE *out,
553
81.5k
                                    const EC_FELEM *x, const EC_FELEM *y) {
554
81.5k
  void (*const felem_mul)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a,
555
81.5k
                          const EC_FELEM *b) = group->meth->felem_mul;
556
81.5k
  void (*const felem_sqr)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a) =
557
81.5k
      group->meth->felem_sqr;
558
559
  // Check if the point is on the curve.
560
81.5k
  EC_FELEM lhs, rhs;
561
81.5k
  felem_sqr(group, &lhs, y);                   // lhs = y^2
562
81.5k
  felem_sqr(group, &rhs, x);                   // rhs = x^2
563
81.5k
  ec_felem_add(group, &rhs, &rhs, &group->a);  // rhs = x^2 + a
564
81.5k
  felem_mul(group, &rhs, &rhs, x);             // rhs = x^3 + ax
565
81.5k
  ec_felem_add(group, &rhs, &rhs, &group->b);  // rhs = x^3 + ax + b
566
81.5k
  if (!ec_felem_equal(group, &lhs, &rhs)) {
567
19.6k
    OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
568
    // In the event of an error, defend against the caller not checking the
569
    // return value by setting a known safe value. Note this may not be possible
570
    // if the caller is in the process of constructing an arbitrary group and
571
    // the generator is missing.
572
19.6k
    if (group->has_order) {
573
19.6k
      out->X = group->generator.raw.X;
574
19.6k
      out->Y = group->generator.raw.Y;
575
19.6k
    }
576
19.6k
    return 0;
577
19.6k
  }
578
579
61.9k
  out->X = *x;
580
61.9k
  out->Y = *y;
581
61.9k
  return 1;
582
81.5k
}
583
584
int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
585
                                        const BIGNUM *x, const BIGNUM *y,
586
2.63k
                                        BN_CTX *ctx) {
587
2.63k
  if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
588
0
    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
589
0
    return 0;
590
0
  }
591
592
2.63k
  if (x == NULL || y == NULL) {
593
0
    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
594
0
    return 0;
595
0
  }
596
597
2.63k
  EC_FELEM x_felem, y_felem;
598
2.63k
  EC_AFFINE affine;
599
2.63k
  if (!ec_bignum_to_felem(group, &x_felem, x) ||
600
2.63k
      !ec_bignum_to_felem(group, &y_felem, y) ||
601
2.63k
      !ec_point_set_affine_coordinates(group, &affine, &x_felem, &y_felem)) {
602
    // In the event of an error, defend against the caller not checking the
603
    // return value by setting a known safe value.
604
5
    ec_set_to_safe_point(group, &point->raw);
605
5
    return 0;
606
5
  }
607
608
2.62k
  ec_affine_to_jacobian(group, &point->raw, &affine);
609
2.62k
  return 1;
610
2.63k
}
611
612
int EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
613
                                    const BIGNUM *x, const BIGNUM *y,
614
0
                                    BN_CTX *ctx) {
615
0
  return EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx);
616
0
}
617
618
int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
619
0
                 const EC_POINT *b, BN_CTX *ctx) {
620
0
  if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
621
0
      EC_GROUP_cmp(group, a->group, NULL) != 0 ||
622
0
      EC_GROUP_cmp(group, b->group, NULL) != 0) {
623
0
    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
624
0
    return 0;
625
0
  }
626
0
  group->meth->add(group, &r->raw, &a->raw, &b->raw);
627
0
  return 1;
628
0
}
629
630
int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
631
0
                 BN_CTX *ctx) {
632
0
  if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
633
0
      EC_GROUP_cmp(group, a->group, NULL) != 0) {
634
0
    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
635
0
    return 0;
636
0
  }
637
0
  group->meth->dbl(group, &r->raw, &a->raw);
638
0
  return 1;
639
0
}
640
641
642
0
int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
643
0
  if (EC_GROUP_cmp(group, a->group, NULL) != 0) {
644
0
    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
645
0
    return 0;
646
0
  }
647
0
  ec_GFp_simple_invert(group, &a->raw);
648
0
  return 1;
649
0
}
650
651
static int arbitrary_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
652
58.5k
                                      const BIGNUM *in, BN_CTX *ctx) {
653
58.5k
  if (ec_bignum_to_scalar(group, out, in)) {
654
58.0k
    return 1;
655
58.0k
  }
656
657
477
  ERR_clear_error();
658
659
  // This is an unusual input, so we do not guarantee constant-time processing.
660
477
  bssl::BN_CTXScope scope(ctx);
661
477
  BIGNUM *tmp = BN_CTX_get(ctx);
662
477
  return tmp != nullptr && BN_nnmod(tmp, in, EC_GROUP_get0_order(group), ctx) &&
663
477
         ec_bignum_to_scalar(group, out, tmp);
664
58.5k
}
665
666
int ec_point_mul_no_self_test(const EC_GROUP *group, EC_POINT *r,
667
                              const BIGNUM *g_scalar, const EC_POINT *p,
668
58.5k
                              const BIGNUM *p_scalar, BN_CTX *ctx) {
669
  // Previously, this function set |r| to the point at infinity if there was
670
  // nothing to multiply. But, nobody should be calling this function with
671
  // nothing to multiply in the first place.
672
58.5k
  if ((g_scalar == NULL && p_scalar == NULL) ||
673
58.5k
      (p == NULL) != (p_scalar == NULL)) {
674
0
    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
675
0
    return 0;
676
0
  }
677
678
58.5k
  if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
679
58.5k
      (p != NULL && EC_GROUP_cmp(group, p->group, NULL) != 0)) {
680
0
    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
681
0
    return 0;
682
0
  }
683
684
58.5k
  bssl::UniquePtr<BN_CTX> new_ctx;
685
58.5k
  if (ctx == NULL) {
686
58.5k
    new_ctx.reset(BN_CTX_new());
687
58.5k
    if (new_ctx == NULL) {
688
0
      return 0;
689
0
    }
690
58.5k
    ctx = new_ctx.get();
691
58.5k
  }
692
693
  // If both |g_scalar| and |p_scalar| are non-NULL,
694
  // |ec_point_mul_scalar_public| would share the doublings between the two
695
  // products, which would be more efficient. However, we conservatively assume
696
  // the caller needs a constant-time operation. (ECDSA verification does not
697
  // use this function.)
698
  //
699
  // Previously, the low-level constant-time multiplication function aligned
700
  // with this function's calling convention, but this was misleading. Curves
701
  // which combined the two multiplications did not avoid the doubling case
702
  // in the incomplete addition formula and were not constant-time.
703
704
58.5k
  if (g_scalar != NULL) {
705
29.6k
    EC_SCALAR scalar;
706
29.6k
    if (!arbitrary_bignum_to_scalar(group, &scalar, g_scalar, ctx) ||
707
29.6k
        !ec_point_mul_scalar_base(group, &r->raw, &scalar)) {
708
0
      return 0;
709
0
    }
710
29.6k
  }
711
712
58.5k
  if (p_scalar != NULL) {
713
28.8k
    EC_SCALAR scalar;
714
28.8k
    EC_JACOBIAN tmp;
715
28.8k
    if (!arbitrary_bignum_to_scalar(group, &scalar, p_scalar, ctx) ||
716
28.8k
        !ec_point_mul_scalar(group, &tmp, &p->raw, &scalar)) {
717
0
      return 0;
718
0
    }
719
28.8k
    if (g_scalar == NULL) {
720
28.8k
      OPENSSL_memcpy(&r->raw, &tmp, sizeof(EC_JACOBIAN));
721
28.8k
    } else {
722
0
      group->meth->add(group, &r->raw, &r->raw, &tmp);
723
0
    }
724
28.8k
  }
725
726
58.5k
  return 1;
727
58.5k
}
728
729
int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
730
58.5k
                 const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) {
731
58.5k
  boringssl_ensure_ecc_self_test();
732
733
58.5k
  return ec_point_mul_no_self_test(group, r, g_scalar, p, p_scalar, ctx);
734
58.5k
}
735
736
int ec_point_mul_scalar_public(const EC_GROUP *group, EC_JACOBIAN *r,
737
                               const EC_SCALAR *g_scalar, const EC_JACOBIAN *p,
738
5.46k
                               const EC_SCALAR *p_scalar) {
739
5.46k
  if (g_scalar == NULL || p_scalar == NULL || p == NULL) {
740
0
    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
741
0
    return 0;
742
0
  }
743
744
5.46k
  if (group->meth->mul_public == NULL) {
745
901
    return group->meth->mul_public_batch(group, r, g_scalar, p, p_scalar, 1);
746
901
  }
747
748
4.56k
  group->meth->mul_public(group, r, g_scalar, p, p_scalar);
749
4.56k
  return 1;
750
5.46k
}
751
752
int ec_point_mul_scalar_public_batch(const EC_GROUP *group, EC_JACOBIAN *r,
753
                                     const EC_SCALAR *g_scalar,
754
                                     const EC_JACOBIAN *points,
755
0
                                     const EC_SCALAR *scalars, size_t num) {
756
0
  if (group->meth->mul_public_batch == NULL) {
757
0
    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
758
0
    return 0;
759
0
  }
760
761
0
  return group->meth->mul_public_batch(group, r, g_scalar, points, scalars,
762
0
                                       num);
763
0
}
764
765
int ec_point_mul_scalar(const EC_GROUP *group, EC_JACOBIAN *r,
766
28.8k
                        const EC_JACOBIAN *p, const EC_SCALAR *scalar) {
767
28.8k
  if (p == NULL || scalar == NULL) {
768
0
    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
769
0
    return 0;
770
0
  }
771
772
28.8k
  group->meth->mul(group, r, p, scalar);
773
774
  // Check the result is on the curve to defend against fault attacks or bugs.
775
  // This has negligible cost compared to the multiplication.
776
28.8k
  if (!ec_GFp_simple_is_on_curve(group, r)) {
777
0
    OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
778
0
    return 0;
779
0
  }
780
781
28.8k
  return 1;
782
28.8k
}
783
784
int ec_point_mul_scalar_base(const EC_GROUP *group, EC_JACOBIAN *r,
785
32.5k
                             const EC_SCALAR *scalar) {
786
32.5k
  if (scalar == NULL) {
787
0
    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
788
0
    return 0;
789
0
  }
790
791
32.5k
  group->meth->mul_base(group, r, scalar);
792
793
  // Check the result is on the curve to defend against fault attacks or bugs.
794
  // This has negligible cost compared to the multiplication. This can only
795
  // happen on bug or CPU fault, so it okay to leak this. The alternative would
796
  // be to proceed with bad data.
797
32.5k
  if (!constant_time_declassify_int(ec_GFp_simple_is_on_curve(group, r))) {
798
0
    OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
799
0
    return 0;
800
0
  }
801
802
32.5k
  return 1;
803
32.5k
}
804
805
int ec_point_mul_scalar_batch(const EC_GROUP *group, EC_JACOBIAN *r,
806
                              const EC_JACOBIAN *p0, const EC_SCALAR *scalar0,
807
                              const EC_JACOBIAN *p1, const EC_SCALAR *scalar1,
808
0
                              const EC_JACOBIAN *p2, const EC_SCALAR *scalar2) {
809
0
  if (group->meth->mul_batch == NULL) {
810
0
    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
811
0
    return 0;
812
0
  }
813
814
0
  group->meth->mul_batch(group, r, p0, scalar0, p1, scalar1, p2, scalar2);
815
816
  // Check the result is on the curve to defend against fault attacks or bugs.
817
  // This has negligible cost compared to the multiplication.
818
0
  if (!ec_GFp_simple_is_on_curve(group, r)) {
819
0
    OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
820
0
    return 0;
821
0
  }
822
823
0
  return 1;
824
0
}
825
826
int ec_init_precomp(const EC_GROUP *group, EC_PRECOMP *out,
827
0
                    const EC_JACOBIAN *p) {
828
0
  if (group->meth->init_precomp == NULL) {
829
0
    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
830
0
    return 0;
831
0
  }
832
833
0
  return group->meth->init_precomp(group, out, p);
834
0
}
835
836
int ec_point_mul_scalar_precomp(const EC_GROUP *group, EC_JACOBIAN *r,
837
                                const EC_PRECOMP *p0, const EC_SCALAR *scalar0,
838
                                const EC_PRECOMP *p1, const EC_SCALAR *scalar1,
839
                                const EC_PRECOMP *p2,
840
0
                                const EC_SCALAR *scalar2) {
841
0
  if (group->meth->mul_precomp == NULL) {
842
0
    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
843
0
    return 0;
844
0
  }
845
846
0
  group->meth->mul_precomp(group, r, p0, scalar0, p1, scalar1, p2, scalar2);
847
848
  // Check the result is on the curve to defend against fault attacks or bugs.
849
  // This has negligible cost compared to the multiplication.
850
0
  if (!ec_GFp_simple_is_on_curve(group, r)) {
851
0
    OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
852
0
    return 0;
853
0
  }
854
855
0
  return 1;
856
0
}
857
858
void ec_point_select(const EC_GROUP *group, EC_JACOBIAN *out, BN_ULONG mask,
859
134M
                     const EC_JACOBIAN *a, const EC_JACOBIAN *b) {
860
134M
  ec_felem_select(group, &out->X, mask, &a->X, &b->X);
861
134M
  ec_felem_select(group, &out->Y, mask, &a->Y, &b->Y);
862
134M
  ec_felem_select(group, &out->Z, mask, &a->Z, &b->Z);
863
134M
}
864
865
void ec_affine_select(const EC_GROUP *group, EC_AFFINE *out, BN_ULONG mask,
866
0
                      const EC_AFFINE *a, const EC_AFFINE *b) {
867
0
  ec_felem_select(group, &out->X, mask, &a->X, &b->X);
868
0
  ec_felem_select(group, &out->Y, mask, &a->Y, &b->Y);
869
0
}
870
871
void ec_precomp_select(const EC_GROUP *group, EC_PRECOMP *out, BN_ULONG mask,
872
0
                       const EC_PRECOMP *a, const EC_PRECOMP *b) {
873
0
  static_assert(sizeof(out->comb) == sizeof(*out),
874
0
                "out->comb does not span the entire structure");
875
0
  for (size_t i = 0; i < std::size(out->comb); i++) {
876
0
    ec_affine_select(group, &out->comb[i], mask, &a->comb[i], &b->comb[i]);
877
0
  }
878
0
}
879
880
int ec_cmp_x_coordinate(const EC_GROUP *group, const EC_JACOBIAN *p,
881
5.46k
                        const EC_SCALAR *r) {
882
5.46k
  return group->meth->cmp_x_coordinate(group, p, r);
883
5.46k
}
884
885
int ec_get_x_coordinate_as_scalar(const EC_GROUP *group, EC_SCALAR *out,
886
12
                                  const EC_JACOBIAN *p) {
887
12
  uint8_t bytes[EC_MAX_BYTES];
888
12
  size_t len;
889
12
  if (!ec_get_x_coordinate_as_bytes(group, bytes, &len, sizeof(bytes), p)) {
890
0
    return 0;
891
0
  }
892
893
  // The x-coordinate is bounded by p, but we need a scalar, bounded by the
894
  // order. These may not have the same size. However, we must have p < 2×order,
895
  // assuming p is not tiny (p >= 17).
896
  //
897
  // Thus |bytes| will fit in |order.width + 1| words, and we can reduce by
898
  // performing at most one subtraction.
899
  //
900
  // Proof: We only work with prime order curves, so the number of points on
901
  // the curve is the order. Thus Hasse's theorem gives:
902
  //
903
  //     |order - (p + 1)| <= 2×sqrt(p)
904
  //         p + 1 - order <= 2×sqrt(p)
905
  //     p + 1 - 2×sqrt(p) <= order
906
  //       p + 1 - 2×(p/4)  < order       (p/4 > sqrt(p) for p >= 17)
907
  //         p/2 < p/2 + 1  < order
908
  //                     p  < 2×order
909
  //
910
  // Additionally, one can manually check this property for built-in curves. It
911
  // is enforced for legacy custom curves in |EC_GROUP_set_generator|.
912
12
  const BIGNUM *order = EC_GROUP_get0_order(group);
913
12
  BN_ULONG words[EC_MAX_WORDS + 1] = {0};
914
12
  bn_big_endian_to_words(words, order->width + 1, bytes, len);
915
12
  bn_reduce_once(out->words, words, /*carry=*/words[order->width], order->d,
916
12
                 order->width);
917
12
  return 1;
918
12
}
919
920
int ec_get_x_coordinate_as_bytes(const EC_GROUP *group, uint8_t *out,
921
                                 size_t *out_len, size_t max_out,
922
12
                                 const EC_JACOBIAN *p) {
923
12
  size_t len = BN_num_bytes(&group->field.N);
924
12
  assert(len <= EC_MAX_BYTES);
925
12
  if (max_out < len) {
926
0
    OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
927
0
    return 0;
928
0
  }
929
930
12
  EC_FELEM x;
931
12
  if (!group->meth->point_get_affine_coordinates(group, p, &x, NULL)) {
932
0
    return 0;
933
0
  }
934
935
12
  ec_felem_to_bytes(group, out, out_len, &x);
936
12
  *out_len = len;
937
12
  return 1;
938
12
}
939
940
19.9k
void ec_set_to_safe_point(const EC_GROUP *group, EC_JACOBIAN *out) {
941
19.9k
  if (group->has_order) {
942
19.9k
    ec_GFp_simple_point_copy(out, &group->generator.raw);
943
19.9k
  } else {
944
    // The generator can be missing if the caller is in the process of
945
    // constructing an arbitrary group. In this case, we give up and use the
946
    // point at infinity.
947
0
    ec_GFp_simple_point_set_to_infinity(group, out);
948
0
  }
949
19.9k
}
950
951
0
void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {}
952
953
0
int EC_GROUP_get_asn1_flag(const EC_GROUP *group) {
954
0
  return OPENSSL_EC_NAMED_CURVE;
955
0
}
956
957
0
const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) {
958
  // This function exists purely to give callers a way to call
959
  // |EC_METHOD_get_field_type|. cryptography.io crashes if |EC_GROUP_method_of|
960
  // returns NULL, so return some other garbage pointer.
961
0
  return (const EC_METHOD *)0x12340000;
962
0
}
963
964
0
int EC_METHOD_get_field_type(const EC_METHOD *meth) {
965
0
  return NID_X9_62_prime_field;
966
0
}
967
968
void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
969
0
                                        point_conversion_form_t form) {
970
0
  if (form != POINT_CONVERSION_UNCOMPRESSED) {
971
0
    abort();
972
0
  }
973
0
}