X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fec%2Fecp_nistp224.c;h=2763398a335a0fe5f2710b0379f2cf713925f221;hp=c2677a85d5be816b1ea60ea0d46d249752cb908b;hb=207a56437916a715bcf6e299c868c75a17ad8fc0;hpb=3aef36ffef89849348049296892327e6fdf9d705 diff --git a/crypto/ec/ecp_nistp224.c b/crypto/ec/ecp_nistp224.c index c2677a85d5..2763398a33 100644 --- a/crypto/ec/ecp_nistp224.c +++ b/crypto/ec/ecp_nistp224.c @@ -1,7 +1,12 @@ -/* crypto/ec/ecp_nistp224.c */ /* - * Written by Emilia Kasper (Google) for the OpenSSL project. + * Copyright 2010-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (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 */ + /* Copyright 2011 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,7 +31,9 @@ */ #include -#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128 +NON_EMPTY_TRANSLATION_UNIT +#else # include # include @@ -43,7 +50,6 @@ typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit typedef uint8_t u8; typedef uint64_t u64; -typedef int64_t s64; /******************************************************************************/ /*- @@ -230,6 +236,7 @@ static const felem gmul[2][16][3] = { struct nistp224_pre_comp_st { felem g_pre_comp[2][16][3]; int references; + CRYPTO_RWLOCK *lock; }; const EC_METHOD *EC_GFp_nistp224_method(void) @@ -244,6 +251,7 @@ const EC_METHOD *EC_GFp_nistp224_method(void) 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, @@ -271,9 +279,20 @@ const EC_METHOD *EC_GFp_nistp224_method(void) ec_GFp_nist_field_mul, ec_GFp_nist_field_sqr, 0 /* field_div */ , + ec_GFp_simple_field_inv, 0 /* field_encode */ , 0 /* field_decode */ , - 0 /* field_set_to_one */ + 0, /* field_set_to_one */ + ec_key_simple_priv2oct, + ec_key_simple_oct2priv, + 0, /* set private */ + ec_key_simple_generate_key, + ec_key_simple_check_key, + ec_key_simple_generate_public_key, + 0, /* keycopy */ + 0, /* keyfinish */ + ecdh_simple_compute_key, + 0 /* blind_coordinates */ }; return &ret; @@ -301,34 +320,21 @@ 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) { + if (BN_is_negative(bn)) { ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); return 0; } - if (BN_is_negative(bn)) { + num_bytes = BN_bn2lebinpad(bn, b_out, sizeof(b_out)); + if (num_bytes < 0) { ECerr(EC_F_BN_TO_FELEM, 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; } @@ -336,10 +342,9 @@ static int BN_to_felem(felem out, const BIGNUM *bn) /* 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); } /******************************************************************************/ @@ -682,7 +687,7 @@ static limb felem_is_zero(const felem in) return (zero | two224m96p1 | two225m97p2); } -static limb felem_is_zero_int(const felem in) +static int felem_is_zero_int(const void *in) { return (int)(felem_is_zero(in) & ((limb) 1)); } @@ -1205,22 +1210,40 @@ static NISTP224_PRE_COMP *nistp224_pre_comp_new() ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); return ret; } + ret->references = 1; + + ret->lock = CRYPTO_THREAD_lock_new(); + if (ret->lock == NULL) { + ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); + OPENSSL_free(ret); + return NULL; + } return ret; } NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *p) { + int i; if (p != NULL) - CRYPTO_add(&p->references, 1, CRYPTO_LOCK_EC_PRE_COMP); + CRYPTO_atomic_add(&p->references, 1, &i, p->lock); return p; } void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *p) { - if (p == NULL - || CRYPTO_add(&p->references, -1, CRYPTO_LOCK_EC_PRE_COMP) > 0) + int i; + + if (p == NULL) + return; + + CRYPTO_atomic_add(&p->references, -1, &i, p->lock); + REF_PRINT_COUNT("EC_nistp224", x); + if (i > 0) return; + REF_ASSERT_ISNT(i < 0); + + CRYPTO_THREAD_lock_free(p->lock); OPENSSL_free(p); } @@ -1329,7 +1352,6 @@ static void make_points_affine(size_t num, felem points[ /* num */ ][3], sizeof(felem), tmp_felems, (void (*)(void *))felem_one, - (int (*)(const void *)) felem_is_zero_int, (void (*)(void *, const void *)) felem_assign, @@ -1366,8 +1388,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, 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; @@ -1444,14 +1465,12 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, * 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]; } @@ -1467,10 +1486,16 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, 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) { + ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } /* precompute multiples */ if ((!BN_to_felem(x_out, p->X)) || (!BN_to_felem(y_out, p->Y)) || @@ -1513,20 +1538,21 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, 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); @@ -1559,7 +1585,7 @@ int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx) felem tmp_felems[32]; /* throw away old precomputation */ - EC_nistp224_pre_comp_free(group->pre_comp.nistp224); + EC_pre_comp_free(group); if (ctx == NULL) if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0; @@ -1583,8 +1609,7 @@ int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx) */ if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) { memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp)); - ret = 1; - goto err; + goto done; } if ((!BN_to_felem(pre->g_pre_comp[0][1][0], group->generator->X)) || (!BN_to_felem(pre->g_pre_comp[0][1][1], group->generator->Y)) || @@ -1662,6 +1687,7 @@ int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx) } make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_felems); + done: SETPRECOMP(group, nistp224, pre); pre = NULL; ret = 1; @@ -1678,6 +1704,4 @@ int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group) return HAVEPRECOMP(group, nistp224); } -#else -static void *dummy = &dummy; #endif