Fix warnings.

Also, use the common Configure mechanism for enabling/disabling the 64-bit ECC code.
This commit is contained in:
Bodo Möller 2011-10-19 08:58:35 +00:00
parent 9c37519b55
commit 3d520f7c2d
12 changed files with 119 additions and 99 deletions

View File

@ -7,11 +7,12 @@
*) Add optional 64-bit optimized implementations of elliptic curves NIST-P224, *) Add optional 64-bit optimized implementations of elliptic curves NIST-P224,
NIST-P256, NIST-P521, with constant-time single point multiplication on NIST-P256, NIST-P521, with constant-time single point multiplication on
typical inputs. Compiler support for the nonstandard type __uint128_t is typical inputs. Compiler support for the nonstandard type __uint128_t is
required to use this. Code made available under Apache License version 2.0. required to use this (present in gcc 4.4 and later, for 64-bit builds).
Code made available under Apache License version 2.0.
To include this in your build of OpenSSL, use -DEC_NISTP_64_GCC_128 on Specify "enable-ec_nistp_64_gcc_128" on the Configure (or config) command
the Configure (or config) command line, and run "make depend" (or "make line to include this in your build of OpenSSL, and run "make depend" (or
update"). This enables the following EC_METHODs: "make update"). This enables the following EC_METHODs:
EC_GFp_nistp224_method() EC_GFp_nistp224_method()
EC_GFp_nistp256_method() EC_GFp_nistp256_method()

View File

@ -170,7 +170,7 @@ my %table=(
"debug-ben-no-opt", "gcc: -Wall -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -DDEBUG_SAFESTACK -DCRYPTO_MDEBUG -Werror -DL_ENDIAN -DTERMIOS -Wall -g3::(unknown)::::::", "debug-ben-no-opt", "gcc: -Wall -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -DDEBUG_SAFESTACK -DCRYPTO_MDEBUG -Werror -DL_ENDIAN -DTERMIOS -Wall -g3::(unknown)::::::",
"debug-ben-strict", "gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DCONST_STRICT -O2 -Wall -Wshadow -Werror -Wpointer-arith -Wcast-qual -Wwrite-strings -pipe::(unknown)::::::", "debug-ben-strict", "gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DCONST_STRICT -O2 -Wall -Wshadow -Werror -Wpointer-arith -Wcast-qual -Wwrite-strings -pipe::(unknown)::::::",
"debug-rse","cc:-DTERMIOS -DL_ENDIAN -pipe -O -g -ggdb3 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}", "debug-rse","cc:-DTERMIOS -DL_ENDIAN -pipe -O -g -ggdb3 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}",
"debug-bodo", "gcc:-DL_ENDIAN -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBIO_PAIR_DEBUG -DPEDANTIC -g -march=i486 -pedantic -Wshadow -Wall -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion::-D_REENTRANT:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}", "debug-bodo", "gcc:$gcc_devteam_warn -DBN_DEBUG -DBN_DEBUG_RAND -DCONF_DEBUG -DBIO_PAIR_DEBUG -m64 -DL_ENDIAN -DTERMIO -g -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
"debug-ulf", "gcc:-DTERMIOS -DL_ENDIAN -march=i486 -Wall -DBN_DEBUG -DBN_DEBUG_RAND -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DOPENSSL_NO_ASM -g -Wformat -Wshadow -Wmissing-prototypes -Wmissing-declarations:::CYGWIN32:::${no_asm}:win32:cygwin-shared:::.dll", "debug-ulf", "gcc:-DTERMIOS -DL_ENDIAN -march=i486 -Wall -DBN_DEBUG -DBN_DEBUG_RAND -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DOPENSSL_NO_ASM -g -Wformat -Wshadow -Wmissing-prototypes -Wmissing-declarations:::CYGWIN32:::${no_asm}:win32:cygwin-shared:::.dll",
"debug-steve64", "gcc:$gcc_devteam_warn -m64 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -DDEBUG_SAFESTACK -g -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", "debug-steve64", "gcc:$gcc_devteam_warn -m64 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -DDEBUG_SAFESTACK -g -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"debug-steve32", "gcc:$gcc_devteam_warn -m32 -DL_ENDIAN -DCONF_DEBUG -DDEBUG_SAFESTACK -g -pipe::-D_REENTRANT::-rdynamic -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC:-m32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", "debug-steve32", "gcc:$gcc_devteam_warn -m32 -DL_ENDIAN -DCONF_DEBUG -DDEBUG_SAFESTACK -g -pipe::-D_REENTRANT::-rdynamic -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC:-m32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
@ -680,7 +680,7 @@ if (exists $ENV{FIPSDIR})
# All of the following is disabled by default (RC5 was enabled before 0.9.8): # All of the following is disabled by default (RC5 was enabled before 0.9.8):
my %disabled = ( # "what" => "comment" [or special keyword "experimental"] my %disabled = ( # "what" => "comment" [or special keyword "experimental"]
"ec-nistp224-64-gcc-128" => "default", "ec_nistp_64_gcc_128" => "default",
"gmp" => "default", "gmp" => "default",
"jpake" => "experimental", "jpake" => "experimental",
"md2" => "default", "md2" => "default",
@ -695,7 +695,7 @@ my @experimental = ();
# This is what $depflags will look like with the above defaults # This is what $depflags will look like with the above defaults
# (we need this to see if we should advise the user to run "make depend"): # (we need this to see if we should advise the user to run "make depend"):
my $default_depflags = " -DOPENSSL_NO_EC_NISTP224_64_GCC_128 -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_STORE"; my $default_depflags = " -DOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_STORE";
# Explicit "no-..." options will be collected in %disabled along with the defaults. # Explicit "no-..." options will be collected in %disabled along with the defaults.
# To remove something from %disabled, use "enable-foo" (unless it's experimental). # To remove something from %disabled, use "enable-foo" (unless it's experimental).

44
TABLE
View File

@ -1738,34 +1738,34 @@ $multilib =
*** debug-bodo *** debug-bodo
$cc = gcc $cc = gcc
$cflags = -DL_ENDIAN -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBIO_PAIR_DEBUG -DPEDANTIC -g -march=i486 -pedantic -Wshadow -Wall -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion $cflags = -Wall -pedantic -DPEDANTIC -Wno-long-long -Wsign-compare -Wmissing-prototypes -Wshadow -Wformat -Werror -DCRYPTO_MDEBUG_ALL -DCRYPTO_MDEBUG_ABORT -DREF_CHECK -DOPENSSL_NO_DEPRECATED -DBN_DEBUG -DBN_DEBUG_RAND -DCONF_DEBUG -DBIO_PAIR_DEBUG -m64 -DL_ENDIAN -DTERMIO -g -DMD32_REG_T=int
$unistd = $unistd =
$thread_cflag = -D_REENTRANT $thread_cflag = -D_REENTRANT
$sys_id = $sys_id =
$lflags = $lflags = -ldl
$bn_ops = BN_LLONG DES_PTR DES_RISC1 DES_UNROLL RC4_INDEX MD2_INT $bn_ops = SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL
$cpuid_obj = x86cpuid.o $cpuid_obj = x86_64cpuid.o
$bn_obj = bn-586.o co-586.o x86-mont.o $bn_obj = x86_64-gcc.o x86_64-mont.o modexp512-x86_64.o
$des_obj = des-586.o crypt586.o $des_obj =
$aes_obj = aes-586.o aesni-x86.o $aes_obj = aes-x86_64.o aesni-x86_64.o aesni-sha1-x86_64.o
$bf_obj = bf-586.o $bf_obj =
$md5_obj = md5-586.o $md5_obj = md5-x86_64.o
$sha1_obj = sha1-586.o sha256-586.o sha512-586.o $sha1_obj = sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o
$cast_obj = cast-586.o $cast_obj =
$rc4_obj = rc4-586.o $rc4_obj = rc4-x86_64.o rc4-md5-x86_64.o
$rmd160_obj = rmd-586.o $rmd160_obj =
$rc5_obj = rc5-586.o $rc5_obj =
$wp_obj = wp_block.o wp-mmx.o $wp_obj = wp-x86_64.o
$cmll_obj = cmll-x86.o $cmll_obj = cmll-x86_64.o cmll_misc.o
$perlasm_scheme = elf $perlasm_scheme = elf
$dso_scheme = $dso_scheme = dlfcn
$shared_target= $shared_target= linux-shared
$shared_cflag = $shared_cflag = -fPIC
$shared_ldflag = $shared_ldflag = -m64
$shared_extension = $shared_extension = .so.$(SHLIB_MAJOR).$(SHLIB_MINOR)
$ranlib = $ranlib =
$arflags = $arflags =
$multilib = $multilib = 64
*** debug-darwin-i386-cc *** debug-darwin-i386-cc
$cc = cc $cc = cc

View File

@ -151,7 +151,7 @@ const EC_METHOD *EC_GFp_mont_method(void);
*/ */
const EC_METHOD *EC_GFp_nist_method(void); const EC_METHOD *EC_GFp_nist_method(void);
#ifdef EC_NISTP_64_GCC_128 #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
/** Returns 64-bit optimized methods for nistp224 /** Returns 64-bit optimized methods for nistp224
* \return EC_METHOD object * \return EC_METHOD object
*/ */

View File

@ -72,6 +72,7 @@
#include "ec_lcl.h" #include "ec_lcl.h"
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/obj_mac.h> #include <openssl/obj_mac.h>
#include <openssl/opensslconf.h>
typedef struct { typedef struct {
int field_type, /* either NID_X9_62_prime_field or int field_type, /* either NID_X9_62_prime_field or
@ -1841,7 +1842,7 @@ static const ec_list_element curve_list[] = {
/* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */ /* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */
{ NID_secp192k1, &_EC_SECG_PRIME_192K1.h, 0, "SECG curve over a 192 bit prime field" }, { NID_secp192k1, &_EC_SECG_PRIME_192K1.h, 0, "SECG curve over a 192 bit prime field" },
{ NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0, "SECG curve over a 224 bit prime field" }, { NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0, "SECG curve over a 224 bit prime field" },
#ifdef EC_NISTP_64_GCC_128 #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
{ NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method, "NIST/SECG curve over a 224 bit prime field" }, { NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method, "NIST/SECG curve over a 224 bit prime field" },
#else #else
{ NID_secp224r1, &_EC_NIST_PRIME_224.h, 0, "NIST/SECG curve over a 224 bit prime field" }, { NID_secp224r1, &_EC_NIST_PRIME_224.h, 0, "NIST/SECG curve over a 224 bit prime field" },
@ -1849,7 +1850,7 @@ static const ec_list_element curve_list[] = {
{ NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0, "SECG curve over a 256 bit prime field" }, { NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0, "SECG curve over a 256 bit prime field" },
/* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */ /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
{ NID_secp384r1, &_EC_NIST_PRIME_384.h, 0, "NIST/SECG curve over a 384 bit prime field" }, { NID_secp384r1, &_EC_NIST_PRIME_384.h, 0, "NIST/SECG curve over a 384 bit prime field" },
#ifdef EC_NISTP_64_GCC_128 #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
{ NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method, "NIST/SECG curve over a 521 bit prime field" }, { NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method, "NIST/SECG curve over a 521 bit prime field" },
#else #else
{ NID_secp521r1, &_EC_NIST_PRIME_521.h, 0, "NIST/SECG curve over a 521 bit prime field" }, { NID_secp521r1, &_EC_NIST_PRIME_521.h, 0, "NIST/SECG curve over a 521 bit prime field" },
@ -1861,7 +1862,7 @@ static const ec_list_element curve_list[] = {
{ NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, 0, "X9.62 curve over a 239 bit prime field" }, { NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, 0, "X9.62 curve over a 239 bit prime field" },
{ NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0, "X9.62 curve over a 239 bit prime field" }, { NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0, "X9.62 curve over a 239 bit prime field" },
{ NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0, "X9.62 curve over a 239 bit prime field" }, { NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0, "X9.62 curve over a 239 bit prime field" },
#ifdef EC_NISTP_64_GCC_128 #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
{ NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, EC_GFp_nistp256_method, "X9.62/SECG curve over a 256 bit prime field" }, { NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, EC_GFp_nistp256_method, "X9.62/SECG curve over a 256 bit prime field" },
#else #else
{ NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, 0, "X9.62/SECG curve over a 256 bit prime field" }, { NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, 0, "X9.62/SECG curve over a 256 bit prime field" },

View File

@ -398,13 +398,13 @@ int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx); int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
int ec_GF2m_have_precompute_mult(const EC_GROUP *group); int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
#ifdef EC_NISTP_64_GCC_128
/* method functions in ec2_mult.c */ /* method functions in ec2_mult.c */
int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *); size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx); int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
int ec_GF2m_have_precompute_mult(const EC_GROUP *group); int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
#ifndef OPENSSL_EC_NISTP_64_GCC_128
/* method functions in ecp_nistp224.c */ /* method functions in ecp_nistp224.c */
int ec_GFp_nistp224_group_init(EC_GROUP *group); int ec_GFp_nistp224_group_init(EC_GROUP *group);
int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *); int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *);

View File

@ -24,7 +24,10 @@
* Inspired by Daniel J. Bernstein's public domain nistp224 implementation * Inspired by Daniel J. Bernstein's public domain nistp224 implementation
* and Adam Langley's public domain 64-bit C implementation of curve25519 * and Adam Langley's public domain 64-bit C implementation of curve25519
*/ */
#ifdef EC_NISTP_64_GCC_128
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <openssl/err.h> #include <openssl/err.h>
@ -247,9 +250,9 @@ const EC_METHOD *EC_GFp_nistp224_method(void)
ec_GFp_simple_get_Jprojective_coordinates_GFp, ec_GFp_simple_get_Jprojective_coordinates_GFp,
ec_GFp_simple_point_set_affine_coordinates, ec_GFp_simple_point_set_affine_coordinates,
ec_GFp_nistp224_point_get_affine_coordinates, ec_GFp_nistp224_point_get_affine_coordinates,
0 /* point_set_compressed_coordinates */, 0 /* point_set_compressed_coordinates */,
0 /* point2oct */, 0 /* point2oct */,
0 /* oct2point */, 0 /* oct2point */,
ec_GFp_simple_add, ec_GFp_simple_add,
ec_GFp_simple_dbl, ec_GFp_simple_dbl,
ec_GFp_simple_invert, ec_GFp_simple_invert,
@ -1000,9 +1003,9 @@ static void point_add(felem x3, felem y3, felem z3,
felem_assign(z3, z_out); felem_assign(z3, z_out);
} }
/* select_point selects the |index|th point from a precomputation table and /* select_point selects the |idx|th point from a precomputation table and
* copies it to out. */ * copies it to out. */
static void select_point(const u64 index, unsigned int size, const felem pre_comp[/*size*/][3], felem out[3]) static void select_point(const u64 idx, unsigned int size, const felem pre_comp[/*size*/][3], felem out[3])
{ {
unsigned i, j; unsigned i, j;
limb *outlimbs = &out[0][0]; limb *outlimbs = &out[0][0];
@ -1011,7 +1014,7 @@ static void select_point(const u64 index, unsigned int size, const felem pre_com
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
{ {
const limb *inlimbs = &pre_comp[i][0][0]; const limb *inlimbs = &pre_comp[i][0][0];
u64 mask = i ^ index; u64 mask = i ^ idx;
mask |= mask >> 4; mask |= mask >> 4;
mask |= mask >> 2; mask |= mask >> 2;
mask |= mask >> 1; mask |= mask >> 1;

View File

@ -26,7 +26,8 @@
* work which got its smarts from Daniel J. Bernstein's work on the same. * work which got its smarts from Daniel J. Bernstein's work on the same.
*/ */
#ifdef EC_NISTP_64_GCC_128 #include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@ -363,6 +364,10 @@ static const felem zero110 = { two64m0, two110p32m0, two64m46, two64m32 };
static void felem_shrink(smallfelem out, const felem in) static void felem_shrink(smallfelem out, const felem in)
{ {
felem tmp; felem tmp;
u64 a, b, mask;
s64 high, low;
static const u64 kPrime3Test = 0x7fffffff00000001ul; /* 2^63 - 2^32 + 1 */
/* Carry 2->3 */ /* Carry 2->3 */
tmp[3] = zero110[3] + in[3] + ((u64) (in[2] >> 64)); tmp[3] = zero110[3] + in[3] + ((u64) (in[2] >> 64));
/* tmp[3] < 2^110 */ /* tmp[3] < 2^110 */
@ -375,13 +380,13 @@ static void felem_shrink(smallfelem out, const felem in)
/* We perform two partial reductions where we eliminate the /* We perform two partial reductions where we eliminate the
* high-word of tmp[3]. We don't update the other words till the end. * high-word of tmp[3]. We don't update the other words till the end.
*/ */
u64 a = tmp[3] >> 64; /* a < 2^46 */ a = tmp[3] >> 64; /* a < 2^46 */
tmp[3] = (u64) tmp[3]; tmp[3] = (u64) tmp[3];
tmp[3] -= a; tmp[3] -= a;
tmp[3] += ((limb)a) << 32; tmp[3] += ((limb)a) << 32;
/* tmp[3] < 2^79 */ /* tmp[3] < 2^79 */
u64 b = a; b = a;
a = tmp[3] >> 64; /* a < 2^15 */ a = tmp[3] >> 64; /* a < 2^15 */
b += a; /* b < 2^46 + 2^15 < 2^47 */ b += a; /* b < 2^46 + 2^15 < 2^47 */
tmp[3] = (u64) tmp[3]; tmp[3] = (u64) tmp[3];
@ -396,16 +401,15 @@ static void felem_shrink(smallfelem out, const felem in)
/* In order to make space in tmp[3] for the carry from 2 -> 3, we /* In order to make space in tmp[3] for the carry from 2 -> 3, we
* conditionally subtract kPrime if tmp[3] is large enough. */ * conditionally subtract kPrime if tmp[3] is large enough. */
static const u64 kPrime3Test = 0x7fffffff00000001ul; /* 2^63 - 2^32 + 1 */ high = tmp[3] >> 64;
s64 high = tmp[3] >> 64;
/* As tmp[3] < 2^65, high is either 1 or 0 */ /* As tmp[3] < 2^65, high is either 1 or 0 */
high <<= 63; high <<= 63;
high >>= 63; high >>= 63;
/* high is: /* high is:
* all ones if the high word of tmp[3] is 1 * all ones if the high word of tmp[3] is 1
* all zeros if the high word of tmp[3] if 0 */ * all zeros if the high word of tmp[3] if 0 */
s64 low = tmp[3]; low = tmp[3];
u64 mask = low >> 63; mask = low >> 63;
/* mask is: /* mask is:
* all ones if the MSB of low is 1 * all ones if the MSB of low is 1
* all zeros if the MSB of low if 0 */ * all zeros if the MSB of low if 0 */
@ -815,7 +819,9 @@ static void felem_contract(smallfelem out, const felem in)
* compare each u64, from most-significant to least significant. For * compare each u64, from most-significant to least significant. For
* each one, if all words so far have been equal (m is all ones) then a * each one, if all words so far have been equal (m is all ones) then a
* non-equal result is the answer. Otherwise we continue. */ * non-equal result is the answer. Otherwise we continue. */
for (i = 3; i < 4; i--) { for (i = 3; i < 4; i--)
{
u64 equal;
uint128_t a = ((uint128_t) kPrime[i]) - out[i]; uint128_t a = ((uint128_t) kPrime[i]) - out[i];
/* if out[i] > kPrime[i] then a will underflow and the high /* if out[i] > kPrime[i] then a will underflow and the high
* 64-bits will all be set. */ * 64-bits will all be set. */
@ -823,7 +829,7 @@ static void felem_contract(smallfelem out, const felem in)
/* if kPrime[i] == out[i] then |equal| will be all zeros and /* if kPrime[i] == out[i] then |equal| will be all zeros and
* the decrement will make it all ones. */ * the decrement will make it all ones. */
u64 equal = kPrime[i] ^ out[i]; equal = kPrime[i] ^ out[i];
equal--; equal--;
equal &= equal << 32; equal &= equal << 32;
equal &= equal << 16; equal &= equal << 16;
@ -834,7 +840,7 @@ static void felem_contract(smallfelem out, const felem in)
equal = ((s64) equal) >> 63; equal = ((s64) equal) >> 63;
all_equal_so_far &= equal; all_equal_so_far &= equal;
} }
/* if all_equal_so_far is still all ones then the two values are equal /* if all_equal_so_far is still all ones then the two values are equal
* and so out >= kPrime is true. */ * and so out >= kPrime is true. */
@ -884,6 +890,7 @@ static void smallfelem_mul_contract(smallfelem out, const smallfelem in1, const
static limb smallfelem_is_zero(const smallfelem small) static limb smallfelem_is_zero(const smallfelem small)
{ {
limb result; limb result;
u64 is_p;
u64 is_zero = small[0] | small[1] | small[2] | small[3]; u64 is_zero = small[0] | small[1] | small[2] | small[3];
is_zero--; is_zero--;
@ -895,10 +902,10 @@ static limb smallfelem_is_zero(const smallfelem small)
is_zero &= is_zero << 1; is_zero &= is_zero << 1;
is_zero = ((s64) is_zero) >> 63; is_zero = ((s64) is_zero) >> 63;
u64 is_p = (small[0] ^ kPrime[0]) | is_p = (small[0] ^ kPrime[0]) |
(small[1] ^ kPrime[1]) | (small[1] ^ kPrime[1]) |
(small[2] ^ kPrime[2]) | (small[2] ^ kPrime[2]) |
(small[3] ^ kPrime[3]); (small[3] ^ kPrime[3]);
is_p--; is_p--;
is_p &= is_p << 32; is_p &= is_p << 32;
is_p &= is_p << 16; is_p &= is_p << 16;
@ -1457,9 +1464,9 @@ static const smallfelem gmul[2][16][3] =
{0x501e82885bc98cda, 0x41ef80e5d046ac04, 0x557d9f49461210fb, 0x4ab5b6b2b8753f81}, {0x501e82885bc98cda, 0x41ef80e5d046ac04, 0x557d9f49461210fb, 0x4ab5b6b2b8753f81},
{1, 0, 0, 0}}}}; {1, 0, 0, 0}}}};
/* select_point selects the |index|th point from a precomputation table and /* select_point selects the |idx|th point from a precomputation table and
* copies it to out. */ * copies it to out. */
static void select_point(const u64 index, unsigned int size, const smallfelem pre_comp[16][3], smallfelem out[3]) static void select_point(const u64 idx, unsigned int size, const smallfelem pre_comp[16][3], smallfelem out[3])
{ {
unsigned i, j; unsigned i, j;
u64 *outlimbs = &out[0][0]; u64 *outlimbs = &out[0][0];
@ -1468,7 +1475,7 @@ static void select_point(const u64 index, unsigned int size, const smallfelem pr
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
{ {
const u64 *inlimbs = (u64*) &pre_comp[i][0][0]; const u64 *inlimbs = (u64*) &pre_comp[i][0][0];
u64 mask = i ^ index; u64 mask = i ^ idx;
mask |= mask >> 4; mask |= mask >> 4;
mask |= mask >> 2; mask |= mask >> 2;
mask |= mask >> 1; mask |= mask >> 1;
@ -1623,9 +1630,9 @@ const EC_METHOD *EC_GFp_nistp256_method(void)
ec_GFp_simple_get_Jprojective_coordinates_GFp, ec_GFp_simple_get_Jprojective_coordinates_GFp,
ec_GFp_simple_point_set_affine_coordinates, ec_GFp_simple_point_set_affine_coordinates,
ec_GFp_nistp256_point_get_affine_coordinates, ec_GFp_nistp256_point_get_affine_coordinates,
0 /* point_set_compressed_coordinates */, 0 /* point_set_compressed_coordinates */,
0 /* point2oct */, 0 /* point2oct */,
0 /* oct2point */, 0 /* oct2point */,
ec_GFp_simple_add, ec_GFp_simple_add,
ec_GFp_simple_dbl, ec_GFp_simple_dbl,
ec_GFp_simple_invert, ec_GFp_simple_invert,
@ -1784,16 +1791,17 @@ int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
felem_contract(y_out, y_in); felem_contract(y_out, y_in);
if (y != NULL) if (y != NULL)
{ {
if (!smallfelem_to_BN(y, y_out)) { if (!smallfelem_to_BN(y, y_out))
ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES, {
ERR_R_BN_LIB); ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
return 0; ERR_R_BN_LIB);
} return 0;
}
} }
return 1; return 1;
} }
static void make_points_affine(size_t num, smallfelem points[num][3], smallfelem tmp_smallfelems[num+1]) static void make_points_affine(size_t num, smallfelem points[/* num */][3], smallfelem tmp_smallfelems[/* num+1 */])
{ {
/* Runs in constant time, unless an input is the point at infinity /* Runs in constant time, unless an input is the point at infinity
* (which normally shouldn't happen). */ * (which normally shouldn't happen). */

View File

@ -26,7 +26,8 @@
* work which got its smarts from Daniel J. Bernstein's work on the same. * work which got its smarts from Daniel J. Bernstein's work on the same.
*/ */
#ifdef EC_NISTP_64_GCC_128 #include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@ -339,7 +340,7 @@ static void felem_diff64(felem out, const felem in)
*/ */
static void felem_diff_128_64(largefelem out, const felem in) static void felem_diff_128_64(largefelem out, const felem in)
{ {
// In order to prevent underflow, we add 0 mod p before subtracting. /* In order to prevent underflow, we add 0 mod p before subtracting. */
static const limb two63m6 = (((limb)1) << 62) - (((limb)1) << 5); static const limb two63m6 = (((limb)1) << 62) - (((limb)1) << 5);
static const limb two63m5 = (((limb)1) << 62) - (((limb)1) << 4); static const limb two63m5 = (((limb)1) << 62) - (((limb)1) << 4);
@ -362,7 +363,7 @@ static void felem_diff_128_64(largefelem out, const felem in)
*/ */
static void felem_diff128(largefelem out, const largefelem in) static void felem_diff128(largefelem out, const largefelem in)
{ {
// In order to prevent underflow, we add 0 mod p before subtracting. /* In order to prevent underflow, we add 0 mod p before subtracting. */
static const uint128_t two127m70 = (((uint128_t)1) << 127) - (((uint128_t)1) << 70); static const uint128_t two127m70 = (((uint128_t)1) << 127) - (((uint128_t)1) << 70);
static const uint128_t two127m69 = (((uint128_t)1) << 127) - (((uint128_t)1) << 69); static const uint128_t two127m69 = (((uint128_t)1) << 127) - (((uint128_t)1) << 69);
@ -431,40 +432,40 @@ static void felem_square(largefelem out, const felem in)
* the inputs to the multiplication. If we want to double for both this * the inputs to the multiplication. If we want to double for both this
* reason, and the reason above, then we end up multiplying by four. */ * reason, and the reason above, then we end up multiplying by four. */
// 9 /* 9 */
out[0] += ((uint128_t) in[1]) * inx4[8] + out[0] += ((uint128_t) in[1]) * inx4[8] +
((uint128_t) in[2]) * inx4[7] + ((uint128_t) in[2]) * inx4[7] +
((uint128_t) in[3]) * inx4[6] + ((uint128_t) in[3]) * inx4[6] +
((uint128_t) in[4]) * inx4[5]; ((uint128_t) in[4]) * inx4[5];
// 10 /* 10 */
out[1] += ((uint128_t) in[2]) * inx4[8] + out[1] += ((uint128_t) in[2]) * inx4[8] +
((uint128_t) in[3]) * inx4[7] + ((uint128_t) in[3]) * inx4[7] +
((uint128_t) in[4]) * inx4[6] + ((uint128_t) in[4]) * inx4[6] +
((uint128_t) in[5]) * inx2[5]; ((uint128_t) in[5]) * inx2[5];
// 11 /* 11 */
out[2] += ((uint128_t) in[3]) * inx4[8] + out[2] += ((uint128_t) in[3]) * inx4[8] +
((uint128_t) in[4]) * inx4[7] + ((uint128_t) in[4]) * inx4[7] +
((uint128_t) in[5]) * inx4[6]; ((uint128_t) in[5]) * inx4[6];
// 12 /* 12 */
out[3] += ((uint128_t) in[4]) * inx4[8] + out[3] += ((uint128_t) in[4]) * inx4[8] +
((uint128_t) in[5]) * inx4[7] + ((uint128_t) in[5]) * inx4[7] +
((uint128_t) in[6]) * inx2[6]; ((uint128_t) in[6]) * inx2[6];
// 13 /* 13 */
out[4] += ((uint128_t) in[5]) * inx4[8] + out[4] += ((uint128_t) in[5]) * inx4[8] +
((uint128_t) in[6]) * inx4[7]; ((uint128_t) in[6]) * inx4[7];
// 14 /* 14 */
out[5] += ((uint128_t) in[6]) * inx4[8] + out[5] += ((uint128_t) in[6]) * inx4[8] +
((uint128_t) in[7]) * inx2[7]; ((uint128_t) in[7]) * inx2[7];
// 15 /* 15 */
out[6] += ((uint128_t) in[7]) * inx4[8]; out[6] += ((uint128_t) in[7]) * inx4[8];
// 16 /* 16 */
out[7] += ((uint128_t) in[8]) * inx2[8]; out[7] += ((uint128_t) in[8]) * inx2[8];
} }
@ -591,6 +592,8 @@ static const limb bottom52bits = 0xfffffffffffff;
*/ */
static void felem_reduce(felem out, const largefelem in) static void felem_reduce(felem out, const largefelem in)
{ {
u64 overflow1, overflow2;
out[0] = ((limb) in[0]) & bottom58bits; out[0] = ((limb) in[0]) & bottom58bits;
out[1] = ((limb) in[1]) & bottom58bits; out[1] = ((limb) in[1]) & bottom58bits;
out[2] = ((limb) in[2]) & bottom58bits; out[2] = ((limb) in[2]) & bottom58bits;
@ -637,11 +640,11 @@ static void felem_reduce(felem out, const largefelem in)
out[8] += (((limb) (in[7] >> 64)) & bottom52bits) << 6; out[8] += (((limb) (in[7] >> 64)) & bottom52bits) << 6;
/* out[x > 1] < 2^58 + 2^6 + 2^58 + 2^12 /* out[x > 1] < 2^58 + 2^6 + 2^58 + 2^12
* < 2^59 + 2^13 */ * < 2^59 + 2^13 */
u64 overflow1 = ((limb) (in[7] >> 64)) >> 52; overflow1 = ((limb) (in[7] >> 64)) >> 52;
overflow1 += ((limb) in[8]) >> 58; overflow1 += ((limb) in[8]) >> 58;
overflow1 += (((limb) (in[8] >> 64)) & bottom52bits) << 6; overflow1 += (((limb) (in[8] >> 64)) & bottom52bits) << 6;
u64 overflow2 = ((limb) (in[8] >> 64)) >> 52; overflow2 = ((limb) (in[8] >> 64)) >> 52;
overflow1 <<= 1; /* overflow1 < 2^13 + 2^7 + 2^59 */ overflow1 <<= 1; /* overflow1 < 2^13 + 2^7 + 2^59 */
overflow2 <<= 1; /* overflow2 < 2^13 */ overflow2 <<= 1; /* overflow2 < 2^13 */
@ -800,8 +803,8 @@ static limb felem_is_zero(const felem in)
is_zero |= ftmp[8]; is_zero |= ftmp[8];
is_zero--; is_zero--;
// We know that ftmp[i] < 2^63, therefore the only way that the top bit /* We know that ftmp[i] < 2^63, therefore the only way that the top bit
// can be set is if is_zero was 0 before the decrement. * can be set is if is_zero was 0 before the decrement. */
is_zero = ((s64) is_zero) >> 63; is_zero = ((s64) is_zero) >> 63;
is_p = ftmp[0] ^ kPrime[0]; is_p = ftmp[0] ^ kPrime[0];
@ -1341,9 +1344,9 @@ static const felem gmul[16][3] =
0x0154536a0c6e966a, 0x037964d1286ee9fe, 0x0199bcd90e125055}, 0x0154536a0c6e966a, 0x037964d1286ee9fe, 0x0199bcd90e125055},
{1, 0, 0, 0, 0, 0, 0, 0, 0}}}; {1, 0, 0, 0, 0, 0, 0, 0, 0}}};
/* select_point selects the |index|th point from a precomputation table and /* select_point selects the |idx|th point from a precomputation table and
* copies it to out. */ * copies it to out. */
static void select_point(const limb index, unsigned int size, const felem pre_comp[size][3], static void select_point(const limb idx, unsigned int size, const felem pre_comp[/* size */][3],
felem out[3]) felem out[3])
{ {
unsigned i, j; unsigned i, j;
@ -1353,7 +1356,7 @@ static void select_point(const limb index, unsigned int size, const felem pre_co
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
{ {
const limb *inlimbs = &pre_comp[i][0][0]; const limb *inlimbs = &pre_comp[i][0][0];
limb mask = i ^ index; limb mask = i ^ idx;
mask |= mask >> 4; mask |= mask >> 4;
mask |= mask >> 2; mask |= mask >> 2;
mask |= mask >> 1; mask |= mask >> 1;
@ -1493,9 +1496,9 @@ const EC_METHOD *EC_GFp_nistp521_method(void)
ec_GFp_simple_get_Jprojective_coordinates_GFp, ec_GFp_simple_get_Jprojective_coordinates_GFp,
ec_GFp_simple_point_set_affine_coordinates, ec_GFp_simple_point_set_affine_coordinates,
ec_GFp_nistp521_point_get_affine_coordinates, ec_GFp_nistp521_point_get_affine_coordinates,
0 /* point_set_compressed_coordinates */, 0 /* point_set_compressed_coordinates */,
0 /* point2oct */, 0 /* point2oct */,
0 /* oct2point */, 0 /* oct2point */,
ec_GFp_simple_add, ec_GFp_simple_add,
ec_GFp_simple_dbl, ec_GFp_simple_dbl,
ec_GFp_simple_invert, ec_GFp_simple_invert,
@ -1663,7 +1666,7 @@ int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
return 1; return 1;
} }
static void make_points_affine(size_t num, felem points[num][3], felem tmp_felems[num+1]) static void make_points_affine(size_t num, felem points[/* num */][3], felem tmp_felems[/* num+1 */])
{ {
/* Runs in constant time, unless an input is the point at infinity /* Runs in constant time, unless an input is the point at infinity
* (which normally shouldn't happen). */ * (which normally shouldn't happen). */

View File

@ -18,7 +18,8 @@
* limitations under the License. * limitations under the License.
*/ */
#ifdef EC_NISTP_64_GCC_128 #include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
/* /*
* Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c. * Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c.

View File

@ -94,6 +94,7 @@ int main(int argc, char * argv[]) { puts("Elliptic curves are disabled."); retur
#include <openssl/objects.h> #include <openssl/objects.h>
#include <openssl/rand.h> #include <openssl/rand.h>
#include <openssl/bn.h> #include <openssl/bn.h>
#include <openssl/opensslconf.h>
#if defined(_MSC_VER) && defined(_MIPS_) && (_MSC_VER/100==12) #if defined(_MSC_VER) && defined(_MIPS_) && (_MSC_VER/100==12)
/* suppress "too big too optimize" warning */ /* suppress "too big too optimize" warning */
@ -1270,7 +1271,7 @@ static void internal_curve_test(void)
return; return;
} }
#ifdef EC_NISTP_64_GCC_128 #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
/* nistp_test_params contains magic numbers for testing our optimized /* nistp_test_params contains magic numbers for testing our optimized
* implementations of several NIST curves with characteristic > 3. */ * implementations of several NIST curves with characteristic > 3. */
struct nistp_test_params struct nistp_test_params
@ -1331,16 +1332,18 @@ static const struct nistp_test_params nistp_tests_params[] =
void nistp_single_test(const struct nistp_test_params *test) void nistp_single_test(const struct nistp_test_params *test)
{ {
fprintf(stdout, "\nNIST curve P-%d (optimised implementation):\n", test->degree); BN_CTX *ctx;
BIGNUM *p, *a, *b, *x, *y, *n, *m, *order; BIGNUM *p, *a, *b, *x, *y, *n, *m, *order;
EC_GROUP *NISTP;
EC_POINT *G, *P, *Q, *Q_CHECK;
fprintf(stdout, "\nNIST curve P-%d (optimised implementation):\n", test->degree);
ctx = BN_CTX_new();
p = BN_new(); p = BN_new();
a = BN_new(); a = BN_new();
b = BN_new(); b = BN_new();
x = BN_new(); y = BN_new(); x = BN_new(); y = BN_new();
m = BN_new(); n = BN_new(); order = BN_new(); m = BN_new(); n = BN_new(); order = BN_new();
BN_CTX *ctx = BN_CTX_new();
EC_GROUP *NISTP;
EC_POINT *G, *P, *Q, *Q_CHECK;
NISTP = EC_GROUP_new(test->meth()); NISTP = EC_GROUP_new(test->meth());
if(!NISTP) ABORT; if(!NISTP) ABORT;
@ -1467,7 +1470,7 @@ int main(int argc, char *argv[])
#ifndef OPENSSL_NO_EC2M #ifndef OPENSSL_NO_EC2M
char2_field_tests(); char2_field_tests();
#endif #endif
#ifdef EC_NISTP_64_GCC_128 #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
nistp_tests(); nistp_tests();
#endif #endif
/* test the internal curves */ /* test the internal curves */

View File

@ -86,8 +86,8 @@ my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF",
"SHA256", "SHA512", "RIPEMD", "SHA256", "SHA512", "RIPEMD",
"MDC2", "WHIRLPOOL", "RSA", "DSA", "DH", "EC", "ECDH", "ECDSA", "EC2M", "MDC2", "WHIRLPOOL", "RSA", "DSA", "DH", "EC", "ECDH", "ECDSA", "EC2M",
"HMAC", "AES", "CAMELLIA", "SEED", "GOST", "HMAC", "AES", "CAMELLIA", "SEED", "GOST",
# ECP_NISTP224 # EC_NISTP_64_GCC_128
"EC_NISTP224_64_GCC_128", "EC_NISTP_64_GCC_128",
# Envelope "algorithms" # Envelope "algorithms"
"EVP", "X509", "ASN1_TYPEDEFS", "EVP", "X509", "ASN1_TYPEDEFS",
# Helper "algorithms" # Helper "algorithms"
@ -1188,7 +1188,7 @@ sub is_valid
if ($keyword eq "PSK" && $no_psk) { return 0; } if ($keyword eq "PSK" && $no_psk) { return 0; }
if ($keyword eq "CMS" && $no_cms) { return 0; } if ($keyword eq "CMS" && $no_cms) { return 0; }
if ($keyword eq "EC2M" && $no_ec2m) { return 0; } if ($keyword eq "EC2M" && $no_ec2m) { return 0; }
if ($keyword eq "EC_NISTP224_64_GCC_128" && $no_nistp_gcc) if ($keyword eq "EC_NISTP_64_GCC_128" && $no_nistp_gcc)
{ return 0; } { return 0; }
if ($keyword eq "SSL2" && $no_ssl2) { return 0; } if ($keyword eq "SSL2" && $no_ssl2) { return 0; }
if ($keyword eq "CAPIENG" && $no_capieng) { return 0; } if ($keyword eq "CAPIENG" && $no_capieng) { return 0; }