/*
- * Copyright 2010-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
* limitations under the License.
*/
+/*
+ * ECDSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
/*
* A 64-bit implementation of the NIST P-224 elliptic curve point multiplication
*
*/
#include <openssl/opensslconf.h>
-#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
-NON_EMPTY_TRANSLATION_UNIT
-#else
-# include <stdint.h>
-# include <string.h>
-# include <openssl/err.h>
-# include "ec_lcl.h"
+#include <stdint.h>
+#include <string.h>
+#include <openssl/err.h>
+#include "ec_local.h"
-# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+#if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16
/* even with gcc, the typedef won't work for 32-bit platforms */
typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit
* platforms */
-# else
-# error "Need GCC 3.1 or later to define type uint128_t"
-# endif
+#else
+# error "Your compiler doesn't appear to support 128-bit integer types"
+#endif
typedef uint8_t u8;
typedef uint64_t u64;
-typedef int64_t s64;
/******************************************************************************/
/*-
*/
typedef uint64_t limb;
+typedef uint64_t limb_aX __attribute((__aligned__(1)));
typedef uint128_t widelimb;
typedef limb felem[4];
typedef widelimb widefelem[7];
/*
- * Field element represented as a byte arrary. 28*8 = 224 bits is also the
+ * Field element represented as a byte array. 28*8 = 224 bits is also the
* group order size for the elliptic curve, and we also use this type for
* scalars for point multiplication.
*/
static const EC_METHOD ret = {
EC_FLAGS_DEFAULT_OCT,
NID_X9_62_prime_field,
- ec_GFp_nistp224_group_init,
- ec_GFp_simple_group_finish,
- ec_GFp_simple_group_clear_finish,
- ec_GFp_nist_group_copy,
- ec_GFp_nistp224_group_set_curve,
- ec_GFp_simple_group_get_curve,
- ec_GFp_simple_group_get_degree,
- ec_group_simple_order_bits,
- ec_GFp_simple_group_check_discriminant,
- ec_GFp_simple_point_init,
- ec_GFp_simple_point_finish,
- ec_GFp_simple_point_clear_finish,
- ec_GFp_simple_point_copy,
- ec_GFp_simple_point_set_to_infinity,
- ec_GFp_simple_set_Jprojective_coordinates_GFp,
- ec_GFp_simple_get_Jprojective_coordinates_GFp,
- ec_GFp_simple_point_set_affine_coordinates,
- ec_GFp_nistp224_point_get_affine_coordinates,
+ ossl_ec_GFp_nistp224_group_init,
+ ossl_ec_GFp_simple_group_finish,
+ ossl_ec_GFp_simple_group_clear_finish,
+ ossl_ec_GFp_nist_group_copy,
+ ossl_ec_GFp_nistp224_group_set_curve,
+ ossl_ec_GFp_simple_group_get_curve,
+ ossl_ec_GFp_simple_group_get_degree,
+ ossl_ec_group_simple_order_bits,
+ ossl_ec_GFp_simple_group_check_discriminant,
+ ossl_ec_GFp_simple_point_init,
+ ossl_ec_GFp_simple_point_finish,
+ ossl_ec_GFp_simple_point_clear_finish,
+ ossl_ec_GFp_simple_point_copy,
+ ossl_ec_GFp_simple_point_set_to_infinity,
+ ossl_ec_GFp_simple_point_set_affine_coordinates,
+ ossl_ec_GFp_nistp224_point_get_affine_coordinates,
0 /* point_set_compressed_coordinates */ ,
0 /* point2oct */ ,
0 /* oct2point */ ,
- ec_GFp_simple_add,
- ec_GFp_simple_dbl,
- ec_GFp_simple_invert,
- ec_GFp_simple_is_at_infinity,
- ec_GFp_simple_is_on_curve,
- ec_GFp_simple_cmp,
- ec_GFp_simple_make_affine,
- ec_GFp_simple_points_make_affine,
- ec_GFp_nistp224_points_mul,
- ec_GFp_nistp224_precompute_mult,
- ec_GFp_nistp224_have_precompute_mult,
- ec_GFp_nist_field_mul,
- ec_GFp_nist_field_sqr,
+ ossl_ec_GFp_simple_add,
+ ossl_ec_GFp_simple_dbl,
+ ossl_ec_GFp_simple_invert,
+ ossl_ec_GFp_simple_is_at_infinity,
+ ossl_ec_GFp_simple_is_on_curve,
+ ossl_ec_GFp_simple_cmp,
+ ossl_ec_GFp_simple_make_affine,
+ ossl_ec_GFp_simple_points_make_affine,
+ ossl_ec_GFp_nistp224_points_mul,
+ ossl_ec_GFp_nistp224_precompute_mult,
+ ossl_ec_GFp_nistp224_have_precompute_mult,
+ ossl_ec_GFp_nist_field_mul,
+ ossl_ec_GFp_nist_field_sqr,
0 /* field_div */ ,
+ ossl_ec_GFp_simple_field_inv,
0 /* field_encode */ ,
0 /* field_decode */ ,
0, /* field_set_to_one */
- ec_key_simple_priv2oct,
- ec_key_simple_oct2priv,
+ ossl_ec_key_simple_priv2oct,
+ ossl_ec_key_simple_oct2priv,
0, /* set private */
- ec_key_simple_generate_key,
- ec_key_simple_check_key,
- ec_key_simple_generate_public_key,
+ ossl_ec_key_simple_generate_key,
+ ossl_ec_key_simple_check_key,
+ ossl_ec_key_simple_generate_public_key,
0, /* keycopy */
0, /* keyfinish */
- ecdh_simple_compute_key
+ ossl_ecdh_simple_compute_key,
+ ossl_ecdsa_simple_sign_setup,
+ ossl_ecdsa_simple_sign_sig,
+ ossl_ecdsa_simple_verify_sig,
+ 0, /* field_inverse_mod_ord */
+ 0, /* blind_coordinates */
+ 0, /* ladder_pre */
+ 0, /* ladder_step */
+ 0 /* ladder_post */
};
return &ret;
*/
static void bin28_to_felem(felem out, const u8 in[28])
{
- out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff;
- out[1] = (*((const uint64_t *)(in + 7))) & 0x00ffffffffffffff;
- out[2] = (*((const uint64_t *)(in + 14))) & 0x00ffffffffffffff;
- out[3] = (*((const uint64_t *)(in+20))) >> 8;
+ out[0] = *((const limb *)(in)) & 0x00ffffffffffffff;
+ out[1] = (*((const limb_aX *)(in + 7))) & 0x00ffffffffffffff;
+ out[2] = (*((const limb_aX *)(in + 14))) & 0x00ffffffffffffff;
+ out[3] = (*((const limb_aX *)(in + 20))) >> 8;
}
static void felem_to_bin28(u8 out[28], const felem in)
}
}
-/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
-static void flip_endian(u8 *out, const u8 *in, unsigned len)
-{
- unsigned i;
- for (i = 0; i < len; ++i)
- out[i] = in[len - 1 - i];
-}
-
/* From OpenSSL BIGNUM to internal representation */
static int BN_to_felem(felem out, const BIGNUM *bn)
{
- felem_bytearray b_in;
felem_bytearray b_out;
- unsigned num_bytes;
+ int num_bytes;
- /* BN_bn2bin eats leading zeroes */
- memset(b_out, 0, sizeof(b_out));
- num_bytes = BN_num_bytes(bn);
- if (num_bytes > sizeof b_out) {
- ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ if (BN_is_negative(bn)) {
+ ERR_raise(ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
- if (BN_is_negative(bn)) {
- ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ num_bytes = BN_bn2lebinpad(bn, b_out, sizeof(b_out));
+ if (num_bytes < 0) {
+ ERR_raise(ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
- num_bytes = BN_bn2bin(bn, b_in);
- flip_endian(b_out, b_in, num_bytes);
bin28_to_felem(out, b_out);
return 1;
}
/* From internal representation to OpenSSL BIGNUM */
static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
{
- felem_bytearray b_in, b_out;
- felem_to_bin28(b_in, in);
- flip_endian(b_out, b_in, sizeof b_out);
- return BN_bin2bn(b_out, sizeof b_out, out);
+ felem_bytearray b_out;
+ felem_to_bin28(b_out, in);
+ return BN_lebin2bn(b_out, sizeof(b_out), out);
}
/******************************************************************************/
out[3] += in[3];
}
-/* Get negative value: out = -in */
-/* Assumes in[i] < 2^57 */
-static void felem_neg(felem out, const felem in)
-{
- static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2);
- static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2);
- static const limb two58m42m2 = (((limb) 1) << 58) -
- (((limb) 1) << 42) - (((limb) 1) << 2);
-
- /* Set to 0 mod 2^224-2^96+1 to ensure out > in */
- out[0] = two58p2 - in[0];
- out[1] = two58m42m2 - in[1];
- out[2] = two58m2 - in[2];
- out[3] = two58m2 - in[3];
-}
-
/* Subtract field elements: out -= in */
/* Assumes in[i] < 2^57 */
static void felem_diff(felem out, const felem in)
out[3] = tmp[3];
}
+/*
+ * Get negative value: out = -in
+ * Requires in[i] < 2^63,
+ * ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16
+ */
+static void felem_neg(felem out, const felem in)
+{
+ widefelem tmp;
+
+ memset(tmp, 0, sizeof(tmp));
+ felem_diff_128_64(tmp, in);
+ felem_reduce(out, tmp);
+}
+
/*
* Zero-check: returns 1 if input is 0, and 0 otherwise. We know that field
* elements are reduced to in < 2^225, so we only need to check three cases:
* Double an elliptic curve point:
* (X', Y', Z') = 2 * (X, Y, Z), where
* X' = (3 * (X - Z^2) * (X + Z^2))^2 - 8 * X * Y^2
- * Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^2
+ * Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^4
* Z' = (Y + Z)^2 - Y^2 - Z^2 = 2 * Y * Z
* Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed,
* while x_out == y_in is not (maybe this works, but it's not tested).
felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out;
widefelem tmp, tmp2;
limb z1_is_zero, z2_is_zero, x_equal, y_equal;
+ limb points_equal;
if (!mixed) {
/* ftmp2 = z2^2 */
felem_reduce(ftmp, tmp);
/*
- * the formulae are incorrect if the points are equal so we check for
- * this and do doubling if this happens
+ * The formulae are incorrect if the points are equal, in affine coordinates
+ * (X_1, Y_1) == (X_2, Y_2), so we check for this and do doubling if this
+ * happens.
+ *
+ * We use bitwise operations to avoid potential side-channels introduced by
+ * the short-circuiting behaviour of boolean operators.
*/
x_equal = felem_is_zero(ftmp);
y_equal = felem_is_zero(ftmp3);
+ /*
+ * The special case of either point being the point at infinity (z1 and/or
+ * z2 are zero), is handled separately later on in this function, so we
+ * avoid jumping to point_double here in those special cases.
+ */
z1_is_zero = felem_is_zero(z1);
z2_is_zero = felem_is_zero(z2);
- /* In affine coordinates, (X_1, Y_1) == (X_2, Y_2) */
- if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
+
+ /*
+ * Compared to `ecp_nistp256.c` and `ecp_nistp521.c`, in this
+ * specific implementation `felem_is_zero()` returns truth as `0x1`
+ * (rather than `0xff..ff`).
+ *
+ * This implies that `~true` in this implementation becomes
+ * `0xff..fe` (rather than `0x0`): for this reason, to be used in
+ * the if expression, we mask out only the last bit in the next
+ * line.
+ */
+ points_equal = (x_equal & y_equal & (~z1_is_zero) & (~z2_is_zero)) & 1;
+
+ if (points_equal) {
+ /*
+ * This is obviously not constant-time but, as mentioned before, this
+ * case never happens during single point multiplication, so there is no
+ * timing leak for ECDH or ECDSA signing.
+ */
point_double(x3, y3, z3, x1, y1, z1);
return;
}
bits |= get_bit(scalars[num], i + 1) << 2;
bits |= get_bit(scalars[num], i) << 1;
bits |= get_bit(scalars[num], i - 1);
- ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
+ ossl_ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
/* select the point to add or subtract */
select_point(digit, 17, pre_comp[num], tmp);
* FUNCTIONS TO MANAGE PRECOMPUTATION
*/
-static NISTP224_PRE_COMP *nistp224_pre_comp_new()
+static NISTP224_PRE_COMP *nistp224_pre_comp_new(void)
{
NISTP224_PRE_COMP *ret = OPENSSL_zalloc(sizeof(*ret));
if (!ret) {
- ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return ret;
}
ret->lock = CRYPTO_THREAD_lock_new();
if (ret->lock == NULL) {
- ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
OPENSSL_free(ret);
return NULL;
}
* OPENSSL EC_METHOD FUNCTIONS
*/
-int ec_GFp_nistp224_group_init(EC_GROUP *group)
+int ossl_ec_GFp_nistp224_group_init(EC_GROUP *group)
{
int ret;
- ret = ec_GFp_simple_group_init(group);
+ ret = ossl_ec_GFp_simple_group_init(group);
group->a_is_minus3 = 1;
return ret;
}
-int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
- const BIGNUM *a, const BIGNUM *b,
- BN_CTX *ctx)
+int ossl_ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b,
+ BN_CTX *ctx)
{
int ret = 0;
- BN_CTX *new_ctx = NULL;
BIGNUM *curve_p, *curve_a, *curve_b;
+#ifndef FIPS_MODULE
+ BN_CTX *new_ctx = NULL;
if (ctx == NULL)
- if ((ctx = new_ctx = BN_CTX_new()) == NULL)
- return 0;
+ ctx = new_ctx = BN_CTX_new();
+#endif
+ if (ctx == NULL)
+ return 0;
+
BN_CTX_start(ctx);
curve_p = BN_CTX_get(ctx);
curve_a = BN_CTX_get(ctx);
BN_bin2bn(nistp224_curve_params[1], sizeof(felem_bytearray), curve_a);
BN_bin2bn(nistp224_curve_params[2], sizeof(felem_bytearray), curve_b);
if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) {
- ECerr(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE,
- EC_R_WRONG_CURVE_PARAMETERS);
+ ERR_raise(ERR_LIB_EC, EC_R_WRONG_CURVE_PARAMETERS);
goto err;
}
group->field_mod_func = BN_nist_mod_224;
- ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+ ret = ossl_ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
err:
BN_CTX_end(ctx);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
return ret;
}
* Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') =
* (X/Z^2, Y/Z^3)
*/
-int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
- const EC_POINT *point,
- BIGNUM *x, BIGNUM *y,
- BN_CTX *ctx)
+int ossl_ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx)
{
felem z1, z2, x_in, y_in, x_out, y_out;
widefelem tmp;
if (EC_POINT_is_at_infinity(group, point)) {
- ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
- EC_R_POINT_AT_INFINITY);
+ ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY);
return 0;
}
if ((!BN_to_felem(x_in, point->X)) || (!BN_to_felem(y_in, point->Y)) ||
felem_contract(x_out, x_in);
if (x != NULL) {
if (!felem_to_BN(x, x_out)) {
- ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
- ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
return 0;
}
}
felem_contract(y_out, y_in);
if (y != NULL) {
if (!felem_to_BN(y, y_out)) {
- ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
- ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
return 0;
}
}
* Runs in constant time, unless an input is the point at infinity (which
* normally shouldn't happen).
*/
- ec_GFp_nistp_points_make_affine_internal(num,
- points,
- sizeof(felem),
- tmp_felems,
- (void (*)(void *))felem_one,
- felem_is_zero_int,
- (void (*)(void *, const void *))
- felem_assign,
- (void (*)(void *, const void *))
- felem_square_reduce, (void (*)
- (void *,
- const void
- *,
- const void
- *))
- felem_mul_reduce,
- (void (*)(void *, const void *))
- felem_inv,
- (void (*)(void *, const void *))
- felem_contract);
+ ossl_ec_GFp_nistp_points_make_affine_internal(num,
+ points,
+ sizeof(felem),
+ tmp_felems,
+ (void (*)(void *))felem_one,
+ felem_is_zero_int,
+ (void (*)(void *, const void *))
+ felem_assign,
+ (void (*)(void *, const void *))
+ felem_square_reduce, (void (*)
+ (void *,
+ const void
+ *,
+ const void
+ *))
+ felem_mul_reduce,
+ (void (*)(void *, const void *))
+ felem_inv,
+ (void (*)(void *, const void *))
+ felem_contract);
}
/*
* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL
* values Result is stored in r (r can equal one of the inputs).
*/
-int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
- const BIGNUM *scalar, size_t num,
- const EC_POINT *points[],
- const BIGNUM *scalars[], BN_CTX *ctx)
+int ossl_ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *ctx)
{
int ret = 0;
int j;
unsigned i;
int mixed = 0;
- BN_CTX *new_ctx = NULL;
BIGNUM *x, *y, *z, *tmp_scalar;
felem_bytearray g_secret;
felem_bytearray *secrets = NULL;
felem (*pre_comp)[17][3] = NULL;
felem *tmp_felems = NULL;
- felem_bytearray tmp;
- unsigned num_bytes;
+ int num_bytes;
int have_pre_comp = 0;
size_t num_points = num;
felem x_in, y_in, z_in, x_out, y_out, z_out;
const EC_POINT *p = NULL;
const BIGNUM *p_scalar = NULL;
- if (ctx == NULL)
- if ((ctx = new_ctx = BN_CTX_new()) == NULL)
- return 0;
BN_CTX_start(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
if (!felem_to_BN(x, g_pre_comp[0][1][0]) ||
!felem_to_BN(y, g_pre_comp[0][1][1]) ||
!felem_to_BN(z, g_pre_comp[0][1][2])) {
- ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
- if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
- generator, x, y, z,
- ctx))
+ if (!ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group,
+ generator,
+ x, y, z, ctx))
goto err;
if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
/* precomputation matches generator */
OPENSSL_malloc(sizeof(felem) * (num_points * 17 + 1));
if ((secrets == NULL) || (pre_comp == NULL)
|| (mixed && (tmp_felems == NULL))) {
- ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
goto err;
}
* i.e., they contribute nothing to the linear combination
*/
for (i = 0; i < num_points; ++i) {
- if (i == num)
+ if (i == num) {
/* the generator */
- {
p = EC_GROUP_get0_generator(group);
p_scalar = scalar;
- } else
+ } else {
/* the i^th point */
- {
p = points[i];
p_scalar = scalars[i];
}
* constant-timeness
*/
if (!BN_nnmod(tmp_scalar, p_scalar, group->order, ctx)) {
- ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
- num_bytes = BN_bn2bin(tmp_scalar, tmp);
- } else
- num_bytes = BN_bn2bin(p_scalar, tmp);
- flip_endian(secrets[i], tmp, num_bytes);
+ num_bytes = BN_bn2lebinpad(tmp_scalar,
+ secrets[i], sizeof(secrets[i]));
+ } else {
+ num_bytes = BN_bn2lebinpad(p_scalar,
+ secrets[i], sizeof(secrets[i]));
+ }
+ if (num_bytes < 0) {
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
+ goto err;
+ }
/* precompute multiples */
if ((!BN_to_felem(x_out, p->X)) ||
(!BN_to_felem(y_out, p->Y)) ||
* constant-timeness
*/
if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) {
- ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
- num_bytes = BN_bn2bin(tmp_scalar, tmp);
- } else
- num_bytes = BN_bn2bin(scalar, tmp);
- flip_endian(g_secret, tmp, num_bytes);
+ num_bytes = BN_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret));
+ } else {
+ num_bytes = BN_bn2lebinpad(scalar, g_secret, sizeof(g_secret));
+ }
/* do the multiplication with generator precomputation */
batch_mul(x_out, y_out, z_out,
(const felem_bytearray(*))secrets, num_points,
g_secret,
mixed, (const felem(*)[17][3])pre_comp, g_pre_comp);
- } else
+ } else {
/* do the multiplication without generator precomputation */
batch_mul(x_out, y_out, z_out,
(const felem_bytearray(*))secrets, num_points,
NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
+ }
/* reduce the output to its unique minimal representation */
felem_contract(x_in, x_out);
felem_contract(y_in, y_out);
felem_contract(z_in, z_out);
if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) ||
(!felem_to_BN(z, z_in))) {
- ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
- ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
+ ret = ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group, r, x, y, z,
+ ctx);
err:
BN_CTX_end(ctx);
EC_POINT_free(generator);
- BN_CTX_free(new_ctx);
OPENSSL_free(secrets);
OPENSSL_free(pre_comp);
OPENSSL_free(tmp_felems);
return ret;
}
-int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+int ossl_ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
{
int ret = 0;
NISTP224_PRE_COMP *pre = NULL;
int i, j;
- BN_CTX *new_ctx = NULL;
BIGNUM *x, *y;
EC_POINT *generator = NULL;
felem tmp_felems[32];
+#ifndef FIPS_MODULE
+ BN_CTX *new_ctx = NULL;
+#endif
/* throw away old precomputation */
EC_pre_comp_free(group);
+
+#ifndef FIPS_MODULE
if (ctx == NULL)
- if ((ctx = new_ctx = BN_CTX_new()) == NULL)
- return 0;
+ ctx = new_ctx = BN_CTX_new();
+#endif
+ if (ctx == NULL)
+ return 0;
+
BN_CTX_start(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
goto err;
BN_bin2bn(nistp224_curve_params[3], sizeof(felem_bytearray), x);
BN_bin2bn(nistp224_curve_params[4], sizeof(felem_bytearray), y);
- if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
+ if (!EC_POINT_set_affine_coordinates(group, generator, x, y, ctx))
goto err;
if ((pre = nistp224_pre_comp_new()) == NULL)
goto err;
err:
BN_CTX_end(ctx);
EC_POINT_free(generator);
+#ifndef FIPS_MODULE
BN_CTX_free(new_ctx);
+#endif
EC_nistp224_pre_comp_free(pre);
return ret;
}
-int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group)
+int ossl_ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group)
{
return HAVEPRECOMP(group, nistp224);
}
-
-#endif