Import OpenSSL 1.1.0f
This commit is contained in:
@@ -1,274 +0,0 @@
|
||||
#
|
||||
# crypto/ec/Makefile
|
||||
#
|
||||
|
||||
DIR= ec
|
||||
TOP= ../..
|
||||
CC= cc
|
||||
INCLUDES= -I.. -I$(TOP) -I../../include
|
||||
CFLAG=-g
|
||||
MAKEFILE= Makefile
|
||||
AR= ar r
|
||||
|
||||
CFLAGS= $(INCLUDES) $(CFLAG)
|
||||
ASFLAGS= $(INCLUDES) $(ASFLAG)
|
||||
AFLAGS= $(ASFLAGS)
|
||||
|
||||
GENERAL=Makefile
|
||||
TEST=ectest.c
|
||||
APPS=
|
||||
|
||||
LIB=$(TOP)/libcrypto.a
|
||||
LIBSRC= ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c\
|
||||
ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c\
|
||||
ec2_smpl.c ec2_mult.c ec_ameth.c ec_pmeth.c eck_prn.c \
|
||||
ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c \
|
||||
ecp_oct.c ec2_oct.c ec_oct.c
|
||||
|
||||
LIBOBJ= ec_lib.o ecp_smpl.o ecp_mont.o ecp_nist.o ec_cvt.o ec_mult.o\
|
||||
ec_err.o ec_curve.o ec_check.o ec_print.o ec_asn1.o ec_key.o\
|
||||
ec2_smpl.o ec2_mult.o ec_ameth.o ec_pmeth.o eck_prn.o \
|
||||
ecp_nistp224.o ecp_nistp256.o ecp_nistp521.o ecp_nistputil.o \
|
||||
ecp_oct.o ec2_oct.o ec_oct.o $(EC_ASM)
|
||||
|
||||
SRC= $(LIBSRC)
|
||||
|
||||
EXHEADER= ec.h
|
||||
HEADER= ec_lcl.h $(EXHEADER)
|
||||
|
||||
ALL= $(GENERAL) $(SRC) $(HEADER)
|
||||
|
||||
top:
|
||||
(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
|
||||
|
||||
all: lib
|
||||
|
||||
lib: $(LIBOBJ)
|
||||
$(AR) $(LIB) $(LIBOBJ)
|
||||
$(RANLIB) $(LIB) || echo Never mind.
|
||||
@touch lib
|
||||
|
||||
ecp_nistz256-x86_64.s: asm/ecp_nistz256-x86_64.pl
|
||||
$(PERL) asm/ecp_nistz256-x86_64.pl $(PERLASM_SCHEME) > $@
|
||||
|
||||
ecp_nistz256-avx2.s: asm/ecp_nistz256-avx2.pl
|
||||
$(PERL) asm/ecp_nistz256-avx2.pl $(PERLASM_SCHEME) > $@
|
||||
|
||||
files:
|
||||
$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
|
||||
|
||||
links:
|
||||
@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
|
||||
@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
|
||||
@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
|
||||
|
||||
install:
|
||||
@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
|
||||
@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
|
||||
do \
|
||||
(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
|
||||
chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
|
||||
done;
|
||||
|
||||
tags:
|
||||
ctags $(SRC)
|
||||
|
||||
tests:
|
||||
|
||||
lint:
|
||||
lint -DLINT $(INCLUDES) $(SRC)>fluff
|
||||
|
||||
update: depend
|
||||
|
||||
depend:
|
||||
@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
|
||||
$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
|
||||
|
||||
dclean:
|
||||
$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
|
||||
mv -f Makefile.new $(MAKEFILE)
|
||||
|
||||
clean:
|
||||
rm -f *.s *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
ec2_mult.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
ec2_mult.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
ec2_mult.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
ec2_mult.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
|
||||
ec2_mult.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
|
||||
ec2_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ec2_mult.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
ec2_mult.o: ../../include/openssl/symhacks.h ec2_mult.c ec_lcl.h
|
||||
ec2_oct.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
ec2_oct.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
ec2_oct.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
ec2_oct.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
|
||||
ec2_oct.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
|
||||
ec2_oct.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ec2_oct.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
ec2_oct.o: ../../include/openssl/symhacks.h ec2_oct.c ec_lcl.h
|
||||
ec2_smpl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
ec2_smpl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
ec2_smpl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
ec2_smpl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
|
||||
ec2_smpl.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
|
||||
ec2_smpl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ec2_smpl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
ec2_smpl.o: ../../include/openssl/symhacks.h ec2_smpl.c ec_lcl.h
|
||||
ec_ameth.o: ../../e_os.h ../../include/openssl/asn1.h
|
||||
ec_ameth.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
|
||||
ec_ameth.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
|
||||
ec_ameth.o: ../../include/openssl/cms.h ../../include/openssl/crypto.h
|
||||
ec_ameth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
ec_ameth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
|
||||
ec_ameth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
|
||||
ec_ameth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
|
||||
ec_ameth.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
|
||||
ec_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ec_ameth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
|
||||
ec_ameth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
|
||||
ec_ameth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
|
||||
ec_ameth.o: ../../include/openssl/x509_vfy.h ../asn1/asn1_locl.h ../cryptlib.h
|
||||
ec_ameth.o: ec_ameth.c ec_lcl.h
|
||||
ec_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
|
||||
ec_asn1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
|
||||
ec_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
|
||||
ec_asn1.o: ../../include/openssl/ec.h ../../include/openssl/err.h
|
||||
ec_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
|
||||
ec_asn1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
|
||||
ec_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ec_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
ec_asn1.o: ../../include/openssl/symhacks.h ec_asn1.c ec_lcl.h
|
||||
ec_check.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
ec_check.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
ec_check.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
ec_check.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
|
||||
ec_check.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
|
||||
ec_check.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ec_check.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
ec_check.o: ../../include/openssl/symhacks.h ec_check.c ec_lcl.h
|
||||
ec_curve.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
ec_curve.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
ec_curve.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
ec_curve.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
|
||||
ec_curve.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
|
||||
ec_curve.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ec_curve.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
ec_curve.o: ../../include/openssl/symhacks.h ec_curve.c ec_lcl.h
|
||||
ec_cvt.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
ec_cvt.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
ec_cvt.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
ec_cvt.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
|
||||
ec_cvt.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
|
||||
ec_cvt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ec_cvt.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
ec_cvt.o: ../../include/openssl/symhacks.h ec_cvt.c ec_lcl.h
|
||||
ec_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
ec_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
|
||||
ec_err.o: ../../include/openssl/ec.h ../../include/openssl/err.h
|
||||
ec_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
|
||||
ec_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ec_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
ec_err.o: ../../include/openssl/symhacks.h ec_err.c
|
||||
ec_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
ec_key.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
ec_key.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
ec_key.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
|
||||
ec_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
|
||||
ec_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ec_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
ec_key.o: ../../include/openssl/symhacks.h ec_key.c ec_lcl.h
|
||||
ec_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
ec_lib.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
ec_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
ec_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
|
||||
ec_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
|
||||
ec_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ec_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
ec_lib.o: ../../include/openssl/symhacks.h ec_lcl.h ec_lib.c
|
||||
ec_mult.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
ec_mult.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
ec_mult.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
ec_mult.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
|
||||
ec_mult.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
|
||||
ec_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ec_mult.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
ec_mult.o: ../../include/openssl/symhacks.h ec_lcl.h ec_mult.c
|
||||
ec_oct.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
ec_oct.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
ec_oct.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
ec_oct.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
|
||||
ec_oct.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
|
||||
ec_oct.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ec_oct.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
ec_oct.o: ../../include/openssl/symhacks.h ec_lcl.h ec_oct.c
|
||||
ec_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
|
||||
ec_pmeth.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
|
||||
ec_pmeth.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
|
||||
ec_pmeth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
|
||||
ec_pmeth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
|
||||
ec_pmeth.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
|
||||
ec_pmeth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
|
||||
ec_pmeth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
|
||||
ec_pmeth.o: ../../include/openssl/opensslconf.h
|
||||
ec_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ec_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
|
||||
ec_pmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
|
||||
ec_pmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
|
||||
ec_pmeth.o: ../../include/openssl/x509_vfy.h ../cryptlib.h ../evp/evp_locl.h
|
||||
ec_pmeth.o: ec_lcl.h ec_pmeth.c
|
||||
ec_print.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
ec_print.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
ec_print.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
ec_print.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
|
||||
ec_print.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ec_print.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
ec_print.o: ../../include/openssl/symhacks.h ec_lcl.h ec_print.c
|
||||
eck_prn.o: ../../e_os.h ../../include/openssl/asn1.h
|
||||
eck_prn.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
|
||||
eck_prn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
|
||||
eck_prn.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
eck_prn.o: ../../include/openssl/err.h ../../include/openssl/evp.h
|
||||
eck_prn.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
|
||||
eck_prn.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
|
||||
eck_prn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
eck_prn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
eck_prn.o: ../../include/openssl/symhacks.h ../cryptlib.h eck_prn.c
|
||||
ecp_mont.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
ecp_mont.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
ecp_mont.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
ecp_mont.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
|
||||
ecp_mont.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
|
||||
ecp_mont.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ecp_mont.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
ecp_mont.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_mont.c
|
||||
ecp_nist.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
ecp_nist.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
ecp_nist.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
ecp_nist.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
|
||||
ecp_nist.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
|
||||
ecp_nist.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ecp_nist.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
ecp_nist.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_nist.c
|
||||
ecp_nistp224.o: ../../include/openssl/opensslconf.h ecp_nistp224.c
|
||||
ecp_nistp256.o: ../../include/openssl/opensslconf.h ecp_nistp256.c
|
||||
ecp_nistp521.o: ../../include/openssl/opensslconf.h ecp_nistp521.c
|
||||
ecp_nistputil.o: ../../include/openssl/opensslconf.h ecp_nistputil.c
|
||||
ecp_oct.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
ecp_oct.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
ecp_oct.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
ecp_oct.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
|
||||
ecp_oct.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
|
||||
ecp_oct.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ecp_oct.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
ecp_oct.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_oct.c
|
||||
ecp_smpl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||
ecp_smpl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
|
||||
ecp_smpl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||
ecp_smpl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
|
||||
ecp_smpl.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
|
||||
ecp_smpl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||
ecp_smpl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
|
||||
ecp_smpl.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_smpl.c
|
||||
1865
crypto/ec/asm/ecp_nistz256-armv4.pl
Normal file
1865
crypto/ec/asm/ecp_nistz256-armv4.pl
Normal file
File diff suppressed because it is too large
Load Diff
1558
crypto/ec/asm/ecp_nistz256-armv8.pl
Normal file
1558
crypto/ec/asm/ecp_nistz256-armv8.pl
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,11 @@
|
||||
#!/usr/bin/env perl
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2014-2016 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
|
||||
|
||||
|
||||
##############################################################################
|
||||
# #
|
||||
@@ -149,7 +156,7 @@ $code.=<<___;
|
||||
___
|
||||
|
||||
{
|
||||
# This function recieves a pointer to an array of four affine points
|
||||
# This function receives a pointer to an array of four affine points
|
||||
# (X, Y, <1>) and rearanges the data for AVX2 execution, while
|
||||
# converting it to 2^29 radix redundant form
|
||||
|
||||
@@ -301,7 +308,7 @@ ___
|
||||
}
|
||||
{
|
||||
################################################################################
|
||||
# This function recieves a pointer to an array of four AVX2 formatted points
|
||||
# This function receives a pointer to an array of four AVX2 formatted points
|
||||
# (X, Y, Z) convert the data to normal representation, and rearanges the data
|
||||
|
||||
my ($D0,$D1,$D2,$D3, $D4,$D5,$D6,$D7, $D8)=map("%ymm$_",(0..8));
|
||||
@@ -1909,7 +1916,7 @@ ___
|
||||
}
|
||||
{
|
||||
################################################################################
|
||||
# void ecp_nistz256_avx2_multi_select_w7(void* RESULT, void *in,
|
||||
# void ecp_nistz256_avx2_multi_gather_w7(void* RESULT, void *in,
|
||||
# int index0, int index1, int index2, int index3);
|
||||
################################################################################
|
||||
|
||||
@@ -1919,10 +1926,10 @@ my ($R0a,$R0b,$R1a,$R1b,$R2a,$R2b,$R3a,$R3b)=map("%ymm$_",(4..11));
|
||||
my ($M0,$T0,$T1,$TMP0)=map("%ymm$_",(12..15));
|
||||
|
||||
$code.=<<___;
|
||||
.globl ecp_nistz256_avx2_multi_select_w7
|
||||
.type ecp_nistz256_avx2_multi_select_w7,\@function,6
|
||||
.globl ecp_nistz256_avx2_multi_gather_w7
|
||||
.type ecp_nistz256_avx2_multi_gather_w7,\@function,6
|
||||
.align 32
|
||||
ecp_nistz256_avx2_multi_select_w7:
|
||||
ecp_nistz256_avx2_multi_gather_w7:
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
@@ -2036,7 +2043,7 @@ $code.=<<___ if ($win64);
|
||||
___
|
||||
$code.=<<___;
|
||||
ret
|
||||
.size ecp_nistz256_avx2_multi_select_w7,.-ecp_nistz256_avx2_multi_select_w7
|
||||
.size ecp_nistz256_avx2_multi_gather_w7,.-ecp_nistz256_avx2_multi_gather_w7
|
||||
|
||||
.extern OPENSSL_ia32cap_P
|
||||
.globl ecp_nistz_avx2_eligible
|
||||
@@ -2061,8 +2068,8 @@ $code.=<<___;
|
||||
.globl ecp_nistz256_avx2_to_mont
|
||||
.globl ecp_nistz256_avx2_from_mont
|
||||
.globl ecp_nistz256_avx2_set1
|
||||
.globl ecp_nistz256_avx2_multi_select_w7
|
||||
.type ecp_nistz256_avx2_multi_select_w7,\@abi-omnipotent
|
||||
.globl ecp_nistz256_avx2_multi_gather_w7
|
||||
.type ecp_nistz256_avx2_multi_gather_w7,\@abi-omnipotent
|
||||
ecp_nistz256_avx2_transpose_convert:
|
||||
ecp_nistz256_avx2_convert_transpose_back:
|
||||
ecp_nistz256_avx2_point_add_affine_x4:
|
||||
@@ -2070,10 +2077,10 @@ ecp_nistz256_avx2_point_add_affines_x4:
|
||||
ecp_nistz256_avx2_to_mont:
|
||||
ecp_nistz256_avx2_from_mont:
|
||||
ecp_nistz256_avx2_set1:
|
||||
ecp_nistz256_avx2_multi_select_w7:
|
||||
ecp_nistz256_avx2_multi_gather_w7:
|
||||
.byte 0x0f,0x0b # ud2
|
||||
ret
|
||||
.size ecp_nistz256_avx2_multi_select_w7,.-ecp_nistz256_avx2_multi_select_w7
|
||||
.size ecp_nistz256_avx2_multi_gather_w7,.-ecp_nistz256_avx2_multi_gather_w7
|
||||
|
||||
.globl ecp_nistz_avx2_eligible
|
||||
.type ecp_nistz_avx2_eligible,\@abi-omnipotent
|
||||
|
||||
3061
crypto/ec/asm/ecp_nistz256-sparcv9.pl
Normal file
3061
crypto/ec/asm/ecp_nistz256-sparcv9.pl
Normal file
File diff suppressed because it is too large
Load Diff
1866
crypto/ec/asm/ecp_nistz256-x86.pl
Normal file
1866
crypto/ec/asm/ecp_nistz256-x86.pl
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,11 @@
|
||||
#!/usr/bin/env perl
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2014-2016 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
|
||||
|
||||
|
||||
##############################################################################
|
||||
# #
|
||||
@@ -60,7 +67,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
||||
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
|
||||
die "can't locate x86_64-xlate.pl";
|
||||
|
||||
open OUT,"| \"$^X\" $xlate $flavour $output";
|
||||
open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
|
||||
*STDOUT=*OUT;
|
||||
|
||||
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
|
||||
@@ -1371,20 +1378,44 @@ my ($M1,$T2a,$T2b,$TMP2,$M2,$T2a,$T2b,$TMP2)=map("%xmm$_",(8..15));
|
||||
|
||||
$code.=<<___;
|
||||
################################################################################
|
||||
# void ecp_nistz256_select_w5(uint64_t *val, uint64_t *in_t, int index);
|
||||
.globl ecp_nistz256_select_w5
|
||||
.type ecp_nistz256_select_w5,\@abi-omnipotent
|
||||
# void ecp_nistz256_scatter_w5(uint64_t *val, uint64_t *in_t, int index);
|
||||
.globl ecp_nistz256_scatter_w5
|
||||
.type ecp_nistz256_scatter_w5,\@abi-omnipotent
|
||||
.align 32
|
||||
ecp_nistz256_select_w5:
|
||||
ecp_nistz256_scatter_w5:
|
||||
lea -3($index,$index,2), $index
|
||||
movdqa 0x00($in_t), %xmm0
|
||||
shl \$5, $index
|
||||
movdqa 0x10($in_t), %xmm1
|
||||
movdqa 0x20($in_t), %xmm2
|
||||
movdqa 0x30($in_t), %xmm3
|
||||
movdqa 0x40($in_t), %xmm4
|
||||
movdqa 0x50($in_t), %xmm5
|
||||
movdqa %xmm0, 0x00($val,$index)
|
||||
movdqa %xmm1, 0x10($val,$index)
|
||||
movdqa %xmm2, 0x20($val,$index)
|
||||
movdqa %xmm3, 0x30($val,$index)
|
||||
movdqa %xmm4, 0x40($val,$index)
|
||||
movdqa %xmm5, 0x50($val,$index)
|
||||
|
||||
ret
|
||||
.size ecp_nistz256_scatter_w5,.-ecp_nistz256_scatter_w5
|
||||
|
||||
################################################################################
|
||||
# void ecp_nistz256_gather_w5(uint64_t *val, uint64_t *in_t, int index);
|
||||
.globl ecp_nistz256_gather_w5
|
||||
.type ecp_nistz256_gather_w5,\@abi-omnipotent
|
||||
.align 32
|
||||
ecp_nistz256_gather_w5:
|
||||
___
|
||||
$code.=<<___ if ($avx>1);
|
||||
mov OPENSSL_ia32cap_P+8(%rip), %eax
|
||||
test \$`1<<5`, %eax
|
||||
jnz .Lavx2_select_w5
|
||||
jnz .Lavx2_gather_w5
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -0x88(%rsp), %rax
|
||||
.LSEH_begin_ecp_nistz256_select_w5:
|
||||
.LSEH_begin_ecp_nistz256_gather_w5:
|
||||
.byte 0x48,0x8d,0x60,0xe0 #lea -0x20(%rax), %rsp
|
||||
.byte 0x0f,0x29,0x70,0xe0 #movaps %xmm6, -0x20(%rax)
|
||||
.byte 0x0f,0x29,0x78,0xf0 #movaps %xmm7, -0x10(%rax)
|
||||
@@ -1461,27 +1492,46 @@ $code.=<<___ if ($win64);
|
||||
movaps 0x80(%rsp), %xmm14
|
||||
movaps 0x90(%rsp), %xmm15
|
||||
lea 0xa8(%rsp), %rsp
|
||||
.LSEH_end_ecp_nistz256_select_w5:
|
||||
.LSEH_end_ecp_nistz256_gather_w5:
|
||||
___
|
||||
$code.=<<___;
|
||||
ret
|
||||
.size ecp_nistz256_select_w5,.-ecp_nistz256_select_w5
|
||||
.size ecp_nistz256_gather_w5,.-ecp_nistz256_gather_w5
|
||||
|
||||
################################################################################
|
||||
# void ecp_nistz256_select_w7(uint64_t *val, uint64_t *in_t, int index);
|
||||
.globl ecp_nistz256_select_w7
|
||||
.type ecp_nistz256_select_w7,\@abi-omnipotent
|
||||
# void ecp_nistz256_scatter_w7(uint64_t *val, uint64_t *in_t, int index);
|
||||
.globl ecp_nistz256_scatter_w7
|
||||
.type ecp_nistz256_scatter_w7,\@abi-omnipotent
|
||||
.align 32
|
||||
ecp_nistz256_select_w7:
|
||||
ecp_nistz256_scatter_w7:
|
||||
movdqu 0x00($in_t), %xmm0
|
||||
shl \$6, $index
|
||||
movdqu 0x10($in_t), %xmm1
|
||||
movdqu 0x20($in_t), %xmm2
|
||||
movdqu 0x30($in_t), %xmm3
|
||||
movdqa %xmm0, 0x00($val,$index)
|
||||
movdqa %xmm1, 0x10($val,$index)
|
||||
movdqa %xmm2, 0x20($val,$index)
|
||||
movdqa %xmm3, 0x30($val,$index)
|
||||
|
||||
ret
|
||||
.size ecp_nistz256_scatter_w7,.-ecp_nistz256_scatter_w7
|
||||
|
||||
################################################################################
|
||||
# void ecp_nistz256_gather_w7(uint64_t *val, uint64_t *in_t, int index);
|
||||
.globl ecp_nistz256_gather_w7
|
||||
.type ecp_nistz256_gather_w7,\@abi-omnipotent
|
||||
.align 32
|
||||
ecp_nistz256_gather_w7:
|
||||
___
|
||||
$code.=<<___ if ($avx>1);
|
||||
mov OPENSSL_ia32cap_P+8(%rip), %eax
|
||||
test \$`1<<5`, %eax
|
||||
jnz .Lavx2_select_w7
|
||||
jnz .Lavx2_gather_w7
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -0x88(%rsp), %rax
|
||||
.LSEH_begin_ecp_nistz256_select_w7:
|
||||
.LSEH_begin_ecp_nistz256_gather_w7:
|
||||
.byte 0x48,0x8d,0x60,0xe0 #lea -0x20(%rax), %rsp
|
||||
.byte 0x0f,0x29,0x70,0xe0 #movaps %xmm6, -0x20(%rax)
|
||||
.byte 0x0f,0x29,0x78,0xf0 #movaps %xmm7, -0x10(%rax)
|
||||
@@ -1547,11 +1597,11 @@ $code.=<<___ if ($win64);
|
||||
movaps 0x80(%rsp), %xmm14
|
||||
movaps 0x90(%rsp), %xmm15
|
||||
lea 0xa8(%rsp), %rsp
|
||||
.LSEH_end_ecp_nistz256_select_w7:
|
||||
.LSEH_end_ecp_nistz256_gather_w7:
|
||||
___
|
||||
$code.=<<___;
|
||||
ret
|
||||
.size ecp_nistz256_select_w7,.-ecp_nistz256_select_w7
|
||||
.size ecp_nistz256_gather_w7,.-ecp_nistz256_gather_w7
|
||||
___
|
||||
}
|
||||
if ($avx>1) {
|
||||
@@ -1562,16 +1612,16 @@ my ($M1,$T1a,$T1b,$T1c,$TMP1)=map("%ymm$_",(10..14));
|
||||
|
||||
$code.=<<___;
|
||||
################################################################################
|
||||
# void ecp_nistz256_avx2_select_w5(uint64_t *val, uint64_t *in_t, int index);
|
||||
.type ecp_nistz256_avx2_select_w5,\@abi-omnipotent
|
||||
# void ecp_nistz256_avx2_gather_w5(uint64_t *val, uint64_t *in_t, int index);
|
||||
.type ecp_nistz256_avx2_gather_w5,\@abi-omnipotent
|
||||
.align 32
|
||||
ecp_nistz256_avx2_select_w5:
|
||||
.Lavx2_select_w5:
|
||||
ecp_nistz256_avx2_gather_w5:
|
||||
.Lavx2_gather_w5:
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -0x88(%rsp), %rax
|
||||
.LSEH_begin_ecp_nistz256_avx2_select_w5:
|
||||
.LSEH_begin_ecp_nistz256_avx2_gather_w5:
|
||||
.byte 0x48,0x8d,0x60,0xe0 #lea -0x20(%rax), %rsp
|
||||
.byte 0xc5,0xf8,0x29,0x70,0xe0 #vmovaps %xmm6, -0x20(%rax)
|
||||
.byte 0xc5,0xf8,0x29,0x78,0xf0 #vmovaps %xmm7, -0x10(%rax)
|
||||
@@ -1649,11 +1699,11 @@ $code.=<<___ if ($win64);
|
||||
movaps 0x80(%rsp), %xmm14
|
||||
movaps 0x90(%rsp), %xmm15
|
||||
lea 0xa8(%rsp), %rsp
|
||||
.LSEH_end_ecp_nistz256_avx2_select_w5:
|
||||
.LSEH_end_ecp_nistz256_avx2_gather_w5:
|
||||
___
|
||||
$code.=<<___;
|
||||
ret
|
||||
.size ecp_nistz256_avx2_select_w5,.-ecp_nistz256_avx2_select_w5
|
||||
.size ecp_nistz256_avx2_gather_w5,.-ecp_nistz256_avx2_gather_w5
|
||||
___
|
||||
}
|
||||
if ($avx>1) {
|
||||
@@ -1666,17 +1716,17 @@ my ($M2,$T2a,$T2b,$TMP2)=map("%ymm$_",(12..15));
|
||||
$code.=<<___;
|
||||
|
||||
################################################################################
|
||||
# void ecp_nistz256_avx2_select_w7(uint64_t *val, uint64_t *in_t, int index);
|
||||
.globl ecp_nistz256_avx2_select_w7
|
||||
.type ecp_nistz256_avx2_select_w7,\@abi-omnipotent
|
||||
# void ecp_nistz256_avx2_gather_w7(uint64_t *val, uint64_t *in_t, int index);
|
||||
.globl ecp_nistz256_avx2_gather_w7
|
||||
.type ecp_nistz256_avx2_gather_w7,\@abi-omnipotent
|
||||
.align 32
|
||||
ecp_nistz256_avx2_select_w7:
|
||||
.Lavx2_select_w7:
|
||||
ecp_nistz256_avx2_gather_w7:
|
||||
.Lavx2_gather_w7:
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -0x88(%rsp), %rax
|
||||
.LSEH_begin_ecp_nistz256_avx2_select_w7:
|
||||
.LSEH_begin_ecp_nistz256_avx2_gather_w7:
|
||||
.byte 0x48,0x8d,0x60,0xe0 #lea -0x20(%rax), %rsp
|
||||
.byte 0xc5,0xf8,0x29,0x70,0xe0 #vmovaps %xmm6, -0x20(%rax)
|
||||
.byte 0xc5,0xf8,0x29,0x78,0xf0 #vmovaps %xmm7, -0x10(%rax)
|
||||
@@ -1769,21 +1819,21 @@ $code.=<<___ if ($win64);
|
||||
movaps 0x80(%rsp), %xmm14
|
||||
movaps 0x90(%rsp), %xmm15
|
||||
lea 0xa8(%rsp), %rsp
|
||||
.LSEH_end_ecp_nistz256_avx2_select_w7:
|
||||
.LSEH_end_ecp_nistz256_avx2_gather_w7:
|
||||
___
|
||||
$code.=<<___;
|
||||
ret
|
||||
.size ecp_nistz256_avx2_select_w7,.-ecp_nistz256_avx2_select_w7
|
||||
.size ecp_nistz256_avx2_gather_w7,.-ecp_nistz256_avx2_gather_w7
|
||||
___
|
||||
} else {
|
||||
$code.=<<___;
|
||||
.globl ecp_nistz256_avx2_select_w7
|
||||
.type ecp_nistz256_avx2_select_w7,\@function,3
|
||||
.globl ecp_nistz256_avx2_gather_w7
|
||||
.type ecp_nistz256_avx2_gather_w7,\@function,3
|
||||
.align 32
|
||||
ecp_nistz256_avx2_select_w7:
|
||||
ecp_nistz256_avx2_gather_w7:
|
||||
.byte 0x0f,0x0b # ud2
|
||||
ret
|
||||
.size ecp_nistz256_avx2_select_w7,.-ecp_nistz256_avx2_select_w7
|
||||
.size ecp_nistz256_avx2_gather_w7,.-ecp_nistz256_avx2_gather_w7
|
||||
___
|
||||
}
|
||||
{{{
|
||||
@@ -3002,6 +3052,36 @@ ___
|
||||
}
|
||||
}}}
|
||||
|
||||
########################################################################
|
||||
# Convert ecp_nistz256_table.c to layout expected by ecp_nistz_gather_w7
|
||||
#
|
||||
open TABLE,"<ecp_nistz256_table.c" or
|
||||
open TABLE,"<${dir}../ecp_nistz256_table.c" or
|
||||
die "failed to open ecp_nistz256_table.c:",$!;
|
||||
|
||||
use integer;
|
||||
|
||||
foreach(<TABLE>) {
|
||||
s/TOBN\(\s*(0x[0-9a-f]+),\s*(0x[0-9a-f]+)\s*\)/push @arr,hex($2),hex($1)/geo;
|
||||
}
|
||||
close TABLE;
|
||||
|
||||
die "insane number of elements" if ($#arr != 64*16*37-1);
|
||||
|
||||
print <<___;
|
||||
.text
|
||||
.globl ecp_nistz256_precomputed
|
||||
.type ecp_nistz256_precomputed,\@object
|
||||
.align 4096
|
||||
ecp_nistz256_precomputed:
|
||||
___
|
||||
while (@line=splice(@arr,0,16)) {
|
||||
print ".long\t",join(',',map { sprintf "0x%08x",$_} @line),"\n";
|
||||
}
|
||||
print <<___;
|
||||
.size ecp_nistz256_precomputed,.-ecp_nistz256_precomputed
|
||||
___
|
||||
|
||||
$code =~ s/\`([^\`]*)\`/eval $1/gem;
|
||||
print $code;
|
||||
close STDOUT;
|
||||
|
||||
28
crypto/ec/build.info
Normal file
28
crypto/ec/build.info
Normal file
@@ -0,0 +1,28 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=\
|
||||
ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \
|
||||
ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c \
|
||||
ec2_smpl.c ec2_mult.c ec_ameth.c ec_pmeth.c eck_prn.c \
|
||||
ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c \
|
||||
ecp_oct.c ec2_oct.c ec_oct.c ec_kmeth.c ecdh_ossl.c ecdh_kdf.c \
|
||||
ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c curve25519.c ecx_meth.c \
|
||||
{- $target{ec_asm_src} -}
|
||||
|
||||
GENERATE[ecp_nistz256-x86.s]=asm/ecp_nistz256-x86.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
|
||||
|
||||
GENERATE[ecp_nistz256-x86_64.s]=asm/ecp_nistz256-x86_64.pl $(PERLASM_SCHEME)
|
||||
|
||||
GENERATE[ecp_nistz256-avx2.s]=asm/ecp_nistz256-avx2.pl $(PERLASM_SCHEME)
|
||||
|
||||
GENERATE[ecp_nistz256-sparcv9.S]=asm/ecp_nistz256-sparcv9.pl $(PERLASM_SCHEME)
|
||||
INCLUDE[ecp_nistz256-sparcv9.o]=..
|
||||
|
||||
GENERATE[ecp_nistz256-armv4.S]=asm/ecp_nistz256-armv4.pl $(PERLASM_SCHEME)
|
||||
INCLUDE[ecp_nistz256-armv4.o]=..
|
||||
GENERATE[ecp_nistz256-armv8.S]=asm/ecp_nistz256-armv8.pl $(PERLASM_SCHEME)
|
||||
INCLUDE[ecp_nistz256-armv8.o]=..
|
||||
|
||||
BEGINRAW[Makefile]
|
||||
{- $builddir -}/ecp_nistz256-%.S: {- $sourcedir -}/asm/ecp_nistz256-%.pl
|
||||
CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
|
||||
ENDRAW[Makefile]
|
||||
3394
crypto/ec/curve25519.c
Normal file
3394
crypto/ec/curve25519.c
Normal file
File diff suppressed because it is too large
Load Diff
1282
crypto/ec/ec.h
1282
crypto/ec/ec.h
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,12 @@
|
||||
/* crypto/ec/ec2_mult.c */
|
||||
/*
|
||||
* Copyright 2002-2016 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
*
|
||||
@@ -13,62 +21,10 @@
|
||||
* Douglas Stebila of Sun Microsystems Laboratories.
|
||||
*
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "internal/bn_int.h"
|
||||
#include "ec_lcl.h"
|
||||
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
@@ -103,7 +59,7 @@ static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z,
|
||||
goto err;
|
||||
if (!group->meth->field_sqr(group, t1, t1, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, t1, &group->b, t1, ctx))
|
||||
if (!group->meth->field_mul(group, t1, group->b, t1, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(x, x, t1))
|
||||
goto err;
|
||||
@@ -294,17 +250,17 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group,
|
||||
if (z1 == NULL)
|
||||
goto err;
|
||||
|
||||
x2 = &r->X;
|
||||
z2 = &r->Y;
|
||||
x2 = r->X;
|
||||
z2 = r->Y;
|
||||
|
||||
group_top = group->field.top;
|
||||
group_top = bn_get_top(group->field);
|
||||
if (bn_wexpand(x1, group_top) == NULL
|
||||
|| bn_wexpand(z1, group_top) == NULL
|
||||
|| bn_wexpand(x2, group_top) == NULL
|
||||
|| bn_wexpand(z2, group_top) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_GF2m_mod_arr(x1, &point->X, group->poly))
|
||||
if (!BN_GF2m_mod_arr(x1, point->X, group->poly))
|
||||
goto err; /* x1 = x */
|
||||
if (!BN_one(z1))
|
||||
goto err; /* z1 = 1 */
|
||||
@@ -312,13 +268,13 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group,
|
||||
goto err; /* z2 = x1^2 = x^2 */
|
||||
if (!group->meth->field_sqr(group, x2, z2, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(x2, x2, &group->b))
|
||||
if (!BN_GF2m_add(x2, x2, group->b))
|
||||
goto err; /* x2 = x^4 + b */
|
||||
|
||||
/* find top most bit and go one past it */
|
||||
i = scalar->top - 1;
|
||||
i = bn_get_top(scalar) - 1;
|
||||
mask = BN_TBIT;
|
||||
word = scalar->d[i];
|
||||
word = bn_get_words(scalar)[i];
|
||||
while (!(word & mask))
|
||||
mask >>= 1;
|
||||
mask >>= 1;
|
||||
@@ -329,11 +285,11 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group,
|
||||
}
|
||||
|
||||
for (; i >= 0; i--) {
|
||||
word = scalar->d[i];
|
||||
word = bn_get_words(scalar)[i];
|
||||
while (mask) {
|
||||
BN_consttime_swap(word & mask, x1, x2, group_top);
|
||||
BN_consttime_swap(word & mask, z1, z2, group_top);
|
||||
if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx))
|
||||
if (!gf2m_Madd(group, point->X, x2, z2, x1, z1, ctx))
|
||||
goto err;
|
||||
if (!gf2m_Mdouble(group, x1, z1, ctx))
|
||||
goto err;
|
||||
@@ -345,21 +301,21 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group,
|
||||
}
|
||||
|
||||
/* convert out of "projective" coordinates */
|
||||
i = gf2m_Mxy(group, &point->X, &point->Y, x1, z1, x2, z2, ctx);
|
||||
i = gf2m_Mxy(group, point->X, point->Y, x1, z1, x2, z2, ctx);
|
||||
if (i == 0)
|
||||
goto err;
|
||||
else if (i == 1) {
|
||||
if (!EC_POINT_set_to_infinity(group, r))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_one(&r->Z))
|
||||
if (!BN_one(r->Z))
|
||||
goto err;
|
||||
r->Z_is_one = 1;
|
||||
}
|
||||
|
||||
/* GF(2^m) field elements should always have BIGNUM::neg = 0 */
|
||||
BN_set_negative(&r->X, 0);
|
||||
BN_set_negative(&r->Y, 0);
|
||||
BN_set_negative(r->X, 0);
|
||||
BN_set_negative(r->Y, 0);
|
||||
|
||||
ret = 1;
|
||||
|
||||
@@ -438,12 +394,9 @@ int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (p)
|
||||
EC_POINT_free(p);
|
||||
if (acc)
|
||||
EC_POINT_free(acc);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
EC_POINT_free(p);
|
||||
EC_POINT_free(acc);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
/* crypto/ec/ec2_oct.c */
|
||||
/*
|
||||
* Copyright 2011-2016 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
*
|
||||
@@ -13,59 +21,6 @@
|
||||
* Douglas Stebila of Sun Microsystems Laboratories.
|
||||
*
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
@@ -120,14 +75,14 @@ int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group,
|
||||
if (!BN_GF2m_mod_arr(x, x_, group->poly))
|
||||
goto err;
|
||||
if (BN_is_zero(x)) {
|
||||
if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx))
|
||||
if (!BN_GF2m_mod_sqrt_arr(y, group->b, group->poly, ctx))
|
||||
goto err;
|
||||
} else {
|
||||
if (!group->meth->field_sqr(group, tmp, x, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx))
|
||||
if (!group->meth->field_div(group, tmp, group->b, tmp, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(tmp, &group->a, tmp))
|
||||
if (!BN_GF2m_add(tmp, group->a, tmp))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(tmp, x, tmp))
|
||||
goto err;
|
||||
@@ -160,8 +115,7 @@ int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group,
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -278,15 +232,13 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
|
||||
|
||||
if (used_ctx)
|
||||
BN_CTX_end(ctx);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
|
||||
err:
|
||||
if (used_ctx)
|
||||
BN_CTX_end(ctx);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -357,7 +309,7 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
||||
|
||||
if (!BN_bin2bn(buf + 1, field_len, x))
|
||||
goto err;
|
||||
if (BN_ucmp(x, &group->field) >= 0) {
|
||||
if (BN_ucmp(x, group->field) >= 0) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
goto err;
|
||||
}
|
||||
@@ -369,7 +321,7 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
||||
} else {
|
||||
if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
|
||||
goto err;
|
||||
if (BN_ucmp(y, &group->field) >= 0) {
|
||||
if (BN_ucmp(y, group->field) >= 0) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
goto err;
|
||||
}
|
||||
@@ -382,22 +334,19 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* EC_POINT_set_affine_coordinates_GF2m is responsible for checking that
|
||||
* the point is on the curve.
|
||||
*/
|
||||
if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* test required by X9.62 */
|
||||
if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
/* crypto/ec/ec2_smpl.c */
|
||||
/*
|
||||
* Copyright 2002-2016 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
*
|
||||
@@ -13,70 +21,14 @@
|
||||
* Douglas Stebila of Sun Microsystems Laboratories.
|
||||
*
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "internal/bn_int.h"
|
||||
#include "ec_lcl.h"
|
||||
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
|
||||
# ifdef OPENSSL_FIPS
|
||||
# include <openssl/fips.h>
|
||||
# endif
|
||||
|
||||
const EC_METHOD *EC_GF2m_simple_method(void)
|
||||
{
|
||||
static const EC_METHOD ret = {
|
||||
@@ -89,6 +41,7 @@ const EC_METHOD *EC_GF2m_simple_method(void)
|
||||
ec_GF2m_simple_group_set_curve,
|
||||
ec_GF2m_simple_group_get_curve,
|
||||
ec_GF2m_simple_group_get_degree,
|
||||
ec_group_simple_order_bits,
|
||||
ec_GF2m_simple_group_check_discriminant,
|
||||
ec_GF2m_simple_point_init,
|
||||
ec_GF2m_simple_point_finish,
|
||||
@@ -121,14 +74,18 @@ const EC_METHOD *EC_GF2m_simple_method(void)
|
||||
ec_GF2m_simple_field_div,
|
||||
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
|
||||
};
|
||||
|
||||
# ifdef OPENSSL_FIPS
|
||||
if (FIPS_mode())
|
||||
return fips_ec_gf2m_simple_method();
|
||||
# endif
|
||||
|
||||
return &ret;
|
||||
}
|
||||
|
||||
@@ -138,9 +95,16 @@ const EC_METHOD *EC_GF2m_simple_method(void)
|
||||
*/
|
||||
int ec_GF2m_simple_group_init(EC_GROUP *group)
|
||||
{
|
||||
BN_init(&group->field);
|
||||
BN_init(&group->a);
|
||||
BN_init(&group->b);
|
||||
group->field = BN_new();
|
||||
group->a = BN_new();
|
||||
group->b = BN_new();
|
||||
|
||||
if (group->field == NULL || group->a == NULL || group->b == NULL) {
|
||||
BN_free(group->field);
|
||||
BN_free(group->a);
|
||||
BN_free(group->b);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -150,9 +114,9 @@ int ec_GF2m_simple_group_init(EC_GROUP *group)
|
||||
*/
|
||||
void ec_GF2m_simple_group_finish(EC_GROUP *group)
|
||||
{
|
||||
BN_free(&group->field);
|
||||
BN_free(&group->a);
|
||||
BN_free(&group->b);
|
||||
BN_free(group->field);
|
||||
BN_free(group->a);
|
||||
BN_free(group->b);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -161,9 +125,9 @@ void ec_GF2m_simple_group_finish(EC_GROUP *group)
|
||||
*/
|
||||
void ec_GF2m_simple_group_clear_finish(EC_GROUP *group)
|
||||
{
|
||||
BN_clear_free(&group->field);
|
||||
BN_clear_free(&group->a);
|
||||
BN_clear_free(&group->b);
|
||||
BN_clear_free(group->field);
|
||||
BN_clear_free(group->a);
|
||||
BN_clear_free(group->b);
|
||||
group->poly[0] = 0;
|
||||
group->poly[1] = 0;
|
||||
group->poly[2] = 0;
|
||||
@@ -178,12 +142,11 @@ void ec_GF2m_simple_group_clear_finish(EC_GROUP *group)
|
||||
*/
|
||||
int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
|
||||
{
|
||||
int i;
|
||||
if (!BN_copy(&dest->field, &src->field))
|
||||
if (!BN_copy(dest->field, src->field))
|
||||
return 0;
|
||||
if (!BN_copy(&dest->a, &src->a))
|
||||
if (!BN_copy(dest->a, src->a))
|
||||
return 0;
|
||||
if (!BN_copy(&dest->b, &src->b))
|
||||
if (!BN_copy(dest->b, src->b))
|
||||
return 0;
|
||||
dest->poly[0] = src->poly[0];
|
||||
dest->poly[1] = src->poly[1];
|
||||
@@ -191,16 +154,14 @@ int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
|
||||
dest->poly[3] = src->poly[3];
|
||||
dest->poly[4] = src->poly[4];
|
||||
dest->poly[5] = src->poly[5];
|
||||
if (bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2)
|
||||
== NULL)
|
||||
if (bn_wexpand(dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) ==
|
||||
NULL)
|
||||
return 0;
|
||||
if (bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2)
|
||||
== NULL)
|
||||
if (bn_wexpand(dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) ==
|
||||
NULL)
|
||||
return 0;
|
||||
for (i = dest->a.top; i < dest->a.dmax; i++)
|
||||
dest->a.d[i] = 0;
|
||||
for (i = dest->b.top; i < dest->b.dmax; i++)
|
||||
dest->b.d[i] = 0;
|
||||
bn_set_all_zero(dest->a);
|
||||
bn_set_all_zero(dest->b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -212,31 +173,29 @@ int ec_GF2m_simple_group_set_curve(EC_GROUP *group,
|
||||
int ret = 0, i;
|
||||
|
||||
/* group->field */
|
||||
if (!BN_copy(&group->field, p))
|
||||
if (!BN_copy(group->field, p))
|
||||
goto err;
|
||||
i = BN_GF2m_poly2arr(&group->field, group->poly, 6) - 1;
|
||||
i = BN_GF2m_poly2arr(group->field, group->poly, 6) - 1;
|
||||
if ((i != 5) && (i != 3)) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* group->a */
|
||||
if (!BN_GF2m_mod_arr(&group->a, a, group->poly))
|
||||
if (!BN_GF2m_mod_arr(group->a, a, group->poly))
|
||||
goto err;
|
||||
if (bn_wexpand(&group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2)
|
||||
if (bn_wexpand(group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2)
|
||||
== NULL)
|
||||
goto err;
|
||||
for (i = group->a.top; i < group->a.dmax; i++)
|
||||
group->a.d[i] = 0;
|
||||
bn_set_all_zero(group->a);
|
||||
|
||||
/* group->b */
|
||||
if (!BN_GF2m_mod_arr(&group->b, b, group->poly))
|
||||
if (!BN_GF2m_mod_arr(group->b, b, group->poly))
|
||||
goto err;
|
||||
if (bn_wexpand(&group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2)
|
||||
if (bn_wexpand(group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2)
|
||||
== NULL)
|
||||
goto err;
|
||||
for (i = group->b.top; i < group->b.dmax; i++)
|
||||
group->b.d[i] = 0;
|
||||
bn_set_all_zero(group->b);
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
@@ -253,17 +212,17 @@ int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p,
|
||||
int ret = 0;
|
||||
|
||||
if (p != NULL) {
|
||||
if (!BN_copy(p, &group->field))
|
||||
if (!BN_copy(p, group->field))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a != NULL) {
|
||||
if (!BN_copy(a, &group->a))
|
||||
if (!BN_copy(a, group->a))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (b != NULL) {
|
||||
if (!BN_copy(b, &group->b))
|
||||
if (!BN_copy(b, group->b))
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -279,7 +238,7 @@ int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p,
|
||||
*/
|
||||
int ec_GF2m_simple_group_get_degree(const EC_GROUP *group)
|
||||
{
|
||||
return BN_num_bits(&group->field) - 1;
|
||||
return BN_num_bits(group->field) - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -306,7 +265,7 @@ int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group,
|
||||
if (b == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_GF2m_mod_arr(b, &group->b, group->poly))
|
||||
if (!BN_GF2m_mod_arr(b, group->b, group->poly))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
@@ -321,34 +280,40 @@ int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group,
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Initializes an EC_POINT. */
|
||||
int ec_GF2m_simple_point_init(EC_POINT *point)
|
||||
{
|
||||
BN_init(&point->X);
|
||||
BN_init(&point->Y);
|
||||
BN_init(&point->Z);
|
||||
point->X = BN_new();
|
||||
point->Y = BN_new();
|
||||
point->Z = BN_new();
|
||||
|
||||
if (point->X == NULL || point->Y == NULL || point->Z == NULL) {
|
||||
BN_free(point->X);
|
||||
BN_free(point->Y);
|
||||
BN_free(point->Z);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Frees an EC_POINT. */
|
||||
void ec_GF2m_simple_point_finish(EC_POINT *point)
|
||||
{
|
||||
BN_free(&point->X);
|
||||
BN_free(&point->Y);
|
||||
BN_free(&point->Z);
|
||||
BN_free(point->X);
|
||||
BN_free(point->Y);
|
||||
BN_free(point->Z);
|
||||
}
|
||||
|
||||
/* Clears and frees an EC_POINT. */
|
||||
void ec_GF2m_simple_point_clear_finish(EC_POINT *point)
|
||||
{
|
||||
BN_clear_free(&point->X);
|
||||
BN_clear_free(&point->Y);
|
||||
BN_clear_free(&point->Z);
|
||||
BN_clear_free(point->X);
|
||||
BN_clear_free(point->Y);
|
||||
BN_clear_free(point->Z);
|
||||
point->Z_is_one = 0;
|
||||
}
|
||||
|
||||
@@ -358,11 +323,11 @@ void ec_GF2m_simple_point_clear_finish(EC_POINT *point)
|
||||
*/
|
||||
int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
|
||||
{
|
||||
if (!BN_copy(&dest->X, &src->X))
|
||||
if (!BN_copy(dest->X, src->X))
|
||||
return 0;
|
||||
if (!BN_copy(&dest->Y, &src->Y))
|
||||
if (!BN_copy(dest->Y, src->Y))
|
||||
return 0;
|
||||
if (!BN_copy(&dest->Z, &src->Z))
|
||||
if (!BN_copy(dest->Z, src->Z))
|
||||
return 0;
|
||||
dest->Z_is_one = src->Z_is_one;
|
||||
|
||||
@@ -377,7 +342,7 @@ int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group,
|
||||
EC_POINT *point)
|
||||
{
|
||||
point->Z_is_one = 0;
|
||||
BN_zero(&point->Z);
|
||||
BN_zero(point->Z);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -397,15 +362,15 @@ int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!BN_copy(&point->X, x))
|
||||
if (!BN_copy(point->X, x))
|
||||
goto err;
|
||||
BN_set_negative(&point->X, 0);
|
||||
if (!BN_copy(&point->Y, y))
|
||||
BN_set_negative(point->X, 0);
|
||||
if (!BN_copy(point->Y, y))
|
||||
goto err;
|
||||
BN_set_negative(&point->Y, 0);
|
||||
if (!BN_copy(&point->Z, BN_value_one()))
|
||||
BN_set_negative(point->Y, 0);
|
||||
if (!BN_copy(point->Z, BN_value_one()))
|
||||
goto err;
|
||||
BN_set_negative(&point->Z, 0);
|
||||
BN_set_negative(point->Z, 0);
|
||||
point->Z_is_one = 1;
|
||||
ret = 1;
|
||||
|
||||
@@ -430,18 +395,18 @@ int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (BN_cmp(&point->Z, BN_value_one())) {
|
||||
if (BN_cmp(point->Z, BN_value_one())) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES,
|
||||
ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
if (x != NULL) {
|
||||
if (!BN_copy(x, &point->X))
|
||||
if (!BN_copy(x, point->X))
|
||||
goto err;
|
||||
BN_set_negative(x, 0);
|
||||
}
|
||||
if (y != NULL) {
|
||||
if (!BN_copy(y, &point->Y))
|
||||
if (!BN_copy(y, point->Y))
|
||||
goto err;
|
||||
BN_set_negative(y, 0);
|
||||
}
|
||||
@@ -493,18 +458,18 @@ int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
|
||||
goto err;
|
||||
|
||||
if (a->Z_is_one) {
|
||||
if (!BN_copy(x0, &a->X))
|
||||
if (!BN_copy(x0, a->X))
|
||||
goto err;
|
||||
if (!BN_copy(y0, &a->Y))
|
||||
if (!BN_copy(y0, a->Y))
|
||||
goto err;
|
||||
} else {
|
||||
if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx))
|
||||
goto err;
|
||||
}
|
||||
if (b->Z_is_one) {
|
||||
if (!BN_copy(x1, &b->X))
|
||||
if (!BN_copy(x1, b->X))
|
||||
goto err;
|
||||
if (!BN_copy(y1, &b->Y))
|
||||
if (!BN_copy(y1, b->Y))
|
||||
goto err;
|
||||
} else {
|
||||
if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx))
|
||||
@@ -520,7 +485,7 @@ int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
|
||||
goto err;
|
||||
if (!group->meth->field_sqr(group, x2, s, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(x2, x2, &group->a))
|
||||
if (!BN_GF2m_add(x2, x2, group->a))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(x2, x2, s))
|
||||
goto err;
|
||||
@@ -542,7 +507,7 @@ int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
|
||||
goto err;
|
||||
if (!BN_GF2m_add(x2, x2, s))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(x2, x2, &group->a))
|
||||
if (!BN_GF2m_add(x2, x2, group->a))
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -562,8 +527,7 @@ int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -579,20 +543,20 @@ int ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
|
||||
|
||||
int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
|
||||
{
|
||||
if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y))
|
||||
if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(point->Y))
|
||||
/* point is its own inverse */
|
||||
return 1;
|
||||
|
||||
if (!EC_POINT_make_affine(group, point, ctx))
|
||||
return 0;
|
||||
return BN_GF2m_add(&point->Y, &point->X, &point->Y);
|
||||
return BN_GF2m_add(point->Y, point->X, point->Y);
|
||||
}
|
||||
|
||||
/* Indicates whether the given point is the point at infinity. */
|
||||
int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group,
|
||||
const EC_POINT *point)
|
||||
{
|
||||
return BN_is_zero(&point->Z);
|
||||
return BN_is_zero(point->Z);
|
||||
}
|
||||
|
||||
/*-
|
||||
@@ -638,17 +602,17 @@ int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
|
||||
* <=> x^3 + a*x^2 + x*y + b + y^2 = 0
|
||||
* <=> ((x + a) * x + y ) * x + b + y^2 = 0
|
||||
*/
|
||||
if (!BN_GF2m_add(lh, &point->X, &group->a))
|
||||
if (!BN_GF2m_add(lh, point->X, group->a))
|
||||
goto err;
|
||||
if (!field_mul(group, lh, lh, &point->X, ctx))
|
||||
if (!field_mul(group, lh, lh, point->X, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(lh, lh, &point->Y))
|
||||
if (!BN_GF2m_add(lh, lh, point->Y))
|
||||
goto err;
|
||||
if (!field_mul(group, lh, lh, &point->X, ctx))
|
||||
if (!field_mul(group, lh, lh, point->X, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(lh, lh, &group->b))
|
||||
if (!BN_GF2m_add(lh, lh, group->b))
|
||||
goto err;
|
||||
if (!field_sqr(group, y2, &point->Y, ctx))
|
||||
if (!field_sqr(group, y2, point->Y, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(lh, lh, y2))
|
||||
goto err;
|
||||
@@ -656,8 +620,7 @@ int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
|
||||
err:
|
||||
if (ctx)
|
||||
BN_CTX_end(ctx);
|
||||
if (new_ctx)
|
||||
BN_CTX_free(new_ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -683,8 +646,7 @@ int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
|
||||
return 1;
|
||||
|
||||
if (a->Z_is_one && b->Z_is_one) {
|
||||
return ((BN_cmp(&a->X, &b->X) == 0)
|
||||
&& BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
|
||||
return ((BN_cmp(a->X, b->X) == 0) && BN_cmp(a->Y, b->Y) == 0) ? 0 : 1;
|
||||
}
|
||||
|
||||
if (ctx == NULL) {
|
||||
@@ -710,8 +672,7 @@ int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
|
||||
err:
|
||||
if (ctx)
|
||||
BN_CTX_end(ctx);
|
||||
if (new_ctx)
|
||||
BN_CTX_free(new_ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -740,11 +701,11 @@ int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
|
||||
|
||||
if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx))
|
||||
goto err;
|
||||
if (!BN_copy(&point->X, x))
|
||||
if (!BN_copy(point->X, x))
|
||||
goto err;
|
||||
if (!BN_copy(&point->Y, y))
|
||||
if (!BN_copy(point->Y, y))
|
||||
goto err;
|
||||
if (!BN_one(&point->Z))
|
||||
if (!BN_one(point->Z))
|
||||
goto err;
|
||||
point->Z_is_one = 1;
|
||||
|
||||
@@ -753,8 +714,7 @@ int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
|
||||
err:
|
||||
if (ctx)
|
||||
BN_CTX_end(ctx);
|
||||
if (new_ctx)
|
||||
BN_CTX_free(new_ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -792,7 +752,7 @@ int ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r,
|
||||
int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r,
|
||||
const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
|
||||
{
|
||||
return BN_GF2m_mod_div(r, a, b, &group->field, ctx);
|
||||
return BN_GF2m_mod_div(r, a, b, group->field, ctx);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,71 +1,21 @@
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2006.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
* Copyright 2006-2016 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
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/bn.h>
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
# include <openssl/cms.h>
|
||||
#endif
|
||||
#include <openssl/cms.h>
|
||||
#include <openssl/asn1t.h>
|
||||
#include "asn1_locl.h"
|
||||
#include "internal/asn1_int.h"
|
||||
#include "internal/evp_int.h"
|
||||
#include "ec_lcl.h"
|
||||
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
@@ -91,7 +41,7 @@ static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
|
||||
|
||||
ASN1_STRING *pstr = NULL;
|
||||
pstr = ASN1_STRING_new();
|
||||
if (!pstr)
|
||||
if (pstr == NULL)
|
||||
return 0;
|
||||
pstr->length = i2d_ECParameters(ec_key, &pstr->data);
|
||||
if (pstr->length <= 0) {
|
||||
@@ -121,7 +71,7 @@ static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
|
||||
if (penclen <= 0)
|
||||
goto err;
|
||||
penc = OPENSSL_malloc(penclen);
|
||||
if (!penc)
|
||||
if (penc == NULL)
|
||||
goto err;
|
||||
p = penc;
|
||||
penclen = i2o_ECPublicKey(ec_key, &p);
|
||||
@@ -135,26 +85,25 @@ static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
|
||||
ASN1_OBJECT_free(pval);
|
||||
else
|
||||
ASN1_STRING_free(pval);
|
||||
if (penc)
|
||||
OPENSSL_free(penc);
|
||||
OPENSSL_free(penc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static EC_KEY *eckey_type2param(int ptype, void *pval)
|
||||
static EC_KEY *eckey_type2param(int ptype, const void *pval)
|
||||
{
|
||||
EC_KEY *eckey = NULL;
|
||||
if (ptype == V_ASN1_SEQUENCE) {
|
||||
ASN1_STRING *pstr = pval;
|
||||
const ASN1_STRING *pstr = pval;
|
||||
const unsigned char *pm = NULL;
|
||||
int pmlen;
|
||||
pm = pstr->data;
|
||||
pmlen = pstr->length;
|
||||
if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) {
|
||||
if ((eckey = d2i_ECParameters(NULL, &pm, pmlen)) == NULL) {
|
||||
ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
|
||||
goto ecerr;
|
||||
}
|
||||
} else if (ptype == V_ASN1_OBJECT) {
|
||||
ASN1_OBJECT *poid = pval;
|
||||
const ASN1_OBJECT *poid = pval;
|
||||
EC_GROUP *group;
|
||||
|
||||
/*
|
||||
@@ -179,15 +128,14 @@ static EC_KEY *eckey_type2param(int ptype, void *pval)
|
||||
return eckey;
|
||||
|
||||
ecerr:
|
||||
if (eckey)
|
||||
EC_KEY_free(eckey);
|
||||
EC_KEY_free(eckey);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
|
||||
{
|
||||
const unsigned char *p = NULL;
|
||||
void *pval;
|
||||
const void *pval;
|
||||
int ptype, pklen;
|
||||
EC_KEY *eckey = NULL;
|
||||
X509_ALGOR *palg;
|
||||
@@ -213,8 +161,7 @@ static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
|
||||
return 1;
|
||||
|
||||
ecerr:
|
||||
if (eckey)
|
||||
EC_KEY_free(eckey);
|
||||
EC_KEY_free(eckey);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -234,13 +181,13 @@ static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
return -2;
|
||||
}
|
||||
|
||||
static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
|
||||
static int eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
|
||||
{
|
||||
const unsigned char *p = NULL;
|
||||
void *pval;
|
||||
const void *pval;
|
||||
int ptype, pklen;
|
||||
EC_KEY *eckey = NULL;
|
||||
X509_ALGOR *palg;
|
||||
const X509_ALGOR *palg;
|
||||
|
||||
if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
|
||||
return 0;
|
||||
@@ -257,48 +204,13 @@ static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
|
||||
goto ecerr;
|
||||
}
|
||||
|
||||
/* calculate public key (if necessary) */
|
||||
if (EC_KEY_get0_public_key(eckey) == NULL) {
|
||||
const BIGNUM *priv_key;
|
||||
const EC_GROUP *group;
|
||||
EC_POINT *pub_key;
|
||||
/*
|
||||
* the public key was not included in the SEC1 private key =>
|
||||
* calculate the public key
|
||||
*/
|
||||
group = EC_KEY_get0_group(eckey);
|
||||
pub_key = EC_POINT_new(group);
|
||||
if (pub_key == NULL) {
|
||||
ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
|
||||
goto ecliberr;
|
||||
}
|
||||
if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
|
||||
EC_POINT_free(pub_key);
|
||||
ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
|
||||
goto ecliberr;
|
||||
}
|
||||
priv_key = EC_KEY_get0_private_key(eckey);
|
||||
if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) {
|
||||
EC_POINT_free(pub_key);
|
||||
ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
|
||||
goto ecliberr;
|
||||
}
|
||||
if (EC_KEY_set_public_key(eckey, pub_key) == 0) {
|
||||
EC_POINT_free(pub_key);
|
||||
ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
|
||||
goto ecliberr;
|
||||
}
|
||||
EC_POINT_free(pub_key);
|
||||
}
|
||||
|
||||
EVP_PKEY_assign_EC_KEY(pkey, eckey);
|
||||
return 1;
|
||||
|
||||
ecliberr:
|
||||
ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
|
||||
ecerr:
|
||||
if (eckey)
|
||||
EC_KEY_free(eckey);
|
||||
EC_KEY_free(eckey);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -329,8 +241,8 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
|
||||
ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
|
||||
return 0;
|
||||
}
|
||||
ep = (unsigned char *)OPENSSL_malloc(eplen);
|
||||
if (!ep) {
|
||||
ep = OPENSSL_malloc(eplen);
|
||||
if (ep == NULL) {
|
||||
ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
@@ -342,8 +254,10 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
|
||||
}
|
||||
|
||||
if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
|
||||
ptype, pval, ep, eplen))
|
||||
ptype, pval, ep, eplen)) {
|
||||
OPENSSL_free(ep);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -355,23 +269,23 @@ static int int_ec_size(const EVP_PKEY *pkey)
|
||||
|
||||
static int ec_bits(const EVP_PKEY *pkey)
|
||||
{
|
||||
BIGNUM *order = BN_new();
|
||||
const EC_GROUP *group;
|
||||
int ret;
|
||||
return EC_GROUP_order_bits(EC_KEY_get0_group(pkey->pkey.ec));
|
||||
}
|
||||
|
||||
if (!order) {
|
||||
ERR_clear_error();
|
||||
return 0;
|
||||
}
|
||||
group = EC_KEY_get0_group(pkey->pkey.ec);
|
||||
if (!EC_GROUP_get_order(group, order, NULL)) {
|
||||
ERR_clear_error();
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = BN_num_bits(order);
|
||||
BN_free(order);
|
||||
return ret;
|
||||
static int ec_security_bits(const EVP_PKEY *pkey)
|
||||
{
|
||||
int ecbits = ec_bits(pkey);
|
||||
if (ecbits >= 512)
|
||||
return 256;
|
||||
if (ecbits >= 384)
|
||||
return 192;
|
||||
if (ecbits >= 256)
|
||||
return 128;
|
||||
if (ecbits >= 224)
|
||||
return 112;
|
||||
if (ecbits >= 160)
|
||||
return 80;
|
||||
return ecbits / 2;
|
||||
}
|
||||
|
||||
static int ec_missing_parameters(const EVP_PKEY *pkey)
|
||||
@@ -386,6 +300,11 @@ static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
|
||||
EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
|
||||
if (group == NULL)
|
||||
return 0;
|
||||
if (to->pkey.ec == NULL) {
|
||||
to->pkey.ec = EC_KEY_new();
|
||||
if (to->pkey.ec == NULL)
|
||||
return 0;
|
||||
}
|
||||
if (EC_KEY_set_group(to->pkey.ec, group) == 0)
|
||||
return 0;
|
||||
EC_GROUP_free(group);
|
||||
@@ -409,100 +328,81 @@ static void int_ec_free(EVP_PKEY *pkey)
|
||||
EC_KEY_free(pkey->pkey.ec);
|
||||
}
|
||||
|
||||
static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
|
||||
typedef enum {
|
||||
EC_KEY_PRINT_PRIVATE,
|
||||
EC_KEY_PRINT_PUBLIC,
|
||||
EC_KEY_PRINT_PARAM
|
||||
} ec_print_t;
|
||||
|
||||
static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, ec_print_t ktype)
|
||||
{
|
||||
unsigned char *buffer = NULL;
|
||||
const char *ecstr;
|
||||
size_t buf_len = 0, i;
|
||||
int ret = 0, reason = ERR_R_BIO_LIB;
|
||||
BIGNUM *pub_key = NULL, *order = NULL;
|
||||
BN_CTX *ctx = NULL;
|
||||
unsigned char *priv = NULL, *pub = NULL;
|
||||
size_t privlen = 0, publen = 0;
|
||||
int ret = 0;
|
||||
const EC_GROUP *group;
|
||||
const EC_POINT *public_key;
|
||||
const BIGNUM *priv_key;
|
||||
|
||||
if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
|
||||
reason = ERR_R_PASSED_NULL_PARAMETER;
|
||||
goto err;
|
||||
ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx = BN_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
reason = ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ktype > 0) {
|
||||
public_key = EC_KEY_get0_public_key(x);
|
||||
if (public_key != NULL) {
|
||||
if ((pub_key = EC_POINT_point2bn(group, public_key,
|
||||
EC_KEY_get_conv_form(x), NULL,
|
||||
ctx)) == NULL) {
|
||||
reason = ERR_R_EC_LIB;
|
||||
goto err;
|
||||
}
|
||||
buf_len = (size_t)BN_num_bytes(pub_key);
|
||||
}
|
||||
}
|
||||
|
||||
if (ktype == 2) {
|
||||
priv_key = EC_KEY_get0_private_key(x);
|
||||
if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len)
|
||||
buf_len = i;
|
||||
} else
|
||||
priv_key = NULL;
|
||||
|
||||
if (ktype > 0) {
|
||||
buf_len += 10;
|
||||
if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
|
||||
reason = ERR_R_MALLOC_FAILURE;
|
||||
if (ktype != EC_KEY_PRINT_PARAM && EC_KEY_get0_public_key(x) != NULL) {
|
||||
publen = EC_KEY_key2buf(x, EC_KEY_get_conv_form(x), &pub, NULL);
|
||||
if (publen == 0)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (ktype == 2)
|
||||
|
||||
if (ktype == EC_KEY_PRINT_PRIVATE && EC_KEY_get0_private_key(x) != NULL) {
|
||||
privlen = EC_KEY_priv2buf(x, &priv);
|
||||
if (privlen == 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ktype == EC_KEY_PRINT_PRIVATE)
|
||||
ecstr = "Private-Key";
|
||||
else if (ktype == 1)
|
||||
else if (ktype == EC_KEY_PRINT_PUBLIC)
|
||||
ecstr = "Public-Key";
|
||||
else
|
||||
ecstr = "ECDSA-Parameters";
|
||||
|
||||
if (!BIO_indent(bp, off, 128))
|
||||
goto err;
|
||||
if ((order = BN_new()) == NULL)
|
||||
goto err;
|
||||
if (!EC_GROUP_get_order(group, order, NULL))
|
||||
goto err;
|
||||
if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0)
|
||||
if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
|
||||
EC_GROUP_order_bits(group)) <= 0)
|
||||
goto err;
|
||||
|
||||
if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key,
|
||||
buffer, off))
|
||||
goto err;
|
||||
if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
|
||||
buffer, off))
|
||||
goto err;
|
||||
if (privlen != 0) {
|
||||
if (BIO_printf(bp, "%*spriv:\n", off, "") <= 0)
|
||||
goto err;
|
||||
if (ASN1_buf_print(bp, priv, privlen, off + 4) == 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (publen != 0) {
|
||||
if (BIO_printf(bp, "%*spub:\n", off, "") <= 0)
|
||||
goto err;
|
||||
if (ASN1_buf_print(bp, pub, publen, off + 4) == 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!ECPKParameters_print(bp, group, off))
|
||||
goto err;
|
||||
ret = 1;
|
||||
err:
|
||||
if (!ret)
|
||||
ECerr(EC_F_DO_EC_KEY_PRINT, reason);
|
||||
if (pub_key)
|
||||
BN_free(pub_key);
|
||||
if (order)
|
||||
BN_free(order);
|
||||
if (ctx)
|
||||
BN_CTX_free(ctx);
|
||||
if (buffer != NULL)
|
||||
OPENSSL_free(buffer);
|
||||
return (ret);
|
||||
ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_EC_LIB);
|
||||
OPENSSL_clear_free(priv, privlen);
|
||||
OPENSSL_free(pub);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int eckey_param_decode(EVP_PKEY *pkey,
|
||||
const unsigned char **pder, int derlen)
|
||||
{
|
||||
EC_KEY *eckey;
|
||||
if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) {
|
||||
|
||||
if ((eckey = d2i_ECParameters(NULL, pder, derlen)) == NULL) {
|
||||
ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
|
||||
return 0;
|
||||
}
|
||||
@@ -518,26 +418,27 @@ static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
|
||||
static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *ctx)
|
||||
{
|
||||
return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
|
||||
return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PARAM);
|
||||
}
|
||||
|
||||
static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *ctx)
|
||||
{
|
||||
return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
|
||||
return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PUBLIC);
|
||||
}
|
||||
|
||||
static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *ctx)
|
||||
{
|
||||
return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
|
||||
return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PRIVATE);
|
||||
}
|
||||
|
||||
static int old_ec_priv_decode(EVP_PKEY *pkey,
|
||||
const unsigned char **pder, int derlen)
|
||||
{
|
||||
EC_KEY *ec;
|
||||
if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) {
|
||||
|
||||
if ((ec = d2i_ECPrivateKey(NULL, pder, derlen)) == NULL) {
|
||||
ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
@@ -601,6 +502,13 @@ static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
|
||||
*(int *)arg2 = NID_sha256;
|
||||
return 2;
|
||||
|
||||
case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
|
||||
return EC_KEY_oct2key(EVP_PKEY_get0_EC_KEY(pkey), arg2, arg1, NULL);
|
||||
|
||||
case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
|
||||
return EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(pkey),
|
||||
POINT_CONVERSION_UNCOMPRESSED, arg2, NULL);
|
||||
|
||||
default:
|
||||
return -2;
|
||||
|
||||
@@ -626,6 +534,7 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
|
||||
|
||||
int_ec_size,
|
||||
ec_bits,
|
||||
ec_security_bits,
|
||||
|
||||
eckey_param_decode,
|
||||
eckey_param_encode,
|
||||
@@ -641,14 +550,27 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
|
||||
old_ec_priv_encode
|
||||
};
|
||||
|
||||
int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
|
||||
{
|
||||
int private = EC_KEY_get0_private_key(x) != NULL;
|
||||
|
||||
return do_EC_KEY_print(bp, x, off,
|
||||
private ? EC_KEY_PRINT_PRIVATE : EC_KEY_PRINT_PUBLIC);
|
||||
}
|
||||
|
||||
int ECParameters_print(BIO *bp, const EC_KEY *x)
|
||||
{
|
||||
return do_EC_KEY_print(bp, x, 4, EC_KEY_PRINT_PARAM);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
|
||||
static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
|
||||
X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
|
||||
{
|
||||
ASN1_OBJECT *aoid;
|
||||
const ASN1_OBJECT *aoid;
|
||||
int atype;
|
||||
void *aval;
|
||||
const void *aval;
|
||||
int rv = 0;
|
||||
EVP_PKEY *pkpeer = NULL;
|
||||
EC_KEY *ecpeer = NULL;
|
||||
@@ -666,7 +588,7 @@ static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
|
||||
goto err;
|
||||
grp = EC_KEY_get0_group(pk->pkey.ec);
|
||||
ecpeer = EC_KEY_new();
|
||||
if (!ecpeer)
|
||||
if (ecpeer == NULL)
|
||||
goto err;
|
||||
if (!EC_KEY_set_group(ecpeer, grp))
|
||||
goto err;
|
||||
@@ -677,22 +599,20 @@ static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
|
||||
}
|
||||
/* We have parameters now set public key */
|
||||
plen = ASN1_STRING_length(pubkey);
|
||||
p = ASN1_STRING_data(pubkey);
|
||||
p = ASN1_STRING_get0_data(pubkey);
|
||||
if (!p || !plen)
|
||||
goto err;
|
||||
if (!o2i_ECPublicKey(&ecpeer, &p, plen))
|
||||
goto err;
|
||||
pkpeer = EVP_PKEY_new();
|
||||
if (!pkpeer)
|
||||
if (pkpeer == NULL)
|
||||
goto err;
|
||||
EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer);
|
||||
if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
|
||||
rv = 1;
|
||||
err:
|
||||
if (ecpeer)
|
||||
EC_KEY_free(ecpeer);
|
||||
if (pkpeer)
|
||||
EVP_PKEY_free(pkpeer);
|
||||
EC_KEY_free(ecpeer);
|
||||
EVP_PKEY_free(pkpeer);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -784,10 +704,8 @@ static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
|
||||
|
||||
rv = 1;
|
||||
err:
|
||||
if (kekalg)
|
||||
X509_ALGOR_free(kekalg);
|
||||
if (der)
|
||||
OPENSSL_free(der);
|
||||
X509_ALGOR_free(kekalg);
|
||||
OPENSSL_free(der);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -826,7 +744,7 @@ static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
int keylen;
|
||||
X509_ALGOR *talg, *wrap_alg = NULL;
|
||||
ASN1_OBJECT *aoid;
|
||||
const ASN1_OBJECT *aoid;
|
||||
ASN1_BIT_STRING *pubkey;
|
||||
ASN1_STRING *wrap_str;
|
||||
ASN1_OCTET_STRING *ukm;
|
||||
@@ -855,7 +773,7 @@ static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
|
||||
if (penclen <= 0)
|
||||
goto err;
|
||||
penc = OPENSSL_malloc(penclen);
|
||||
if (!penc)
|
||||
if (penc == NULL)
|
||||
goto err;
|
||||
p = penc;
|
||||
penclen = i2o_ECPublicKey(eckey, &p);
|
||||
@@ -870,7 +788,7 @@ static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
|
||||
V_ASN1_UNDEF, NULL);
|
||||
}
|
||||
|
||||
/* See if custom paraneters set */
|
||||
/* See if custom parameters set */
|
||||
kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx);
|
||||
if (kdf_type <= 0)
|
||||
goto err;
|
||||
@@ -889,7 +807,7 @@ static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
|
||||
if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0)
|
||||
goto err;
|
||||
} else
|
||||
/* Uknown KDF */
|
||||
/* Unknown KDF */
|
||||
goto err;
|
||||
if (kdf_md == NULL) {
|
||||
/* Fixme later for better MD */
|
||||
@@ -913,11 +831,11 @@ static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
|
||||
/* Package wrap algorithm in an AlgorithmIdentifier */
|
||||
|
||||
wrap_alg = X509_ALGOR_new();
|
||||
if (!wrap_alg)
|
||||
if (wrap_alg == NULL)
|
||||
goto err;
|
||||
wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
|
||||
wrap_alg->parameter = ASN1_TYPE_new();
|
||||
if (!wrap_alg->parameter)
|
||||
if (wrap_alg->parameter == NULL)
|
||||
goto err;
|
||||
if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
|
||||
goto err;
|
||||
@@ -946,7 +864,7 @@ static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
|
||||
if (!penc || !penclen)
|
||||
goto err;
|
||||
wrap_str = ASN1_STRING_new();
|
||||
if (!wrap_str)
|
||||
if (wrap_str == NULL)
|
||||
goto err;
|
||||
ASN1_STRING_set0(wrap_str, penc, penclen);
|
||||
penc = NULL;
|
||||
@@ -955,10 +873,8 @@ static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
|
||||
rv = 1;
|
||||
|
||||
err:
|
||||
if (penc)
|
||||
OPENSSL_free(penc);
|
||||
if (wrap_alg)
|
||||
X509_ALGOR_free(wrap_alg);
|
||||
OPENSSL_free(penc);
|
||||
X509_ALGOR_free(wrap_alg);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,56 +1,10 @@
|
||||
/* crypto/ec/ec_check.c */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
/*
|
||||
* Copyright 2002-2016 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
|
||||
*/
|
||||
|
||||
#include "ec_lcl.h"
|
||||
@@ -59,10 +13,14 @@
|
||||
int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
BIGNUM *order;
|
||||
const BIGNUM *order;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
EC_POINT *point = NULL;
|
||||
|
||||
/* Custom curves assumed to be correct */
|
||||
if ((group->meth->flags & EC_FLAGS_CUSTOM_CURVE) != 0)
|
||||
return 1;
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
@@ -70,9 +28,6 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
BN_CTX_start(ctx);
|
||||
if ((order = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
/* check the discriminant */
|
||||
if (!EC_GROUP_check_discriminant(group, ctx)) {
|
||||
@@ -93,7 +48,8 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
|
||||
/* check the order of the generator */
|
||||
if ((point = EC_POINT_new(group)) == NULL)
|
||||
goto err;
|
||||
if (!EC_GROUP_get_order(group, order, ctx))
|
||||
order = EC_GROUP_get0_order(group);
|
||||
if (order == NULL)
|
||||
goto err;
|
||||
if (BN_is_zero(order)) {
|
||||
ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER);
|
||||
@@ -110,11 +66,7 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
if (point)
|
||||
EC_POINT_free(point);
|
||||
BN_CTX_free(new_ctx);
|
||||
EC_POINT_free(point);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,60 +1,12 @@
|
||||
/* crypto/ec/ec_curve.c */
|
||||
/*
|
||||
* Written by Nils Larsch for the OpenSSL project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2010 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright 2002-2016 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
*
|
||||
@@ -74,10 +26,7 @@
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
# include <openssl/fips.h>
|
||||
#endif
|
||||
#include "e_os.h"
|
||||
|
||||
typedef struct {
|
||||
int field_type, /* either NID_X9_62_prime_field or
|
||||
@@ -1065,16 +1014,6 @@ static const struct {
|
||||
NID_X9_62_characteristic_two_field, 0, 21, 2
|
||||
},
|
||||
{
|
||||
/* no seed */
|
||||
# if 0
|
||||
/*
|
||||
* The algorithm used to derive the curve parameters from the seed
|
||||
* used here is slightly different than the algorithm described in
|
||||
* X9.62 .
|
||||
*/
|
||||
0x24, 0xB7, 0xB1, 0x37, 0xC8, 0xA1, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75,
|
||||
0x61, 0x51, 0x75, 0x6F, 0xD0, 0xDA, 0x2E, 0x5C,
|
||||
# endif
|
||||
/* p */
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9,
|
||||
@@ -1104,16 +1043,6 @@ static const struct {
|
||||
NID_X9_62_characteristic_two_field, 0, 21, 2
|
||||
},
|
||||
{
|
||||
/* no seed */
|
||||
# if 0
|
||||
/*
|
||||
* The seed here was used to created the curve parameters in normal
|
||||
* basis representation (and not the polynomial representation used
|
||||
* here)
|
||||
*/
|
||||
0x85, 0xE2, 0x5B, 0xFE, 0x5C, 0x86, 0x22, 0x6C, 0xDB, 0x12, 0x01, 0x6F,
|
||||
0x75, 0x53, 0xF9, 0xD0, 0xE6, 0x93, 0xA2, 0x68,
|
||||
# endif
|
||||
/* p */
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9,
|
||||
@@ -3005,7 +2934,7 @@ static const ec_list_element curve_list[] = {
|
||||
"NIST/SECG/WTLS curve over a 233 bit binary field"},
|
||||
#endif
|
||||
{NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0,
|
||||
"WTLS curvs over a 224 bit prime field"},
|
||||
"WTLS curve over a 224 bit prime field"},
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
/* IPSec curves */
|
||||
{NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0,
|
||||
@@ -3046,7 +2975,7 @@ static const ec_list_element curve_list[] = {
|
||||
"RFC 5639 curve over a 512 bit prime field"},
|
||||
};
|
||||
|
||||
#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element))
|
||||
#define curve_list_length OSSL_NELEM(curve_list)
|
||||
|
||||
static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
|
||||
{
|
||||
@@ -3061,6 +2990,10 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
|
||||
const EC_CURVE_DATA *data;
|
||||
const unsigned char *params;
|
||||
|
||||
/* If no curve data curve method must handle everything */
|
||||
if (curve.data == NULL)
|
||||
return EC_GROUP_new(curve.meth != NULL ? curve.meth() : NULL);
|
||||
|
||||
if ((ctx = BN_CTX_new()) == NULL) {
|
||||
ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
@@ -3072,9 +3005,9 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
|
||||
params = (const unsigned char *)(data + 1); /* skip header */
|
||||
params += seed_len; /* skip seed */
|
||||
|
||||
if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL))
|
||||
|| !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL))
|
||||
|| !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
|
||||
if ((p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) == NULL
|
||||
|| (a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) == NULL
|
||||
|| (b = BN_bin2bn(params + 2 * param_len, param_len, NULL)) == NULL) {
|
||||
ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
@@ -3108,8 +3041,8 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL))
|
||||
|| !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
|
||||
if ((x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) == NULL
|
||||
|| (y = BN_bin2bn(params + 4 * param_len, param_len, NULL)) == NULL) {
|
||||
ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
@@ -3117,7 +3050,7 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
|
||||
ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL))
|
||||
if ((order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) == NULL
|
||||
|| !BN_set_word(x, (BN_ULONG)data->cofactor)) {
|
||||
ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
@@ -3138,22 +3071,14 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
|
||||
EC_GROUP_free(group);
|
||||
group = NULL;
|
||||
}
|
||||
if (P)
|
||||
EC_POINT_free(P);
|
||||
if (ctx)
|
||||
BN_CTX_free(ctx);
|
||||
if (p)
|
||||
BN_free(p);
|
||||
if (a)
|
||||
BN_free(a);
|
||||
if (b)
|
||||
BN_free(b);
|
||||
if (order)
|
||||
BN_free(order);
|
||||
if (x)
|
||||
BN_free(x);
|
||||
if (y)
|
||||
BN_free(y);
|
||||
EC_POINT_free(P);
|
||||
BN_CTX_free(ctx);
|
||||
BN_free(p);
|
||||
BN_free(a);
|
||||
BN_free(b);
|
||||
BN_free(order);
|
||||
BN_free(x);
|
||||
BN_free(y);
|
||||
return group;
|
||||
}
|
||||
|
||||
@@ -3162,10 +3087,6 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int nid)
|
||||
size_t i;
|
||||
EC_GROUP *ret = NULL;
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
if (FIPS_mode())
|
||||
return FIPS_ec_group_new_by_curve_name(nid);
|
||||
#endif
|
||||
if (nid <= 0)
|
||||
return NULL;
|
||||
|
||||
@@ -3230,7 +3151,7 @@ static EC_NIST_NAME nist_curves[] = {
|
||||
const char *EC_curve_nid2nist(int nid)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < sizeof(nist_curves) / sizeof(EC_NIST_NAME); i++) {
|
||||
for (i = 0; i < OSSL_NELEM(nist_curves); i++) {
|
||||
if (nist_curves[i].nid == nid)
|
||||
return nist_curves[i].name;
|
||||
}
|
||||
@@ -3240,8 +3161,8 @@ const char *EC_curve_nid2nist(int nid)
|
||||
int EC_curve_nist2nid(const char *name)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < sizeof(nist_curves) / sizeof(EC_NIST_NAME); i++) {
|
||||
if (!strcmp(nist_curves[i].name, name))
|
||||
for (i = 0; i < OSSL_NELEM(nist_curves); i++) {
|
||||
if (strcmp(nist_curves[i].name, name) == 0)
|
||||
return nist_curves[i].nid;
|
||||
}
|
||||
return NID_undef;
|
||||
|
||||
@@ -1,60 +1,12 @@
|
||||
/* crypto/ec/ec_cvt.c */
|
||||
/*
|
||||
* Originally written by Bodo Moeller for the OpenSSL project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright 2001-2016 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
*
|
||||
@@ -72,20 +24,12 @@
|
||||
#include <openssl/err.h>
|
||||
#include "ec_lcl.h"
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
# include <openssl/fips.h>
|
||||
#endif
|
||||
|
||||
EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *ctx)
|
||||
{
|
||||
const EC_METHOD *meth;
|
||||
EC_GROUP *ret;
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
if (FIPS_mode())
|
||||
return FIPS_ec_group_new_curve_gfp(p, a, b, ctx);
|
||||
#endif
|
||||
#if defined(OPENSSL_BN_ASM_MONT)
|
||||
/*
|
||||
* This might appear controversial, but the fact is that generic
|
||||
@@ -110,7 +54,10 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
|
||||
*/
|
||||
meth = EC_GFp_mont_method();
|
||||
#else
|
||||
meth = EC_GFp_nist_method();
|
||||
if (BN_nist_mod_func(p))
|
||||
meth = EC_GFp_nist_method();
|
||||
else
|
||||
meth = EC_GFp_mont_method();
|
||||
#endif
|
||||
|
||||
ret = EC_GROUP_new(meth);
|
||||
@@ -118,36 +65,8 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
|
||||
return NULL;
|
||||
|
||||
if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) {
|
||||
unsigned long err;
|
||||
|
||||
err = ERR_peek_last_error();
|
||||
|
||||
if (!(ERR_GET_LIB(err) == ERR_LIB_EC &&
|
||||
((ERR_GET_REASON(err) == EC_R_NOT_A_NIST_PRIME) ||
|
||||
(ERR_GET_REASON(err) == EC_R_NOT_A_SUPPORTED_NIST_PRIME)))) {
|
||||
/* real error */
|
||||
|
||||
EC_GROUP_clear_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* not an actual error, we just cannot use EC_GFp_nist_method
|
||||
*/
|
||||
|
||||
ERR_clear_error();
|
||||
|
||||
EC_GROUP_clear_free(ret);
|
||||
meth = EC_GFp_mont_method();
|
||||
|
||||
ret = EC_GROUP_new(meth);
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) {
|
||||
EC_GROUP_clear_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -160,10 +79,6 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a,
|
||||
const EC_METHOD *meth;
|
||||
EC_GROUP *ret;
|
||||
|
||||
# ifdef OPENSSL_FIPS
|
||||
if (FIPS_mode())
|
||||
return FIPS_ec_group_new_curve_gf2m(p, a, b, ctx);
|
||||
# endif
|
||||
meth = EC_GF2m_simple_method();
|
||||
|
||||
ret = EC_GROUP_new(meth);
|
||||
|
||||
@@ -1,62 +1,11 @@
|
||||
/* crypto/ec/ec_err.c */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE: this file was auto generated by the mkerr.pl script: any changes
|
||||
* made to it will be overwritten when the script next updates this file,
|
||||
* only reason strings will be preserved.
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2016 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
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -70,21 +19,28 @@
|
||||
# define ERR_REASON(reason) ERR_PACK(ERR_LIB_EC,0,reason)
|
||||
|
||||
static ERR_STRING_DATA EC_str_functs[] = {
|
||||
{ERR_FUNC(EC_F_BN_TO_FELEM), "BN_TO_FELEM"},
|
||||
{ERR_FUNC(EC_F_COMPUTE_WNAF), "COMPUTE_WNAF"},
|
||||
{ERR_FUNC(EC_F_BN_TO_FELEM), "BN_to_felem"},
|
||||
{ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"},
|
||||
{ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"},
|
||||
{ERR_FUNC(EC_F_D2I_ECPRIVATEKEY), "d2i_ECPrivateKey"},
|
||||
{ERR_FUNC(EC_F_DO_EC_KEY_PRINT), "DO_EC_KEY_PRINT"},
|
||||
{ERR_FUNC(EC_F_ECDH_CMS_DECRYPT), "ECDH_CMS_DECRYPT"},
|
||||
{ERR_FUNC(EC_F_ECDH_CMS_SET_SHARED_INFO), "ECDH_CMS_SET_SHARED_INFO"},
|
||||
{ERR_FUNC(EC_F_ECKEY_PARAM2TYPE), "ECKEY_PARAM2TYPE"},
|
||||
{ERR_FUNC(EC_F_ECKEY_PARAM_DECODE), "ECKEY_PARAM_DECODE"},
|
||||
{ERR_FUNC(EC_F_ECKEY_PRIV_DECODE), "ECKEY_PRIV_DECODE"},
|
||||
{ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE), "ECKEY_PRIV_ENCODE"},
|
||||
{ERR_FUNC(EC_F_ECKEY_PUB_DECODE), "ECKEY_PUB_DECODE"},
|
||||
{ERR_FUNC(EC_F_ECKEY_PUB_ENCODE), "ECKEY_PUB_ENCODE"},
|
||||
{ERR_FUNC(EC_F_ECKEY_TYPE2PARAM), "ECKEY_TYPE2PARAM"},
|
||||
{ERR_FUNC(EC_F_DO_EC_KEY_PRINT), "do_EC_KEY_print"},
|
||||
{ERR_FUNC(EC_F_ECDH_CMS_DECRYPT), "ecdh_cms_decrypt"},
|
||||
{ERR_FUNC(EC_F_ECDH_CMS_SET_SHARED_INFO), "ecdh_cms_set_shared_info"},
|
||||
{ERR_FUNC(EC_F_ECDH_COMPUTE_KEY), "ECDH_compute_key"},
|
||||
{ERR_FUNC(EC_F_ECDH_SIMPLE_COMPUTE_KEY), "ecdh_simple_compute_key"},
|
||||
{ERR_FUNC(EC_F_ECDSA_DO_SIGN_EX), "ECDSA_do_sign_ex"},
|
||||
{ERR_FUNC(EC_F_ECDSA_DO_VERIFY), "ECDSA_do_verify"},
|
||||
{ERR_FUNC(EC_F_ECDSA_SIGN_EX), "ECDSA_sign_ex"},
|
||||
{ERR_FUNC(EC_F_ECDSA_SIGN_SETUP), "ECDSA_sign_setup"},
|
||||
{ERR_FUNC(EC_F_ECDSA_SIG_NEW), "ECDSA_SIG_new"},
|
||||
{ERR_FUNC(EC_F_ECDSA_VERIFY), "ECDSA_verify"},
|
||||
{ERR_FUNC(EC_F_ECKEY_PARAM2TYPE), "eckey_param2type"},
|
||||
{ERR_FUNC(EC_F_ECKEY_PARAM_DECODE), "eckey_param_decode"},
|
||||
{ERR_FUNC(EC_F_ECKEY_PRIV_DECODE), "eckey_priv_decode"},
|
||||
{ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE), "eckey_priv_encode"},
|
||||
{ERR_FUNC(EC_F_ECKEY_PUB_DECODE), "eckey_pub_decode"},
|
||||
{ERR_FUNC(EC_F_ECKEY_PUB_ENCODE), "eckey_pub_encode"},
|
||||
{ERR_FUNC(EC_F_ECKEY_TYPE2PARAM), "eckey_type2param"},
|
||||
{ERR_FUNC(EC_F_ECPARAMETERS_PRINT), "ECParameters_print"},
|
||||
{ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"},
|
||||
{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT), "ECPKParameters_print"},
|
||||
@@ -94,21 +50,14 @@ static ERR_STRING_DATA EC_str_functs[] = {
|
||||
"ecp_nistz256_mult_precompute"},
|
||||
{ERR_FUNC(EC_F_ECP_NISTZ256_POINTS_MUL), "ecp_nistz256_points_mul"},
|
||||
{ERR_FUNC(EC_F_ECP_NISTZ256_PRE_COMP_NEW), "ecp_nistz256_pre_comp_new"},
|
||||
{ERR_FUNC(EC_F_ECP_NISTZ256_SET_WORDS), "ecp_nistz256_set_words"},
|
||||
{ERR_FUNC(EC_F_ECP_NISTZ256_WINDOWED_MUL), "ecp_nistz256_windowed_mul"},
|
||||
{ERR_FUNC(EC_F_ECP_NIST_MOD_192), "ECP_NIST_MOD_192"},
|
||||
{ERR_FUNC(EC_F_ECP_NIST_MOD_224), "ECP_NIST_MOD_224"},
|
||||
{ERR_FUNC(EC_F_ECP_NIST_MOD_256), "ECP_NIST_MOD_256"},
|
||||
{ERR_FUNC(EC_F_ECP_NIST_MOD_521), "ECP_NIST_MOD_521"},
|
||||
{ERR_FUNC(EC_F_EC_ASN1_GROUP2CURVE), "EC_ASN1_GROUP2CURVE"},
|
||||
{ERR_FUNC(EC_F_EC_ASN1_GROUP2FIELDID), "EC_ASN1_GROUP2FIELDID"},
|
||||
{ERR_FUNC(EC_F_EC_ASN1_GROUP2PARAMETERS), "EC_ASN1_GROUP2PARAMETERS"},
|
||||
{ERR_FUNC(EC_F_EC_ASN1_GROUP2PKPARAMETERS), "EC_ASN1_GROUP2PKPARAMETERS"},
|
||||
{ERR_FUNC(EC_F_EC_ASN1_PARAMETERS2GROUP), "EC_ASN1_PARAMETERS2GROUP"},
|
||||
{ERR_FUNC(EC_F_EC_ASN1_PKPARAMETERS2GROUP), "EC_ASN1_PKPARAMETERS2GROUP"},
|
||||
{ERR_FUNC(EC_F_EC_EX_DATA_SET_DATA), "EC_EX_DATA_set_data"},
|
||||
{ERR_FUNC(EC_F_ECX_KEY_OP), "ecx_key_op"},
|
||||
{ERR_FUNC(EC_F_ECX_PRIV_ENCODE), "ecx_priv_encode"},
|
||||
{ERR_FUNC(EC_F_ECX_PUB_ENCODE), "ecx_pub_encode"},
|
||||
{ERR_FUNC(EC_F_EC_ASN1_GROUP2CURVE), "ec_asn1_group2curve"},
|
||||
{ERR_FUNC(EC_F_EC_ASN1_GROUP2FIELDID), "ec_asn1_group2fieldid"},
|
||||
{ERR_FUNC(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY),
|
||||
"EC_GF2M_MONTGOMERY_POINT_MULTIPLY"},
|
||||
"ec_GF2m_montgomery_point_multiply"},
|
||||
{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT),
|
||||
"ec_GF2m_simple_group_check_discriminant"},
|
||||
{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE),
|
||||
@@ -129,8 +78,6 @@ static ERR_STRING_DATA EC_str_functs[] = {
|
||||
{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SQR), "ec_GFp_mont_field_sqr"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE),
|
||||
"ec_GFp_mont_group_set_curve"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP),
|
||||
"EC_GFP_MONT_GROUP_SET_CURVE_GFP"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE),
|
||||
"ec_GFp_nistp224_group_set_curve"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_NISTP224_POINTS_MUL), "ec_GFp_nistp224_points_mul"},
|
||||
@@ -154,10 +101,6 @@ static ERR_STRING_DATA EC_str_functs[] = {
|
||||
"ec_GFp_simple_group_check_discriminant"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE),
|
||||
"ec_GFp_simple_group_set_curve"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP),
|
||||
"EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR),
|
||||
"EC_GFP_SIMPLE_GROUP_SET_GENERATOR"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE), "ec_GFp_simple_make_affine"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_OCT2POINT), "ec_GFp_simple_oct2point"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT2OCT), "ec_GFp_simple_point2oct"},
|
||||
@@ -165,46 +108,48 @@ static ERR_STRING_DATA EC_str_functs[] = {
|
||||
"ec_GFp_simple_points_make_affine"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES),
|
||||
"ec_GFp_simple_point_get_affine_coordinates"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP),
|
||||
"EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES),
|
||||
"ec_GFp_simple_point_set_affine_coordinates"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP),
|
||||
"EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES),
|
||||
"ec_GFp_simple_set_compressed_coordinates"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP),
|
||||
"EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_CHECK), "EC_GROUP_check"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_CHECK_DISCRIMINANT),
|
||||
"EC_GROUP_check_discriminant"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_COPY), "EC_GROUP_copy"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_GET0_GENERATOR), "EC_GROUP_get0_generator"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_GET_COFACTOR), "EC_GROUP_get_cofactor"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GF2M), "EC_GROUP_get_curve_GF2m"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GFP), "EC_GROUP_get_curve_GFp"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_GET_DEGREE), "EC_GROUP_get_degree"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_GET_ORDER), "EC_GROUP_get_order"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_GET_ECPARAMETERS), "EC_GROUP_get_ecparameters"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_GET_ECPKPARAMETERS),
|
||||
"EC_GROUP_get_ecpkparameters"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS),
|
||||
"EC_GROUP_get_pentanomial_basis"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS),
|
||||
"EC_GROUP_get_trinomial_basis"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_NEW), "EC_GROUP_new"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_NEW_BY_CURVE_NAME), "EC_GROUP_new_by_curve_name"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA), "EC_GROUP_NEW_FROM_DATA"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_PRECOMPUTE_MULT), "EC_GROUP_precompute_mult"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA), "ec_group_new_from_data"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS),
|
||||
"EC_GROUP_new_from_ecparameters"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS),
|
||||
"EC_GROUP_new_from_ecpkparameters"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GF2M), "EC_GROUP_set_curve_GF2m"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GFP), "EC_GROUP_set_curve_GFp"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_SET_EXTRA_DATA), "EC_GROUP_SET_EXTRA_DATA"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_SET_GENERATOR), "EC_GROUP_set_generator"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_CHECK_KEY), "EC_KEY_check_key"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_COPY), "EC_KEY_copy"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_GENERATE_KEY), "EC_KEY_generate_key"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_NEW), "EC_KEY_new"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_NEW_METHOD), "EC_KEY_new_method"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_OCT2PRIV), "EC_KEY_oct2priv"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_PRIV2OCT), "EC_KEY_priv2oct"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES),
|
||||
"EC_KEY_set_public_key_affine_coordinates"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_SIMPLE_CHECK_KEY), "ec_key_simple_check_key"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_SIMPLE_OCT2PRIV), "ec_key_simple_oct2priv"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_SIMPLE_PRIV2OCT), "ec_key_simple_priv2oct"},
|
||||
{ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"},
|
||||
@@ -220,7 +165,6 @@ static ERR_STRING_DATA EC_str_functs[] = {
|
||||
{ERR_FUNC(EC_F_EC_POINT_IS_AT_INFINITY), "EC_POINT_is_at_infinity"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_IS_ON_CURVE), "EC_POINT_is_on_curve"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_MAKE_AFFINE), "EC_POINT_make_affine"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_MUL), "EC_POINT_mul"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_NEW), "EC_POINT_new"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_OCT2POINT), "EC_POINT_oct2point"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_POINT2OCT), "EC_POINT_point2oct"},
|
||||
@@ -235,34 +179,41 @@ static ERR_STRING_DATA EC_str_functs[] = {
|
||||
{ERR_FUNC(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP),
|
||||
"EC_POINT_set_Jprojective_coordinates_GFp"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY), "EC_POINT_set_to_infinity"},
|
||||
{ERR_FUNC(EC_F_EC_PRE_COMP_DUP), "EC_PRE_COMP_DUP"},
|
||||
{ERR_FUNC(EC_F_EC_PRE_COMP_NEW), "EC_PRE_COMP_NEW"},
|
||||
{ERR_FUNC(EC_F_EC_PRE_COMP_NEW), "ec_pre_comp_new"},
|
||||
{ERR_FUNC(EC_F_EC_WNAF_MUL), "ec_wNAF_mul"},
|
||||
{ERR_FUNC(EC_F_EC_WNAF_PRECOMPUTE_MULT), "ec_wNAF_precompute_mult"},
|
||||
{ERR_FUNC(EC_F_I2D_ECPARAMETERS), "i2d_ECParameters"},
|
||||
{ERR_FUNC(EC_F_I2D_ECPKPARAMETERS), "i2d_ECPKParameters"},
|
||||
{ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"},
|
||||
{ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"},
|
||||
{ERR_FUNC(EC_F_NISTP224_PRE_COMP_NEW), "NISTP224_PRE_COMP_NEW"},
|
||||
{ERR_FUNC(EC_F_NISTP256_PRE_COMP_NEW), "NISTP256_PRE_COMP_NEW"},
|
||||
{ERR_FUNC(EC_F_NISTP521_PRE_COMP_NEW), "NISTP521_PRE_COMP_NEW"},
|
||||
{ERR_FUNC(EC_F_NISTP224_PRE_COMP_NEW), "nistp224_pre_comp_new"},
|
||||
{ERR_FUNC(EC_F_NISTP256_PRE_COMP_NEW), "nistp256_pre_comp_new"},
|
||||
{ERR_FUNC(EC_F_NISTP521_PRE_COMP_NEW), "nistp521_pre_comp_new"},
|
||||
{ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"},
|
||||
{ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "OLD_EC_PRIV_DECODE"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_CTRL), "PKEY_EC_CTRL"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_CTRL_STR), "PKEY_EC_CTRL_STR"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_DERIVE), "PKEY_EC_DERIVE"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_KEYGEN), "PKEY_EC_KEYGEN"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_PARAMGEN), "PKEY_EC_PARAMGEN"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_SIGN), "PKEY_EC_SIGN"},
|
||||
{ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "old_ec_priv_decode"},
|
||||
{ERR_FUNC(EC_F_OSSL_ECDH_COMPUTE_KEY), "ossl_ecdh_compute_key"},
|
||||
{ERR_FUNC(EC_F_OSSL_ECDSA_SIGN_SIG), "ossl_ecdsa_sign_sig"},
|
||||
{ERR_FUNC(EC_F_OSSL_ECDSA_VERIFY_SIG), "ossl_ecdsa_verify_sig"},
|
||||
{ERR_FUNC(EC_F_PKEY_ECX_DERIVE), "pkey_ecx_derive"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_CTRL), "pkey_ec_ctrl"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_CTRL_STR), "pkey_ec_ctrl_str"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_DERIVE), "pkey_ec_derive"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_KEYGEN), "pkey_ec_keygen"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_PARAMGEN), "pkey_ec_paramgen"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_SIGN), "pkey_ec_sign"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static ERR_STRING_DATA EC_str_reasons[] = {
|
||||
{ERR_REASON(EC_R_ASN1_ERROR), "asn1 error"},
|
||||
{ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD), "asn1 unknown field"},
|
||||
{ERR_REASON(EC_R_BAD_SIGNATURE), "bad signature"},
|
||||
{ERR_REASON(EC_R_BIGNUM_OUT_OF_RANGE), "bignum out of range"},
|
||||
{ERR_REASON(EC_R_BUFFER_TOO_SMALL), "buffer too small"},
|
||||
{ERR_REASON(EC_R_COORDINATES_OUT_OF_RANGE), "coordinates out of range"},
|
||||
{ERR_REASON(EC_R_CURVE_DOES_NOT_SUPPORT_ECDH),
|
||||
"curve does not support ecdh"},
|
||||
{ERR_REASON(EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING),
|
||||
"curve does not support signing"},
|
||||
{ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE),
|
||||
"d2i ecpkparameters failure"},
|
||||
{ERR_REASON(EC_R_DECODE_ERROR), "decode error"},
|
||||
@@ -286,6 +237,9 @@ static ERR_STRING_DATA EC_str_reasons[] = {
|
||||
{ERR_REASON(EC_R_INVALID_FIELD), "invalid field"},
|
||||
{ERR_REASON(EC_R_INVALID_FORM), "invalid form"},
|
||||
{ERR_REASON(EC_R_INVALID_GROUP_ORDER), "invalid group order"},
|
||||
{ERR_REASON(EC_R_INVALID_KEY), "invalid key"},
|
||||
{ERR_REASON(EC_R_INVALID_OUTPUT_LENGTH), "invalid output length"},
|
||||
{ERR_REASON(EC_R_INVALID_PEER_KEY), "invalid peer key"},
|
||||
{ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"},
|
||||
{ERR_REASON(EC_R_INVALID_PRIVATE_KEY), "invalid private key"},
|
||||
{ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS), "invalid trinomial basis"},
|
||||
@@ -293,19 +247,22 @@ static ERR_STRING_DATA EC_str_reasons[] = {
|
||||
{ERR_REASON(EC_R_KEYS_NOT_SET), "keys not set"},
|
||||
{ERR_REASON(EC_R_MISSING_PARAMETERS), "missing parameters"},
|
||||
{ERR_REASON(EC_R_MISSING_PRIVATE_KEY), "missing private key"},
|
||||
{ERR_REASON(EC_R_NEED_NEW_SETUP_VALUES), "need new setup values"},
|
||||
{ERR_REASON(EC_R_NOT_A_NIST_PRIME), "not a NIST prime"},
|
||||
{ERR_REASON(EC_R_NOT_A_SUPPORTED_NIST_PRIME),
|
||||
"not a supported NIST prime"},
|
||||
{ERR_REASON(EC_R_NOT_IMPLEMENTED), "not implemented"},
|
||||
{ERR_REASON(EC_R_NOT_INITIALIZED), "not initialized"},
|
||||
{ERR_REASON(EC_R_NO_FIELD_MOD), "no field mod"},
|
||||
{ERR_REASON(EC_R_NO_PARAMETERS_SET), "no parameters set"},
|
||||
{ERR_REASON(EC_R_NO_PRIVATE_VALUE), "no private value"},
|
||||
{ERR_REASON(EC_R_OPERATION_NOT_SUPPORTED), "operation not supported"},
|
||||
{ERR_REASON(EC_R_PASSED_NULL_PARAMETER), "passed null parameter"},
|
||||
{ERR_REASON(EC_R_PEER_KEY_ERROR), "peer key error"},
|
||||
{ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE),
|
||||
"pkparameters2group failure"},
|
||||
{ERR_REASON(EC_R_POINT_ARITHMETIC_FAILURE), "point arithmetic failure"},
|
||||
{ERR_REASON(EC_R_POINT_AT_INFINITY), "point at infinity"},
|
||||
{ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE), "point is not on curve"},
|
||||
{ERR_REASON(EC_R_RANDOM_NUMBER_GENERATION_FAILED),
|
||||
"random number generation failed"},
|
||||
{ERR_REASON(EC_R_SHARED_INFO_ERROR), "shared info error"},
|
||||
{ERR_REASON(EC_R_SLOT_FULL), "slot full"},
|
||||
{ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"},
|
||||
@@ -320,7 +277,7 @@ static ERR_STRING_DATA EC_str_reasons[] = {
|
||||
|
||||
#endif
|
||||
|
||||
void ERR_load_EC_strings(void)
|
||||
int ERR_load_EC_strings(void)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
@@ -329,4 +286,5 @@ void ERR_load_EC_strings(void)
|
||||
ERR_load_strings(0, EC_str_reasons);
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1,93 +1,27 @@
|
||||
/* crypto/ec/ec_key.c */
|
||||
/*
|
||||
* Written by Nils Larsch for the OpenSSL project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright 2002-2016 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* Portions originally developed by SUN MICROSYSTEMS, INC., and
|
||||
* contributed to the OpenSSL project.
|
||||
*/
|
||||
|
||||
#include <internal/cryptlib.h>
|
||||
#include <string.h>
|
||||
#include "ec_lcl.h"
|
||||
#include <openssl/err.h>
|
||||
#ifdef OPENSSL_FIPS
|
||||
# include <openssl/fips.h>
|
||||
#endif
|
||||
#include <openssl/engine.h>
|
||||
|
||||
EC_KEY *EC_KEY_new(void)
|
||||
{
|
||||
EC_KEY *ret;
|
||||
|
||||
ret = (EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY));
|
||||
if (ret == NULL) {
|
||||
ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ret->version = 1;
|
||||
ret->flags = 0;
|
||||
ret->group = NULL;
|
||||
ret->pub_key = NULL;
|
||||
ret->priv_key = NULL;
|
||||
ret->enc_flag = 0;
|
||||
ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
|
||||
ret->references = 1;
|
||||
ret->method_data = NULL;
|
||||
return (ret);
|
||||
return EC_KEY_new_method(NULL);
|
||||
}
|
||||
|
||||
EC_KEY *EC_KEY_new_by_curve_name(int nid)
|
||||
@@ -100,6 +34,11 @@ EC_KEY *EC_KEY_new_by_curve_name(int nid)
|
||||
EC_KEY_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
if (ret->meth->set_group != NULL
|
||||
&& ret->meth->set_group(ret, ret->group) == 0) {
|
||||
EC_KEY_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -110,101 +49,115 @@ void EC_KEY_free(EC_KEY *r)
|
||||
if (r == NULL)
|
||||
return;
|
||||
|
||||
i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_EC);
|
||||
#ifdef REF_PRINT
|
||||
REF_PRINT("EC_KEY", r);
|
||||
#endif
|
||||
CRYPTO_atomic_add(&r->references, -1, &i, r->lock);
|
||||
REF_PRINT_COUNT("EC_KEY", r);
|
||||
if (i > 0)
|
||||
return;
|
||||
#ifdef REF_CHECK
|
||||
if (i < 0) {
|
||||
fprintf(stderr, "EC_KEY_free, bad reference count\n");
|
||||
abort();
|
||||
}
|
||||
REF_ASSERT_ISNT(i < 0);
|
||||
|
||||
if (r->meth->finish != NULL)
|
||||
r->meth->finish(r);
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_finish(r->engine);
|
||||
#endif
|
||||
|
||||
if (r->group != NULL)
|
||||
EC_GROUP_free(r->group);
|
||||
if (r->pub_key != NULL)
|
||||
EC_POINT_free(r->pub_key);
|
||||
if (r->priv_key != NULL)
|
||||
BN_clear_free(r->priv_key);
|
||||
if (r->group && r->group->meth->keyfinish)
|
||||
r->group->meth->keyfinish(r);
|
||||
|
||||
EC_EX_DATA_free_all_data(&r->method_data);
|
||||
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data);
|
||||
CRYPTO_THREAD_lock_free(r->lock);
|
||||
EC_GROUP_free(r->group);
|
||||
EC_POINT_free(r->pub_key);
|
||||
BN_clear_free(r->priv_key);
|
||||
|
||||
OPENSSL_cleanse((void *)r, sizeof(EC_KEY));
|
||||
|
||||
OPENSSL_free(r);
|
||||
OPENSSL_clear_free((void *)r, sizeof(EC_KEY));
|
||||
}
|
||||
|
||||
EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
|
||||
{
|
||||
EC_EXTRA_DATA *d;
|
||||
|
||||
if (dest == NULL || src == NULL) {
|
||||
ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
if (src->meth != dest->meth) {
|
||||
if (dest->meth->finish != NULL)
|
||||
dest->meth->finish(dest);
|
||||
if (dest->group && dest->group->meth->keyfinish)
|
||||
dest->group->meth->keyfinish(dest);
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (ENGINE_finish(dest->engine) == 0)
|
||||
return 0;
|
||||
dest->engine = NULL;
|
||||
#endif
|
||||
}
|
||||
/* copy the parameters */
|
||||
if (src->group) {
|
||||
if (src->group != NULL) {
|
||||
const EC_METHOD *meth = EC_GROUP_method_of(src->group);
|
||||
/* clear the old group */
|
||||
if (dest->group)
|
||||
EC_GROUP_free(dest->group);
|
||||
EC_GROUP_free(dest->group);
|
||||
dest->group = EC_GROUP_new(meth);
|
||||
if (dest->group == NULL)
|
||||
return NULL;
|
||||
if (!EC_GROUP_copy(dest->group, src->group))
|
||||
return NULL;
|
||||
}
|
||||
/* copy the public key */
|
||||
if (src->pub_key && src->group) {
|
||||
if (dest->pub_key)
|
||||
|
||||
/* copy the public key */
|
||||
if (src->pub_key != NULL) {
|
||||
EC_POINT_free(dest->pub_key);
|
||||
dest->pub_key = EC_POINT_new(src->group);
|
||||
if (dest->pub_key == NULL)
|
||||
return NULL;
|
||||
if (!EC_POINT_copy(dest->pub_key, src->pub_key))
|
||||
return NULL;
|
||||
}
|
||||
/* copy the private key */
|
||||
if (src->priv_key) {
|
||||
if (dest->priv_key == NULL) {
|
||||
dest->priv_key = BN_new();
|
||||
if (dest->priv_key == NULL)
|
||||
dest->pub_key = EC_POINT_new(src->group);
|
||||
if (dest->pub_key == NULL)
|
||||
return NULL;
|
||||
if (!EC_POINT_copy(dest->pub_key, src->pub_key))
|
||||
return NULL;
|
||||
}
|
||||
/* copy the private key */
|
||||
if (src->priv_key != NULL) {
|
||||
if (dest->priv_key == NULL) {
|
||||
dest->priv_key = BN_new();
|
||||
if (dest->priv_key == NULL)
|
||||
return NULL;
|
||||
}
|
||||
if (!BN_copy(dest->priv_key, src->priv_key))
|
||||
return NULL;
|
||||
if (src->group->meth->keycopy
|
||||
&& src->group->meth->keycopy(dest, src) == 0)
|
||||
return NULL;
|
||||
}
|
||||
if (!BN_copy(dest->priv_key, src->priv_key))
|
||||
return NULL;
|
||||
}
|
||||
/* copy method/extra data */
|
||||
EC_EX_DATA_free_all_data(&dest->method_data);
|
||||
|
||||
for (d = src->method_data; d != NULL; d = d->next) {
|
||||
void *t = d->dup_func(d->data);
|
||||
|
||||
if (t == NULL)
|
||||
return 0;
|
||||
if (!EC_EX_DATA_set_data
|
||||
(&dest->method_data, t, d->dup_func, d->free_func,
|
||||
d->clear_free_func))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* copy the rest */
|
||||
dest->enc_flag = src->enc_flag;
|
||||
dest->conv_form = src->conv_form;
|
||||
dest->version = src->version;
|
||||
dest->flags = src->flags;
|
||||
if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY,
|
||||
&dest->ex_data, &src->ex_data))
|
||||
return NULL;
|
||||
|
||||
if (src->meth != dest->meth) {
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (src->engine != NULL && ENGINE_init(src->engine) == 0)
|
||||
return NULL;
|
||||
dest->engine = src->engine;
|
||||
#endif
|
||||
dest->meth = src->meth;
|
||||
}
|
||||
|
||||
if (src->meth->copy != NULL && src->meth->copy(dest, src) == 0)
|
||||
return NULL;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
|
||||
{
|
||||
EC_KEY *ret = EC_KEY_new();
|
||||
EC_KEY *ret = EC_KEY_new_method(ec_key->engine);
|
||||
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
|
||||
if (EC_KEY_copy(ret, ec_key) == NULL) {
|
||||
EC_KEY_free(ret);
|
||||
return NULL;
|
||||
@@ -214,38 +167,42 @@ EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
|
||||
|
||||
int EC_KEY_up_ref(EC_KEY *r)
|
||||
{
|
||||
int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC);
|
||||
#ifdef REF_PRINT
|
||||
REF_PRINT("EC_KEY", r);
|
||||
#endif
|
||||
#ifdef REF_CHECK
|
||||
if (i < 2) {
|
||||
fprintf(stderr, "EC_KEY_up, bad reference count\n");
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
int i;
|
||||
|
||||
if (CRYPTO_atomic_add(&r->references, 1, &i, r->lock) <= 0)
|
||||
return 0;
|
||||
|
||||
REF_PRINT_COUNT("EC_KEY", r);
|
||||
REF_ASSERT_ISNT(i < 2);
|
||||
return ((i > 1) ? 1 : 0);
|
||||
}
|
||||
|
||||
int EC_KEY_generate_key(EC_KEY *eckey)
|
||||
{
|
||||
int ok = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *priv_key = NULL, *order = NULL;
|
||||
EC_POINT *pub_key = NULL;
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
if (FIPS_mode())
|
||||
return FIPS_ec_key_generate_key(eckey);
|
||||
#endif
|
||||
|
||||
if (!eckey || !eckey->group) {
|
||||
if (eckey == NULL || eckey->group == NULL) {
|
||||
ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (eckey->meth->keygen != NULL)
|
||||
return eckey->meth->keygen(eckey);
|
||||
ECerr(EC_F_EC_KEY_GENERATE_KEY, EC_R_OPERATION_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ossl_ec_key_gen(EC_KEY *eckey)
|
||||
{
|
||||
OPENSSL_assert(eckey->group->meth->keygen != NULL);
|
||||
return eckey->group->meth->keygen(eckey);
|
||||
}
|
||||
|
||||
int ec_key_simple_generate_key(EC_KEY *eckey)
|
||||
{
|
||||
int ok = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *priv_key = NULL;
|
||||
const BIGNUM *order = NULL;
|
||||
EC_POINT *pub_key = NULL;
|
||||
|
||||
if ((order = BN_new()) == NULL)
|
||||
goto err;
|
||||
if ((ctx = BN_CTX_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
@@ -256,7 +213,8 @@ int EC_KEY_generate_key(EC_KEY *eckey)
|
||||
} else
|
||||
priv_key = eckey->priv_key;
|
||||
|
||||
if (!EC_GROUP_get_order(eckey->group, order, ctx))
|
||||
order = EC_GROUP_get0_order(eckey->group);
|
||||
if (order == NULL)
|
||||
goto err;
|
||||
|
||||
do
|
||||
@@ -280,31 +238,49 @@ int EC_KEY_generate_key(EC_KEY *eckey)
|
||||
ok = 1;
|
||||
|
||||
err:
|
||||
if (order)
|
||||
BN_free(order);
|
||||
if (pub_key != NULL && eckey->pub_key == NULL)
|
||||
if (eckey->pub_key == NULL)
|
||||
EC_POINT_free(pub_key);
|
||||
if (priv_key != NULL && eckey->priv_key == NULL)
|
||||
if (eckey->priv_key != priv_key)
|
||||
BN_free(priv_key);
|
||||
if (ctx != NULL)
|
||||
BN_CTX_free(ctx);
|
||||
return (ok);
|
||||
BN_CTX_free(ctx);
|
||||
return ok;
|
||||
}
|
||||
|
||||
int ec_key_simple_generate_public_key(EC_KEY *eckey)
|
||||
{
|
||||
return EC_POINT_mul(eckey->group, eckey->pub_key, eckey->priv_key, NULL,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
int EC_KEY_check_key(const EC_KEY *eckey)
|
||||
{
|
||||
if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
|
||||
ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (eckey->group->meth->keycheck == NULL) {
|
||||
ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return eckey->group->meth->keycheck(eckey);
|
||||
}
|
||||
|
||||
int ec_key_simple_check_key(const EC_KEY *eckey)
|
||||
{
|
||||
int ok = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
const BIGNUM *order = NULL;
|
||||
EC_POINT *point = NULL;
|
||||
|
||||
if (!eckey || !eckey->group || !eckey->pub_key) {
|
||||
ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
|
||||
if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) {
|
||||
ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY);
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_AT_INFINITY);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -315,49 +291,47 @@ int EC_KEY_check_key(const EC_KEY *eckey)
|
||||
|
||||
/* testing whether the pub_key is on the elliptic curve */
|
||||
if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
|
||||
ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
|
||||
goto err;
|
||||
}
|
||||
/* testing whether pub_key * order is the point at infinity */
|
||||
order = &eckey->group->order;
|
||||
order = eckey->group->order;
|
||||
if (BN_is_zero(order)) {
|
||||
ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
|
||||
goto err;
|
||||
}
|
||||
if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
|
||||
ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (!EC_POINT_is_at_infinity(eckey->group, point)) {
|
||||
ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER);
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* in case the priv_key is present : check if generator * priv_key ==
|
||||
* pub_key
|
||||
*/
|
||||
if (eckey->priv_key) {
|
||||
if (eckey->priv_key != NULL) {
|
||||
if (BN_cmp(eckey->priv_key, order) >= 0) {
|
||||
ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER);
|
||||
goto err;
|
||||
}
|
||||
if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
|
||||
NULL, NULL, ctx)) {
|
||||
ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) {
|
||||
ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
ok = 1;
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_free(ctx);
|
||||
if (point != NULL)
|
||||
EC_POINT_free(point);
|
||||
return (ok);
|
||||
BN_CTX_free(ctx);
|
||||
EC_POINT_free(point);
|
||||
return ok;
|
||||
}
|
||||
|
||||
int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
|
||||
@@ -371,7 +345,7 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
|
||||
int tmp_nid, is_char_two = 0;
|
||||
#endif
|
||||
|
||||
if (!key || !key->group || !x || !y) {
|
||||
if (key == NULL || key->group == NULL || x == NULL || y == NULL) {
|
||||
ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
@@ -379,10 +353,11 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
|
||||
ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
point = EC_POINT_new(key->group);
|
||||
|
||||
if (!point)
|
||||
if (point == NULL)
|
||||
goto err;
|
||||
|
||||
tx = BN_CTX_get(ctx);
|
||||
@@ -414,10 +389,12 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* Check if retrieved coordinates match originals: if not values are out
|
||||
* of range.
|
||||
* Check if retrieved coordinates match originals and are less than field
|
||||
* order: if not values are out of range.
|
||||
*/
|
||||
if (BN_cmp(x, tx) || BN_cmp(y, ty)) {
|
||||
if (BN_cmp(x, tx) || BN_cmp(y, ty)
|
||||
|| (BN_cmp(x, key->group->field) >= 0)
|
||||
|| (BN_cmp(y, key->group->field) >= 0)) {
|
||||
ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
|
||||
EC_R_COORDINATES_OUT_OF_RANGE);
|
||||
goto err;
|
||||
@@ -446,8 +423,9 @@ const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
|
||||
|
||||
int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
|
||||
{
|
||||
if (key->group != NULL)
|
||||
EC_GROUP_free(key->group);
|
||||
if (key->meth->set_group != NULL && key->meth->set_group(key, group) == 0)
|
||||
return 0;
|
||||
EC_GROUP_free(key->group);
|
||||
key->group = EC_GROUP_dup(group);
|
||||
return (key->group == NULL) ? 0 : 1;
|
||||
}
|
||||
@@ -459,8 +437,15 @@ const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
|
||||
|
||||
int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
|
||||
{
|
||||
if (key->priv_key)
|
||||
BN_clear_free(key->priv_key);
|
||||
if (key->group == NULL || key->group->meth == NULL)
|
||||
return 0;
|
||||
if (key->group->meth->set_private != NULL
|
||||
&& key->group->meth->set_private(key, priv_key) == 0)
|
||||
return 0;
|
||||
if (key->meth->set_private != NULL
|
||||
&& key->meth->set_private(key, priv_key) == 0)
|
||||
return 0;
|
||||
BN_clear_free(key->priv_key);
|
||||
key->priv_key = BN_dup(priv_key);
|
||||
return (key->priv_key == NULL) ? 0 : 1;
|
||||
}
|
||||
@@ -472,8 +457,10 @@ const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
|
||||
|
||||
int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
|
||||
{
|
||||
if (key->pub_key != NULL)
|
||||
EC_POINT_free(key->pub_key);
|
||||
if (key->meth->set_public != NULL
|
||||
&& key->meth->set_public(key, pub_key) == 0)
|
||||
return 0;
|
||||
EC_POINT_free(key->pub_key);
|
||||
key->pub_key = EC_POINT_dup(pub_key, key->group);
|
||||
return (key->pub_key == NULL) ? 0 : 1;
|
||||
}
|
||||
@@ -500,41 +487,6 @@ void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
|
||||
EC_GROUP_set_point_conversion_form(key->group, cform);
|
||||
}
|
||||
|
||||
void *EC_KEY_get_key_method_data(EC_KEY *key,
|
||||
void *(*dup_func) (void *),
|
||||
void (*free_func) (void *),
|
||||
void (*clear_free_func) (void *))
|
||||
{
|
||||
void *ret;
|
||||
|
||||
CRYPTO_r_lock(CRYPTO_LOCK_EC);
|
||||
ret =
|
||||
EC_EX_DATA_get_data(key->method_data, dup_func, free_func,
|
||||
clear_free_func);
|
||||
CRYPTO_r_unlock(CRYPTO_LOCK_EC);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
|
||||
void *(*dup_func) (void *),
|
||||
void (*free_func) (void *),
|
||||
void (*clear_free_func) (void *))
|
||||
{
|
||||
EC_EXTRA_DATA *ex_data;
|
||||
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_EC);
|
||||
ex_data =
|
||||
EC_EX_DATA_get_data(key->method_data, dup_func, free_func,
|
||||
clear_free_func);
|
||||
if (ex_data == NULL)
|
||||
EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func,
|
||||
clear_free_func);
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_EC);
|
||||
|
||||
return ex_data;
|
||||
}
|
||||
|
||||
void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
|
||||
{
|
||||
if (key->group != NULL)
|
||||
@@ -562,3 +514,124 @@ void EC_KEY_clear_flags(EC_KEY *key, int flags)
|
||||
{
|
||||
key->flags &= ~flags;
|
||||
}
|
||||
|
||||
size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form,
|
||||
unsigned char **pbuf, BN_CTX *ctx)
|
||||
{
|
||||
if (key == NULL || key->pub_key == NULL || key->group == NULL)
|
||||
return 0;
|
||||
return EC_POINT_point2buf(key->group, key->pub_key, form, pbuf, ctx);
|
||||
}
|
||||
|
||||
int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
if (key == NULL || key->group == NULL)
|
||||
return 0;
|
||||
if (key->pub_key == NULL)
|
||||
key->pub_key = EC_POINT_new(key->group);
|
||||
if (key->pub_key == NULL)
|
||||
return 0;
|
||||
if (EC_POINT_oct2point(key->group, key->pub_key, buf, len, ctx) == 0)
|
||||
return 0;
|
||||
/*
|
||||
* Save the point conversion form.
|
||||
* For non-custom curves the first octet of the buffer (excluding
|
||||
* the last significant bit) contains the point conversion form.
|
||||
* EC_POINT_oct2point() has already performed sanity checking of
|
||||
* the buffer so we know it is valid.
|
||||
*/
|
||||
if ((key->group->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0)
|
||||
key->conv_form = (point_conversion_form_t)(buf[0] & ~0x01);
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t EC_KEY_priv2oct(const EC_KEY *eckey,
|
||||
unsigned char *buf, size_t len)
|
||||
{
|
||||
if (eckey->group == NULL || eckey->group->meth == NULL)
|
||||
return 0;
|
||||
if (eckey->group->meth->priv2oct == NULL) {
|
||||
ECerr(EC_F_EC_KEY_PRIV2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return eckey->group->meth->priv2oct(eckey, buf, len);
|
||||
}
|
||||
|
||||
size_t ec_key_simple_priv2oct(const EC_KEY *eckey,
|
||||
unsigned char *buf, size_t len)
|
||||
{
|
||||
size_t buf_len;
|
||||
|
||||
buf_len = (EC_GROUP_order_bits(eckey->group) + 7) / 8;
|
||||
if (eckey->priv_key == NULL)
|
||||
return 0;
|
||||
if (buf == NULL)
|
||||
return buf_len;
|
||||
else if (len < buf_len)
|
||||
return 0;
|
||||
|
||||
/* Octetstring may need leading zeros if BN is to short */
|
||||
|
||||
if (BN_bn2binpad(eckey->priv_key, buf, buf_len) == -1) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_PRIV2OCT, EC_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return buf_len;
|
||||
}
|
||||
|
||||
int EC_KEY_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len)
|
||||
{
|
||||
if (eckey->group == NULL || eckey->group->meth == NULL)
|
||||
return 0;
|
||||
if (eckey->group->meth->oct2priv == NULL) {
|
||||
ECerr(EC_F_EC_KEY_OCT2PRIV, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
return eckey->group->meth->oct2priv(eckey, buf, len);
|
||||
}
|
||||
|
||||
int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len)
|
||||
{
|
||||
if (eckey->priv_key == NULL)
|
||||
eckey->priv_key = BN_secure_new();
|
||||
if (eckey->priv_key == NULL) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
eckey->priv_key = BN_bin2bn(buf, len, eckey->priv_key);
|
||||
if (eckey->priv_key == NULL) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_BN_LIB);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf)
|
||||
{
|
||||
size_t len;
|
||||
unsigned char *buf;
|
||||
len = EC_KEY_priv2oct(eckey, NULL, 0);
|
||||
if (len == 0)
|
||||
return 0;
|
||||
buf = OPENSSL_malloc(len);
|
||||
if (buf == NULL)
|
||||
return 0;
|
||||
len = EC_KEY_priv2oct(eckey, buf, len);
|
||||
if (len == 0) {
|
||||
OPENSSL_free(buf);
|
||||
return 0;
|
||||
}
|
||||
*pbuf = buf;
|
||||
return len;
|
||||
}
|
||||
|
||||
int EC_KEY_can_sign(const EC_KEY *eckey)
|
||||
{
|
||||
if (eckey->group == NULL || eckey->group->meth == NULL
|
||||
|| (eckey->group->meth->flags & EC_FLAGS_NO_SIGN))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
317
crypto/ec/ec_kmeth.c
Normal file
317
crypto/ec/ec_kmeth.c
Normal file
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
* Copyright 2015-2016 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
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/err.h>
|
||||
#include "ec_lcl.h"
|
||||
|
||||
|
||||
static const EC_KEY_METHOD openssl_ec_key_method = {
|
||||
"OpenSSL EC_KEY method",
|
||||
0,
|
||||
0,0,0,0,0,0,
|
||||
ossl_ec_key_gen,
|
||||
ossl_ecdh_compute_key,
|
||||
ossl_ecdsa_sign,
|
||||
ossl_ecdsa_sign_setup,
|
||||
ossl_ecdsa_sign_sig,
|
||||
ossl_ecdsa_verify,
|
||||
ossl_ecdsa_verify_sig
|
||||
};
|
||||
|
||||
static const EC_KEY_METHOD *default_ec_key_meth = &openssl_ec_key_method;
|
||||
|
||||
const EC_KEY_METHOD *EC_KEY_OpenSSL(void)
|
||||
{
|
||||
return &openssl_ec_key_method;
|
||||
}
|
||||
|
||||
const EC_KEY_METHOD *EC_KEY_get_default_method(void)
|
||||
{
|
||||
return default_ec_key_meth;
|
||||
}
|
||||
|
||||
void EC_KEY_set_default_method(const EC_KEY_METHOD *meth)
|
||||
{
|
||||
if (meth == NULL)
|
||||
default_ec_key_meth = &openssl_ec_key_method;
|
||||
else
|
||||
default_ec_key_meth = meth;
|
||||
}
|
||||
|
||||
const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key)
|
||||
{
|
||||
return key->meth;
|
||||
}
|
||||
|
||||
int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth)
|
||||
{
|
||||
void (*finish)(EC_KEY *key) = key->meth->finish;
|
||||
|
||||
if (finish != NULL)
|
||||
finish(key);
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_finish(key->engine);
|
||||
key->engine = NULL;
|
||||
#endif
|
||||
|
||||
key->meth = meth;
|
||||
if (meth->init != NULL)
|
||||
return meth->init(key);
|
||||
return 1;
|
||||
}
|
||||
|
||||
EC_KEY *EC_KEY_new_method(ENGINE *engine)
|
||||
{
|
||||
EC_KEY *ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
|
||||
if (ret == NULL) {
|
||||
ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->references = 1;
|
||||
ret->lock = CRYPTO_THREAD_lock_new();
|
||||
if (ret->lock == NULL) {
|
||||
ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->meth = EC_KEY_get_default_method();
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (engine != NULL) {
|
||||
if (!ENGINE_init(engine)) {
|
||||
ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_ENGINE_LIB);
|
||||
goto err;
|
||||
}
|
||||
ret->engine = engine;
|
||||
} else
|
||||
ret->engine = ENGINE_get_default_EC();
|
||||
if (ret->engine != NULL) {
|
||||
ret->meth = ENGINE_get_EC(ret->engine);
|
||||
if (ret->meth == NULL) {
|
||||
ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_ENGINE_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ret->version = 1;
|
||||
ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
|
||||
|
||||
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ret->meth->init != NULL && ret->meth->init(ret) == 0) {
|
||||
ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_INIT_FAIL);
|
||||
goto err;
|
||||
}
|
||||
return ret;
|
||||
|
||||
err:
|
||||
EC_KEY_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
|
||||
const EC_KEY *eckey,
|
||||
void *(*KDF) (const void *in, size_t inlen, void *out,
|
||||
size_t *outlen))
|
||||
{
|
||||
unsigned char *sec = NULL;
|
||||
size_t seclen;
|
||||
if (eckey->meth->compute_key == NULL) {
|
||||
ECerr(EC_F_ECDH_COMPUTE_KEY, EC_R_OPERATION_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
if (outlen > INT_MAX) {
|
||||
ECerr(EC_F_ECDH_COMPUTE_KEY, EC_R_INVALID_OUTPUT_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
if (!eckey->meth->compute_key(&sec, &seclen, pub_key, eckey))
|
||||
return 0;
|
||||
if (KDF != NULL) {
|
||||
KDF(sec, seclen, out, &outlen);
|
||||
} else {
|
||||
if (outlen > seclen)
|
||||
outlen = seclen;
|
||||
memcpy(out, sec, outlen);
|
||||
}
|
||||
OPENSSL_clear_free(sec, seclen);
|
||||
return outlen;
|
||||
}
|
||||
|
||||
EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *meth)
|
||||
{
|
||||
EC_KEY_METHOD *ret = OPENSSL_zalloc(sizeof(*meth));
|
||||
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
if (meth != NULL)
|
||||
*ret = *meth;
|
||||
ret->flags |= EC_KEY_METHOD_DYNAMIC;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_free(EC_KEY_METHOD *meth)
|
||||
{
|
||||
if (meth->flags & EC_KEY_METHOD_DYNAMIC)
|
||||
OPENSSL_free(meth);
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth,
|
||||
int (*init)(EC_KEY *key),
|
||||
void (*finish)(EC_KEY *key),
|
||||
int (*copy)(EC_KEY *dest, const EC_KEY *src),
|
||||
int (*set_group)(EC_KEY *key, const EC_GROUP *grp),
|
||||
int (*set_private)(EC_KEY *key,
|
||||
const BIGNUM *priv_key),
|
||||
int (*set_public)(EC_KEY *key,
|
||||
const EC_POINT *pub_key))
|
||||
{
|
||||
meth->init = init;
|
||||
meth->finish = finish;
|
||||
meth->copy = copy;
|
||||
meth->set_group = set_group;
|
||||
meth->set_private = set_private;
|
||||
meth->set_public = set_public;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth,
|
||||
int (*keygen)(EC_KEY *key))
|
||||
{
|
||||
meth->keygen = keygen;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth,
|
||||
int (*ckey)(unsigned char **psec,
|
||||
size_t *pseclen,
|
||||
const EC_POINT *pub_key,
|
||||
const EC_KEY *ecdh))
|
||||
{
|
||||
meth->compute_key = ckey;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth,
|
||||
int (*sign)(int type, const unsigned char *dgst,
|
||||
int dlen, unsigned char *sig,
|
||||
unsigned int *siglen,
|
||||
const BIGNUM *kinv, const BIGNUM *r,
|
||||
EC_KEY *eckey),
|
||||
int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
|
||||
BIGNUM **kinvp, BIGNUM **rp),
|
||||
ECDSA_SIG *(*sign_sig)(const unsigned char *dgst,
|
||||
int dgst_len,
|
||||
const BIGNUM *in_kinv,
|
||||
const BIGNUM *in_r,
|
||||
EC_KEY *eckey))
|
||||
{
|
||||
meth->sign = sign;
|
||||
meth->sign_setup = sign_setup;
|
||||
meth->sign_sig = sign_sig;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_set_verify(EC_KEY_METHOD *meth,
|
||||
int (*verify)(int type, const unsigned
|
||||
char *dgst, int dgst_len,
|
||||
const unsigned char *sigbuf,
|
||||
int sig_len, EC_KEY *eckey),
|
||||
int (*verify_sig)(const unsigned char *dgst,
|
||||
int dgst_len,
|
||||
const ECDSA_SIG *sig,
|
||||
EC_KEY *eckey))
|
||||
{
|
||||
meth->verify = verify;
|
||||
meth->verify_sig = verify_sig;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_get_init(EC_KEY_METHOD *meth,
|
||||
int (**pinit)(EC_KEY *key),
|
||||
void (**pfinish)(EC_KEY *key),
|
||||
int (**pcopy)(EC_KEY *dest, const EC_KEY *src),
|
||||
int (**pset_group)(EC_KEY *key,
|
||||
const EC_GROUP *grp),
|
||||
int (**pset_private)(EC_KEY *key,
|
||||
const BIGNUM *priv_key),
|
||||
int (**pset_public)(EC_KEY *key,
|
||||
const EC_POINT *pub_key))
|
||||
{
|
||||
if (pinit != NULL)
|
||||
*pinit = meth->init;
|
||||
if (pfinish != NULL)
|
||||
*pfinish = meth->finish;
|
||||
if (pcopy != NULL)
|
||||
*pcopy = meth->copy;
|
||||
if (pset_group != NULL)
|
||||
*pset_group = meth->set_group;
|
||||
if (pset_private != NULL)
|
||||
*pset_private = meth->set_private;
|
||||
if (pset_public != NULL)
|
||||
*pset_public = meth->set_public;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_get_keygen(EC_KEY_METHOD *meth,
|
||||
int (**pkeygen)(EC_KEY *key))
|
||||
{
|
||||
if (pkeygen != NULL)
|
||||
*pkeygen = meth->keygen;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_get_compute_key(EC_KEY_METHOD *meth,
|
||||
int (**pck)(unsigned char **pout,
|
||||
size_t *poutlen,
|
||||
const EC_POINT *pub_key,
|
||||
const EC_KEY *ecdh))
|
||||
{
|
||||
if (pck != NULL)
|
||||
*pck = meth->compute_key;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_get_sign(EC_KEY_METHOD *meth,
|
||||
int (**psign)(int type, const unsigned char *dgst,
|
||||
int dlen, unsigned char *sig,
|
||||
unsigned int *siglen,
|
||||
const BIGNUM *kinv, const BIGNUM *r,
|
||||
EC_KEY *eckey),
|
||||
int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
|
||||
BIGNUM **kinvp, BIGNUM **rp),
|
||||
ECDSA_SIG *(**psign_sig)(const unsigned char *dgst,
|
||||
int dgst_len,
|
||||
const BIGNUM *in_kinv,
|
||||
const BIGNUM *in_r,
|
||||
EC_KEY *eckey))
|
||||
{
|
||||
if (psign != NULL)
|
||||
*psign = meth->sign;
|
||||
if (psign_setup != NULL)
|
||||
*psign_setup = meth->sign_setup;
|
||||
if (psign_sig != NULL)
|
||||
*psign_sig = meth->sign_sig;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_get_verify(EC_KEY_METHOD *meth,
|
||||
int (**pverify)(int type, const unsigned
|
||||
char *dgst, int dgst_len,
|
||||
const unsigned char *sigbuf,
|
||||
int sig_len, EC_KEY *eckey),
|
||||
int (**pverify_sig)(const unsigned char *dgst,
|
||||
int dgst_len,
|
||||
const ECDSA_SIG *sig,
|
||||
EC_KEY *eckey))
|
||||
{
|
||||
if (pverify != NULL)
|
||||
*pverify = meth->verify;
|
||||
if (pverify_sig != NULL)
|
||||
*pverify_sig = meth->verify_sig;
|
||||
}
|
||||
@@ -1,60 +1,12 @@
|
||||
/* crypto/ec/ec_lcl.h */
|
||||
/*
|
||||
* Originally written by Bodo Moeller for the OpenSSL project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2010 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright 2001-2016 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
*
|
||||
@@ -75,6 +27,8 @@
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include "e_os.h"
|
||||
|
||||
#if defined(__SUNPRO_C)
|
||||
# if __SUNPRO_C >= 0x520
|
||||
# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
|
||||
@@ -84,6 +38,12 @@
|
||||
/* Use default functions for poin2oct, oct2point and compressed coordinates */
|
||||
#define EC_FLAGS_DEFAULT_OCT 0x1
|
||||
|
||||
/* Use custom formats for EC_GROUP, EC_POINT and EC_KEY */
|
||||
#define EC_FLAGS_CUSTOM_CURVE 0x2
|
||||
|
||||
/* Curve does not support signing operations */
|
||||
#define EC_FLAGS_NO_SIGN 0x4
|
||||
|
||||
/*
|
||||
* Structure details are not part of the exported interface, so all this may
|
||||
* change in future versions.
|
||||
@@ -110,6 +70,7 @@ struct ec_method_st {
|
||||
BN_CTX *);
|
||||
/* used by EC_GROUP_get_degree: */
|
||||
int (*group_get_degree) (const EC_GROUP *);
|
||||
int (*group_order_bits) (const EC_GROUP *);
|
||||
/* used by EC_GROUP_check: */
|
||||
int (*group_check_discriminant) (const EC_GROUP *, BN_CTX *);
|
||||
/*
|
||||
@@ -196,34 +157,39 @@ struct ec_method_st {
|
||||
int (*field_decode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
BN_CTX *);
|
||||
int (*field_set_to_one) (const EC_GROUP *, BIGNUM *r, BN_CTX *);
|
||||
} /* EC_METHOD */ ;
|
||||
/* private key operations */
|
||||
size_t (*priv2oct)(const EC_KEY *eckey, unsigned char *buf, size_t len);
|
||||
int (*oct2priv)(EC_KEY *eckey, const unsigned char *buf, size_t len);
|
||||
int (*set_private)(EC_KEY *eckey, const BIGNUM *priv_key);
|
||||
int (*keygen)(EC_KEY *eckey);
|
||||
int (*keycheck)(const EC_KEY *eckey);
|
||||
int (*keygenpub)(EC_KEY *eckey);
|
||||
int (*keycopy)(EC_KEY *dst, const EC_KEY *src);
|
||||
void (*keyfinish)(EC_KEY *eckey);
|
||||
/* custom ECDH operation */
|
||||
int (*ecdh_compute_key)(unsigned char **pout, size_t *poutlen,
|
||||
const EC_POINT *pub_key, const EC_KEY *ecdh);
|
||||
};
|
||||
|
||||
typedef struct ec_extra_data_st {
|
||||
struct ec_extra_data_st *next;
|
||||
void *data;
|
||||
void *(*dup_func) (void *);
|
||||
void (*free_func) (void *);
|
||||
void (*clear_free_func) (void *);
|
||||
} EC_EXTRA_DATA; /* used in EC_GROUP */
|
||||
/*
|
||||
* Types and functions to manipulate pre-computed values.
|
||||
*/
|
||||
typedef struct nistp224_pre_comp_st NISTP224_PRE_COMP;
|
||||
typedef struct nistp256_pre_comp_st NISTP256_PRE_COMP;
|
||||
typedef struct nistp521_pre_comp_st NISTP521_PRE_COMP;
|
||||
typedef struct nistz256_pre_comp_st NISTZ256_PRE_COMP;
|
||||
typedef struct ec_pre_comp_st EC_PRE_COMP;
|
||||
|
||||
struct ec_group_st {
|
||||
const EC_METHOD *meth;
|
||||
EC_POINT *generator; /* optional */
|
||||
BIGNUM order, cofactor;
|
||||
BIGNUM *order, *cofactor;
|
||||
int curve_name; /* optional NID for named curve */
|
||||
int asn1_flag; /* flag to control the asn1 encoding */
|
||||
/*
|
||||
* Kludge: upper bit of ans1_flag is used to denote structure
|
||||
* version. Is set, then last field is present. This is done
|
||||
* for interoperation with FIPS code.
|
||||
*/
|
||||
#define EC_GROUP_ASN1_FLAG_MASK 0x7fffffff
|
||||
#define EC_GROUP_VERSION(p) (p->asn1_flag&~EC_GROUP_ASN1_FLAG_MASK)
|
||||
point_conversion_form_t asn1_form;
|
||||
unsigned char *seed; /* optional seed for parameters (appears in
|
||||
* ASN1) */
|
||||
size_t seed_len;
|
||||
EC_EXTRA_DATA *extra_data; /* linked list */
|
||||
/*
|
||||
* The following members are handled by the method functions, even if
|
||||
* they appear generic
|
||||
@@ -233,7 +199,7 @@ struct ec_group_st {
|
||||
* curves over GF(2^m), this is the irreducible polynomial defining the
|
||||
* field.
|
||||
*/
|
||||
BIGNUM field;
|
||||
BIGNUM *field;
|
||||
/*
|
||||
* Field specification for curves over GF(2^m). The irreducible f(t) is
|
||||
* then of the form: t^poly[0] + t^poly[1] + ... + t^poly[k] where m =
|
||||
@@ -249,7 +215,7 @@ struct ec_group_st {
|
||||
* x^3 + a*x + b. For characteristic 2, the curve is defined by an
|
||||
* equation of the form y^2 + x*y = x^3 + a*x^2 + b.
|
||||
*/
|
||||
BIGNUM a, b;
|
||||
BIGNUM *a, *b;
|
||||
/* enable optimized point arithmetics for special case */
|
||||
int a_is_minus3;
|
||||
/* method-specific (e.g., Montgomery structure) */
|
||||
@@ -259,10 +225,36 @@ struct ec_group_st {
|
||||
/* method-specific */
|
||||
int (*field_mod_func) (BIGNUM *, const BIGNUM *, const BIGNUM *,
|
||||
BN_CTX *);
|
||||
BN_MONT_CTX *mont_data; /* data for ECDSA inverse */
|
||||
} /* EC_GROUP */ ;
|
||||
/* data for ECDSA inverse */
|
||||
BN_MONT_CTX *mont_data;
|
||||
|
||||
/*
|
||||
* Precomputed values for speed. The PCT_xxx names match the
|
||||
* pre_comp.xxx union names; see the SETPRECOMP and HAVEPRECOMP
|
||||
* macros, below.
|
||||
*/
|
||||
enum {
|
||||
PCT_none,
|
||||
PCT_nistp224, PCT_nistp256, PCT_nistp521, PCT_nistz256,
|
||||
PCT_ec
|
||||
} pre_comp_type;
|
||||
union {
|
||||
NISTP224_PRE_COMP *nistp224;
|
||||
NISTP256_PRE_COMP *nistp256;
|
||||
NISTP521_PRE_COMP *nistp521;
|
||||
NISTZ256_PRE_COMP *nistz256;
|
||||
EC_PRE_COMP *ec;
|
||||
} pre_comp;
|
||||
};
|
||||
|
||||
#define SETPRECOMP(g, type, pre) \
|
||||
g->pre_comp_type = PCT_##type, g->pre_comp.type = pre
|
||||
#define HAVEPRECOMP(g, type) \
|
||||
g->pre_comp_type == PCT_##type && g->pre_comp.type != NULL
|
||||
|
||||
struct ec_key_st {
|
||||
const EC_KEY_METHOD *meth;
|
||||
ENGINE *engine;
|
||||
int version;
|
||||
EC_GROUP *group;
|
||||
EC_POINT *pub_key;
|
||||
@@ -271,30 +263,9 @@ struct ec_key_st {
|
||||
point_conversion_form_t conv_form;
|
||||
int references;
|
||||
int flags;
|
||||
EC_EXTRA_DATA *method_data;
|
||||
} /* EC_KEY */ ;
|
||||
|
||||
/*
|
||||
* Basically a 'mixin' for extra data, but available for EC_GROUPs/EC_KEYs
|
||||
* only (with visibility limited to 'package' level for now). We use the
|
||||
* function pointers as index for retrieval; this obviates global
|
||||
* ex_data-style index tables.
|
||||
*/
|
||||
int EC_EX_DATA_set_data(EC_EXTRA_DATA **, void *data,
|
||||
void *(*dup_func) (void *),
|
||||
void (*free_func) (void *),
|
||||
void (*clear_free_func) (void *));
|
||||
void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *, void *(*dup_func) (void *),
|
||||
void (*free_func) (void *),
|
||||
void (*clear_free_func) (void *));
|
||||
void EC_EX_DATA_free_data(EC_EXTRA_DATA **, void *(*dup_func) (void *),
|
||||
void (*free_func) (void *),
|
||||
void (*clear_free_func) (void *));
|
||||
void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **, void *(*dup_func) (void *),
|
||||
void (*free_func) (void *),
|
||||
void (*clear_free_func) (void *));
|
||||
void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **);
|
||||
void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **);
|
||||
CRYPTO_EX_DATA ex_data;
|
||||
CRYPTO_RWLOCK *lock;
|
||||
};
|
||||
|
||||
struct ec_point_st {
|
||||
const EC_METHOD *meth;
|
||||
@@ -302,13 +273,27 @@ struct ec_point_st {
|
||||
* All members except 'meth' are handled by the method functions, even if
|
||||
* they appear generic
|
||||
*/
|
||||
BIGNUM X;
|
||||
BIGNUM Y;
|
||||
BIGNUM Z; /* Jacobian projective coordinates: (X, Y, Z)
|
||||
* represents (X/Z^2, Y/Z^3) if Z != 0 */
|
||||
BIGNUM *X;
|
||||
BIGNUM *Y;
|
||||
BIGNUM *Z; /* Jacobian projective coordinates: * (X, Y,
|
||||
* Z) represents (X/Z^2, Y/Z^3) if Z != 0 */
|
||||
int Z_is_one; /* enable optimized point arithmetics for
|
||||
* special case */
|
||||
} /* EC_POINT */ ;
|
||||
};
|
||||
|
||||
NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *);
|
||||
NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *);
|
||||
NISTP521_PRE_COMP *EC_nistp521_pre_comp_dup(NISTP521_PRE_COMP *);
|
||||
NISTZ256_PRE_COMP *EC_nistz256_pre_comp_dup(NISTZ256_PRE_COMP *);
|
||||
NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *);
|
||||
EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_COMP *);
|
||||
|
||||
void EC_pre_comp_free(EC_GROUP *group);
|
||||
void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *);
|
||||
void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *);
|
||||
void EC_nistp521_pre_comp_free(NISTP521_PRE_COMP *);
|
||||
void EC_nistz256_pre_comp_free(NISTZ256_PRE_COMP *);
|
||||
void EC_ec_pre_comp_free(EC_PRE_COMP *);
|
||||
|
||||
/*
|
||||
* method functions in ec_mult.c (ec_lib.c uses these as defaults if
|
||||
@@ -550,6 +535,7 @@ void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
|
||||
unsigned char *digit, unsigned char in);
|
||||
#endif
|
||||
int ec_precompute_mont_data(EC_GROUP *);
|
||||
int ec_group_simple_order_bits(const EC_GROUP *group);
|
||||
|
||||
#ifdef ECP_NISTZ256_ASM
|
||||
/** Returns GFp methods using montgomery multiplication, with x86-64 optimized
|
||||
@@ -559,10 +545,69 @@ int ec_precompute_mont_data(EC_GROUP *);
|
||||
const EC_METHOD *EC_GFp_nistz256_method(void);
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
EC_GROUP *FIPS_ec_group_new_curve_gfp(const BIGNUM *p, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *ctx);
|
||||
EC_GROUP *FIPS_ec_group_new_curve_gf2m(const BIGNUM *p, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *ctx);
|
||||
EC_GROUP *FIPS_ec_group_new_by_curve_name(int nid);
|
||||
#endif
|
||||
size_t ec_key_simple_priv2oct(const EC_KEY *eckey,
|
||||
unsigned char *buf, size_t len);
|
||||
int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len);
|
||||
int ec_key_simple_generate_key(EC_KEY *eckey);
|
||||
int ec_key_simple_generate_public_key(EC_KEY *eckey);
|
||||
int ec_key_simple_check_key(const EC_KEY *eckey);
|
||||
|
||||
/* EC_METHOD definitions */
|
||||
|
||||
struct ec_key_method_st {
|
||||
const char *name;
|
||||
int32_t flags;
|
||||
int (*init)(EC_KEY *key);
|
||||
void (*finish)(EC_KEY *key);
|
||||
int (*copy)(EC_KEY *dest, const EC_KEY *src);
|
||||
int (*set_group)(EC_KEY *key, const EC_GROUP *grp);
|
||||
int (*set_private)(EC_KEY *key, const BIGNUM *priv_key);
|
||||
int (*set_public)(EC_KEY *key, const EC_POINT *pub_key);
|
||||
int (*keygen)(EC_KEY *key);
|
||||
int (*compute_key)(unsigned char **pout, size_t *poutlen,
|
||||
const EC_POINT *pub_key, const EC_KEY *ecdh);
|
||||
int (*sign)(int type, const unsigned char *dgst, int dlen, unsigned char
|
||||
*sig, unsigned int *siglen, const BIGNUM *kinv,
|
||||
const BIGNUM *r, EC_KEY *eckey);
|
||||
int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
|
||||
BIGNUM **rp);
|
||||
ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, int dgst_len,
|
||||
const BIGNUM *in_kinv, const BIGNUM *in_r,
|
||||
EC_KEY *eckey);
|
||||
|
||||
int (*verify)(int type, const unsigned char *dgst, int dgst_len,
|
||||
const unsigned char *sigbuf, int sig_len, EC_KEY *eckey);
|
||||
int (*verify_sig)(const unsigned char *dgst, int dgst_len,
|
||||
const ECDSA_SIG *sig, EC_KEY *eckey);
|
||||
};
|
||||
|
||||
#define EC_KEY_METHOD_DYNAMIC 1
|
||||
|
||||
int ossl_ec_key_gen(EC_KEY *eckey);
|
||||
int ossl_ecdh_compute_key(unsigned char **pout, size_t *poutlen,
|
||||
const EC_POINT *pub_key, const EC_KEY *ecdh);
|
||||
int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
|
||||
const EC_POINT *pub_key, const EC_KEY *ecdh);
|
||||
|
||||
struct ECDSA_SIG_st {
|
||||
BIGNUM *r;
|
||||
BIGNUM *s;
|
||||
};
|
||||
|
||||
int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
|
||||
BIGNUM **rp);
|
||||
int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen,
|
||||
unsigned char *sig, unsigned int *siglen,
|
||||
const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey);
|
||||
ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
|
||||
const BIGNUM *in_kinv, const BIGNUM *in_r,
|
||||
EC_KEY *eckey);
|
||||
int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
|
||||
const unsigned char *sigbuf, int sig_len, EC_KEY *eckey);
|
||||
int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
|
||||
const ECDSA_SIG *sig, EC_KEY *eckey);
|
||||
|
||||
int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
|
||||
const uint8_t peer_public_value[32]);
|
||||
void X25519_public_from_private(uint8_t out_public_value[32],
|
||||
const uint8_t private_key[32]);
|
||||
|
||||
@@ -1,60 +1,12 @@
|
||||
/* crypto/ec/ec_lib.c */
|
||||
/*
|
||||
* Originally written by Bodo Moeller for the OpenSSL project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright 2001-2016 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* Binary polynomial ECC support in OpenSSL originally developed by
|
||||
@@ -68,8 +20,6 @@
|
||||
|
||||
#include "ec_lcl.h"
|
||||
|
||||
const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT;
|
||||
|
||||
/* functions for EC_GROUP objects */
|
||||
|
||||
EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
|
||||
@@ -85,34 +35,60 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = OPENSSL_malloc(sizeof *ret);
|
||||
ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
if (ret == NULL) {
|
||||
ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->meth = meth;
|
||||
|
||||
ret->extra_data = NULL;
|
||||
ret->mont_data = NULL;
|
||||
|
||||
ret->generator = NULL;
|
||||
BN_init(&ret->order);
|
||||
BN_init(&ret->cofactor);
|
||||
|
||||
ret->curve_name = 0;
|
||||
ret->asn1_flag = ~EC_GROUP_ASN1_FLAG_MASK;
|
||||
ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
|
||||
|
||||
ret->seed = NULL;
|
||||
ret->seed_len = 0;
|
||||
|
||||
if (!meth->group_init(ret)) {
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
if ((ret->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) {
|
||||
ret->order = BN_new();
|
||||
if (ret->order == NULL)
|
||||
goto err;
|
||||
ret->cofactor = BN_new();
|
||||
if (ret->cofactor == NULL)
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret->asn1_flag = OPENSSL_EC_NAMED_CURVE;
|
||||
ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
|
||||
if (!meth->group_init(ret))
|
||||
goto err;
|
||||
return ret;
|
||||
|
||||
err:
|
||||
BN_free(ret->order);
|
||||
BN_free(ret->cofactor);
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void EC_pre_comp_free(EC_GROUP *group)
|
||||
{
|
||||
switch (group->pre_comp_type) {
|
||||
default:
|
||||
break;
|
||||
#ifdef ECP_NISTZ256_REFERENCE_IMPLEMENTATION
|
||||
case PCT_nistz256:
|
||||
EC_nistz256_pre_comp_free(group->pre_comp.nistz256);
|
||||
break;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
case PCT_nistp224:
|
||||
EC_nistp224_pre_comp_free(group->pre_comp.nistp224);
|
||||
break;
|
||||
case PCT_nistp256:
|
||||
EC_nistp256_pre_comp_free(group->pre_comp.nistp256);
|
||||
break;
|
||||
case PCT_nistp521:
|
||||
EC_nistp521_pre_comp_free(group->pre_comp.nistp521);
|
||||
break;
|
||||
#endif
|
||||
case PCT_ec:
|
||||
EC_ec_pre_comp_free(group->pre_comp.ec);
|
||||
break;
|
||||
}
|
||||
group->pre_comp.ec = NULL;
|
||||
}
|
||||
|
||||
void EC_GROUP_free(EC_GROUP *group)
|
||||
@@ -123,19 +99,12 @@ void EC_GROUP_free(EC_GROUP *group)
|
||||
if (group->meth->group_finish != 0)
|
||||
group->meth->group_finish(group);
|
||||
|
||||
EC_EX_DATA_free_all_data(&group->extra_data);
|
||||
|
||||
if (EC_GROUP_VERSION(group) && group->mont_data)
|
||||
BN_MONT_CTX_free(group->mont_data);
|
||||
|
||||
if (group->generator != NULL)
|
||||
EC_POINT_free(group->generator);
|
||||
BN_free(&group->order);
|
||||
BN_free(&group->cofactor);
|
||||
|
||||
if (group->seed)
|
||||
OPENSSL_free(group->seed);
|
||||
|
||||
EC_pre_comp_free(group);
|
||||
BN_MONT_CTX_free(group->mont_data);
|
||||
EC_POINT_free(group->generator);
|
||||
BN_free(group->order);
|
||||
BN_free(group->cofactor);
|
||||
OPENSSL_free(group->seed);
|
||||
OPENSSL_free(group);
|
||||
}
|
||||
|
||||
@@ -149,29 +118,17 @@ void EC_GROUP_clear_free(EC_GROUP *group)
|
||||
else if (group->meth->group_finish != 0)
|
||||
group->meth->group_finish(group);
|
||||
|
||||
EC_EX_DATA_clear_free_all_data(&group->extra_data);
|
||||
|
||||
if (EC_GROUP_VERSION(group) && group->mont_data)
|
||||
BN_MONT_CTX_free(group->mont_data);
|
||||
|
||||
if (group->generator != NULL)
|
||||
EC_POINT_clear_free(group->generator);
|
||||
BN_clear_free(&group->order);
|
||||
BN_clear_free(&group->cofactor);
|
||||
|
||||
if (group->seed) {
|
||||
OPENSSL_cleanse(group->seed, group->seed_len);
|
||||
OPENSSL_free(group->seed);
|
||||
}
|
||||
|
||||
OPENSSL_cleanse(group, sizeof *group);
|
||||
OPENSSL_free(group);
|
||||
EC_pre_comp_free(group);
|
||||
BN_MONT_CTX_free(group->mont_data);
|
||||
EC_POINT_clear_free(group->generator);
|
||||
BN_clear_free(group->order);
|
||||
BN_clear_free(group->cofactor);
|
||||
OPENSSL_clear_free(group->seed, group->seed_len);
|
||||
OPENSSL_clear_free(group, sizeof(*group));
|
||||
}
|
||||
|
||||
int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
|
||||
{
|
||||
EC_EXTRA_DATA *d;
|
||||
|
||||
if (dest->meth->group_copy == 0) {
|
||||
ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
@@ -183,20 +140,34 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
|
||||
if (dest == src)
|
||||
return 1;
|
||||
|
||||
EC_EX_DATA_free_all_data(&dest->extra_data);
|
||||
|
||||
for (d = src->extra_data; d != NULL; d = d->next) {
|
||||
void *t = d->dup_func(d->data);
|
||||
|
||||
if (t == NULL)
|
||||
return 0;
|
||||
if (!EC_EX_DATA_set_data
|
||||
(&dest->extra_data, t, d->dup_func, d->free_func,
|
||||
d->clear_free_func))
|
||||
return 0;
|
||||
/* Copy precomputed */
|
||||
dest->pre_comp_type = src->pre_comp_type;
|
||||
switch (src->pre_comp_type) {
|
||||
default:
|
||||
dest->pre_comp.ec = NULL;
|
||||
break;
|
||||
#ifdef ECP_NISTZ256_REFERENCE_IMPLEMENTATION
|
||||
case PCT_nistz256:
|
||||
dest->pre_comp.nistz256 = EC_nistz256_pre_comp_dup(src->pre_comp.nistz256);
|
||||
break;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
case PCT_nistp224:
|
||||
dest->pre_comp.nistp224 = EC_nistp224_pre_comp_dup(src->pre_comp.nistp224);
|
||||
break;
|
||||
case PCT_nistp256:
|
||||
dest->pre_comp.nistp256 = EC_nistp256_pre_comp_dup(src->pre_comp.nistp256);
|
||||
break;
|
||||
case PCT_nistp521:
|
||||
dest->pre_comp.nistp521 = EC_nistp521_pre_comp_dup(src->pre_comp.nistp521);
|
||||
break;
|
||||
#endif
|
||||
case PCT_ec:
|
||||
dest->pre_comp.ec = EC_ec_pre_comp_dup(src->pre_comp.ec);
|
||||
break;
|
||||
}
|
||||
|
||||
if (EC_GROUP_VERSION(src) && src->mont_data != NULL) {
|
||||
if (src->mont_data != NULL) {
|
||||
if (dest->mont_data == NULL) {
|
||||
dest->mont_data = BN_MONT_CTX_new();
|
||||
if (dest->mont_data == NULL)
|
||||
@@ -206,10 +177,8 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
|
||||
return 0;
|
||||
} else {
|
||||
/* src->generator == NULL */
|
||||
if (EC_GROUP_VERSION(dest) && dest->mont_data != NULL) {
|
||||
BN_MONT_CTX_free(dest->mont_data);
|
||||
dest->mont_data = NULL;
|
||||
}
|
||||
BN_MONT_CTX_free(dest->mont_data);
|
||||
dest->mont_data = NULL;
|
||||
}
|
||||
|
||||
if (src->generator != NULL) {
|
||||
@@ -222,24 +191,23 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
|
||||
return 0;
|
||||
} else {
|
||||
/* src->generator == NULL */
|
||||
if (dest->generator != NULL) {
|
||||
EC_POINT_clear_free(dest->generator);
|
||||
dest->generator = NULL;
|
||||
}
|
||||
EC_POINT_clear_free(dest->generator);
|
||||
dest->generator = NULL;
|
||||
}
|
||||
|
||||
if (!BN_copy(&dest->order, &src->order))
|
||||
return 0;
|
||||
if (!BN_copy(&dest->cofactor, &src->cofactor))
|
||||
return 0;
|
||||
if ((src->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) {
|
||||
if (!BN_copy(dest->order, src->order))
|
||||
return 0;
|
||||
if (!BN_copy(dest->cofactor, src->cofactor))
|
||||
return 0;
|
||||
}
|
||||
|
||||
dest->curve_name = src->curve_name;
|
||||
dest->asn1_flag = src->asn1_flag;
|
||||
dest->asn1_form = src->asn1_form;
|
||||
|
||||
if (src->seed) {
|
||||
if (dest->seed)
|
||||
OPENSSL_free(dest->seed);
|
||||
OPENSSL_free(dest->seed);
|
||||
dest->seed = OPENSSL_malloc(src->seed_len);
|
||||
if (dest->seed == NULL)
|
||||
return 0;
|
||||
@@ -247,8 +215,7 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
|
||||
return 0;
|
||||
dest->seed_len = src->seed_len;
|
||||
} else {
|
||||
if (dest->seed)
|
||||
OPENSSL_free(dest->seed);
|
||||
OPENSSL_free(dest->seed);
|
||||
dest->seed = NULL;
|
||||
dest->seed_len = 0;
|
||||
}
|
||||
@@ -273,10 +240,9 @@ EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
|
||||
|
||||
err:
|
||||
if (!ok) {
|
||||
if (t)
|
||||
EC_GROUP_free(t);
|
||||
EC_GROUP_free(t);
|
||||
return NULL;
|
||||
} else
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -307,24 +273,28 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
|
||||
return 0;
|
||||
|
||||
if (order != NULL) {
|
||||
if (!BN_copy(&group->order, order))
|
||||
if (!BN_copy(group->order, order))
|
||||
return 0;
|
||||
} else
|
||||
BN_zero(&group->order);
|
||||
BN_zero(group->order);
|
||||
|
||||
if (cofactor != NULL) {
|
||||
if (!BN_copy(&group->cofactor, cofactor))
|
||||
if (!BN_copy(group->cofactor, cofactor))
|
||||
return 0;
|
||||
} else
|
||||
BN_zero(&group->cofactor);
|
||||
BN_zero(group->cofactor);
|
||||
|
||||
/*
|
||||
* We ignore the return value because some groups have an order with
|
||||
* Some groups have an order with
|
||||
* factors of two, which makes the Montgomery setup fail.
|
||||
* |group->mont_data| will be NULL in this case.
|
||||
*/
|
||||
ec_precompute_mont_data(group);
|
||||
if (BN_is_odd(group->order)) {
|
||||
return ec_precompute_mont_data(group);
|
||||
}
|
||||
|
||||
BN_MONT_CTX_free(group->mont_data);
|
||||
group->mont_data = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -335,24 +305,45 @@ const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
|
||||
|
||||
BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group)
|
||||
{
|
||||
return EC_GROUP_VERSION(group) ? group->mont_data : NULL;
|
||||
return group->mont_data;
|
||||
}
|
||||
|
||||
int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
|
||||
{
|
||||
if (!BN_copy(order, &group->order))
|
||||
if (group->order == NULL)
|
||||
return 0;
|
||||
if (!BN_copy(order, group->order))
|
||||
return 0;
|
||||
|
||||
return !BN_is_zero(order);
|
||||
}
|
||||
|
||||
const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group)
|
||||
{
|
||||
return group->order;
|
||||
}
|
||||
|
||||
int EC_GROUP_order_bits(const EC_GROUP *group)
|
||||
{
|
||||
OPENSSL_assert(group->meth->group_order_bits != NULL);
|
||||
return group->meth->group_order_bits(group);
|
||||
}
|
||||
|
||||
int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
if (!BN_copy(cofactor, &group->cofactor))
|
||||
|
||||
if (group->cofactor == NULL)
|
||||
return 0;
|
||||
if (!BN_copy(cofactor, group->cofactor))
|
||||
return 0;
|
||||
|
||||
return !BN_is_zero(&group->cofactor);
|
||||
return !BN_is_zero(group->cofactor);
|
||||
}
|
||||
|
||||
const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group)
|
||||
{
|
||||
return group->cofactor;
|
||||
}
|
||||
|
||||
void EC_GROUP_set_curve_name(EC_GROUP *group, int nid)
|
||||
@@ -367,13 +358,12 @@ int EC_GROUP_get_curve_name(const EC_GROUP *group)
|
||||
|
||||
void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
|
||||
{
|
||||
group->asn1_flag &= ~EC_GROUP_ASN1_FLAG_MASK;
|
||||
group->asn1_flag |= flag & EC_GROUP_ASN1_FLAG_MASK;
|
||||
group->asn1_flag = flag;
|
||||
}
|
||||
|
||||
int EC_GROUP_get_asn1_flag(const EC_GROUP *group)
|
||||
{
|
||||
return group->asn1_flag & EC_GROUP_ASN1_FLAG_MASK;
|
||||
return group->asn1_flag;
|
||||
}
|
||||
|
||||
void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
|
||||
@@ -390,11 +380,9 @@ point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP
|
||||
|
||||
size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
|
||||
{
|
||||
if (group->seed) {
|
||||
OPENSSL_free(group->seed);
|
||||
group->seed = NULL;
|
||||
group->seed_len = 0;
|
||||
}
|
||||
OPENSSL_free(group->seed);
|
||||
group->seed = NULL;
|
||||
group->seed_len = 0;
|
||||
|
||||
if (!len || !p)
|
||||
return 1;
|
||||
@@ -494,10 +482,12 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
|
||||
if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
|
||||
EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
|
||||
return 1;
|
||||
if (a->meth->flags & EC_FLAGS_CUSTOM_CURVE)
|
||||
return 0;
|
||||
|
||||
if (!ctx)
|
||||
if (ctx == NULL)
|
||||
ctx_new = ctx = BN_CTX_new();
|
||||
if (!ctx)
|
||||
if (ctx == NULL)
|
||||
return -1;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
@@ -507,10 +497,9 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
|
||||
b1 = BN_CTX_get(ctx);
|
||||
b2 = BN_CTX_get(ctx);
|
||||
b3 = BN_CTX_get(ctx);
|
||||
if (!b3) {
|
||||
if (b3 == NULL) {
|
||||
BN_CTX_end(ctx);
|
||||
if (ctx_new)
|
||||
BN_CTX_free(ctx);
|
||||
BN_CTX_free(ctx_new);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -531,172 +520,27 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
|
||||
r = 1;
|
||||
|
||||
if (!r) {
|
||||
const BIGNUM *ao, *bo, *ac, *bc;
|
||||
/* compare the order and cofactor */
|
||||
if (!EC_GROUP_get_order(a, a1, ctx) ||
|
||||
!EC_GROUP_get_order(b, b1, ctx) ||
|
||||
!EC_GROUP_get_cofactor(a, a2, ctx) ||
|
||||
!EC_GROUP_get_cofactor(b, b2, ctx)) {
|
||||
ao = EC_GROUP_get0_order(a);
|
||||
bo = EC_GROUP_get0_order(b);
|
||||
ac = EC_GROUP_get0_cofactor(a);
|
||||
bc = EC_GROUP_get0_cofactor(b);
|
||||
if (ao == NULL || bo == NULL) {
|
||||
BN_CTX_end(ctx);
|
||||
if (ctx_new)
|
||||
BN_CTX_free(ctx);
|
||||
BN_CTX_free(ctx_new);
|
||||
return -1;
|
||||
}
|
||||
if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
|
||||
if (BN_cmp(ao, bo) || BN_cmp(ac, bc))
|
||||
r = 1;
|
||||
}
|
||||
|
||||
BN_CTX_end(ctx);
|
||||
if (ctx_new)
|
||||
BN_CTX_free(ctx);
|
||||
BN_CTX_free(ctx_new);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* this has 'package' visibility */
|
||||
int EC_EX_DATA_set_data(EC_EXTRA_DATA **ex_data, void *data,
|
||||
void *(*dup_func) (void *),
|
||||
void (*free_func) (void *),
|
||||
void (*clear_free_func) (void *))
|
||||
{
|
||||
EC_EXTRA_DATA *d;
|
||||
|
||||
if (ex_data == NULL)
|
||||
return 0;
|
||||
|
||||
for (d = *ex_data; d != NULL; d = d->next) {
|
||||
if (d->dup_func == dup_func && d->free_func == free_func
|
||||
&& d->clear_free_func == clear_free_func) {
|
||||
ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (data == NULL)
|
||||
/* no explicit entry needed */
|
||||
return 1;
|
||||
|
||||
d = OPENSSL_malloc(sizeof *d);
|
||||
if (d == NULL)
|
||||
return 0;
|
||||
|
||||
d->data = data;
|
||||
d->dup_func = dup_func;
|
||||
d->free_func = free_func;
|
||||
d->clear_free_func = clear_free_func;
|
||||
|
||||
d->next = *ex_data;
|
||||
*ex_data = d;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* this has 'package' visibility */
|
||||
void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *ex_data,
|
||||
void *(*dup_func) (void *),
|
||||
void (*free_func) (void *),
|
||||
void (*clear_free_func) (void *))
|
||||
{
|
||||
const EC_EXTRA_DATA *d;
|
||||
|
||||
for (d = ex_data; d != NULL; d = d->next) {
|
||||
if (d->dup_func == dup_func && d->free_func == free_func
|
||||
&& d->clear_free_func == clear_free_func)
|
||||
return d->data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* this has 'package' visibility */
|
||||
void EC_EX_DATA_free_data(EC_EXTRA_DATA **ex_data,
|
||||
void *(*dup_func) (void *),
|
||||
void (*free_func) (void *),
|
||||
void (*clear_free_func) (void *))
|
||||
{
|
||||
EC_EXTRA_DATA **p;
|
||||
|
||||
if (ex_data == NULL)
|
||||
return;
|
||||
|
||||
for (p = ex_data; *p != NULL; p = &((*p)->next)) {
|
||||
if ((*p)->dup_func == dup_func && (*p)->free_func == free_func
|
||||
&& (*p)->clear_free_func == clear_free_func) {
|
||||
EC_EXTRA_DATA *next = (*p)->next;
|
||||
|
||||
(*p)->free_func((*p)->data);
|
||||
OPENSSL_free(*p);
|
||||
|
||||
*p = next;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* this has 'package' visibility */
|
||||
void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **ex_data,
|
||||
void *(*dup_func) (void *),
|
||||
void (*free_func) (void *),
|
||||
void (*clear_free_func) (void *))
|
||||
{
|
||||
EC_EXTRA_DATA **p;
|
||||
|
||||
if (ex_data == NULL)
|
||||
return;
|
||||
|
||||
for (p = ex_data; *p != NULL; p = &((*p)->next)) {
|
||||
if ((*p)->dup_func == dup_func && (*p)->free_func == free_func
|
||||
&& (*p)->clear_free_func == clear_free_func) {
|
||||
EC_EXTRA_DATA *next = (*p)->next;
|
||||
|
||||
(*p)->clear_free_func((*p)->data);
|
||||
OPENSSL_free(*p);
|
||||
|
||||
*p = next;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* this has 'package' visibility */
|
||||
void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **ex_data)
|
||||
{
|
||||
EC_EXTRA_DATA *d;
|
||||
|
||||
if (ex_data == NULL)
|
||||
return;
|
||||
|
||||
d = *ex_data;
|
||||
while (d) {
|
||||
EC_EXTRA_DATA *next = d->next;
|
||||
|
||||
d->free_func(d->data);
|
||||
OPENSSL_free(d);
|
||||
|
||||
d = next;
|
||||
}
|
||||
*ex_data = NULL;
|
||||
}
|
||||
|
||||
/* this has 'package' visibility */
|
||||
void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **ex_data)
|
||||
{
|
||||
EC_EXTRA_DATA *d;
|
||||
|
||||
if (ex_data == NULL)
|
||||
return;
|
||||
|
||||
d = *ex_data;
|
||||
while (d) {
|
||||
EC_EXTRA_DATA *next = d->next;
|
||||
|
||||
d->clear_free_func(d->data);
|
||||
OPENSSL_free(d);
|
||||
|
||||
d = next;
|
||||
}
|
||||
*ex_data = NULL;
|
||||
}
|
||||
|
||||
/* functions for EC_POINT objects */
|
||||
|
||||
EC_POINT *EC_POINT_new(const EC_GROUP *group)
|
||||
@@ -712,7 +556,7 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = OPENSSL_malloc(sizeof *ret);
|
||||
ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
if (ret == NULL) {
|
||||
ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
@@ -747,8 +591,7 @@ void EC_POINT_clear_free(EC_POINT *point)
|
||||
point->meth->point_clear_finish(point);
|
||||
else if (point->meth->point_finish != 0)
|
||||
point->meth->point_finish(point);
|
||||
OPENSSL_cleanse(point, sizeof *point);
|
||||
OPENSSL_free(point);
|
||||
OPENSSL_clear_free(point, sizeof(*point));
|
||||
}
|
||||
|
||||
int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
|
||||
@@ -781,8 +624,8 @@ EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
|
||||
if (!r) {
|
||||
EC_POINT_free(t);
|
||||
return NULL;
|
||||
} else
|
||||
return t;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
|
||||
@@ -856,7 +699,15 @@ int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group,
|
||||
EC_R_INCOMPATIBLE_OBJECTS);
|
||||
return 0;
|
||||
}
|
||||
return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
|
||||
if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
|
||||
return 0;
|
||||
|
||||
if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
|
||||
ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
|
||||
EC_R_POINT_IS_NOT_ON_CURVE);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
@@ -874,7 +725,15 @@ int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group,
|
||||
EC_R_INCOMPATIBLE_OBJECTS);
|
||||
return 0;
|
||||
}
|
||||
return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
|
||||
if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
|
||||
return 0;
|
||||
|
||||
if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
|
||||
ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
|
||||
EC_R_POINT_IS_NOT_ON_CURVE);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1103,22 +962,17 @@ int ec_precompute_mont_data(EC_GROUP *group)
|
||||
BN_CTX *ctx = BN_CTX_new();
|
||||
int ret = 0;
|
||||
|
||||
if (!EC_GROUP_VERSION(group))
|
||||
goto err;
|
||||
|
||||
if (group->mont_data) {
|
||||
BN_MONT_CTX_free(group->mont_data);
|
||||
group->mont_data = NULL;
|
||||
}
|
||||
BN_MONT_CTX_free(group->mont_data);
|
||||
group->mont_data = NULL;
|
||||
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
|
||||
group->mont_data = BN_MONT_CTX_new();
|
||||
if (!group->mont_data)
|
||||
if (group->mont_data == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_MONT_CTX_set(group->mont_data, &group->order, ctx)) {
|
||||
if (!BN_MONT_CTX_set(group->mont_data, group->order, ctx)) {
|
||||
BN_MONT_CTX_free(group->mont_data);
|
||||
group->mont_data = NULL;
|
||||
goto err;
|
||||
@@ -1128,7 +982,23 @@ int ec_precompute_mont_data(EC_GROUP *group)
|
||||
|
||||
err:
|
||||
|
||||
if (ctx)
|
||||
BN_CTX_free(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg)
|
||||
{
|
||||
return CRYPTO_set_ex_data(&key->ex_data, idx, arg);
|
||||
}
|
||||
|
||||
void *EC_KEY_get_ex_data(const EC_KEY *key, int idx)
|
||||
{
|
||||
return CRYPTO_get_ex_data(&key->ex_data, idx);
|
||||
}
|
||||
|
||||
int ec_group_simple_order_bits(const EC_GROUP *group)
|
||||
{
|
||||
if (group->order == NULL)
|
||||
return 0;
|
||||
return BN_num_bits(group->order);
|
||||
}
|
||||
|
||||
@@ -1,60 +1,12 @@
|
||||
/* crypto/ec/ec_mult.c */
|
||||
/*
|
||||
* Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright 2001-2016 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* Portions of this software developed by SUN MICROSYSTEMS, INC.,
|
||||
@@ -62,20 +14,25 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/bn_int.h"
|
||||
#include "ec_lcl.h"
|
||||
|
||||
/*
|
||||
* This file implements the wNAF-based interleaving multi-exponentation method
|
||||
* (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>);
|
||||
* for multiplication with precomputation, we use wNAF splitting
|
||||
* (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp>).
|
||||
* This file implements the wNAF-based interleaving multi-exponentiation method
|
||||
* Formerly at:
|
||||
* http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp
|
||||
* You might now find it here:
|
||||
* http://link.springer.com/chapter/10.1007%2F3-540-45537-X_13
|
||||
* http://www.bmoeller.de/pdf/TI-01-08.multiexp.pdf
|
||||
* For multiplication with precomputation, we use wNAF splitting, formerly at:
|
||||
* http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp
|
||||
*/
|
||||
|
||||
/* structure for precomputed multiples of the generator */
|
||||
typedef struct ec_pre_comp_st {
|
||||
struct ec_pre_comp_st {
|
||||
const EC_GROUP *group; /* parent EC_GROUP object */
|
||||
size_t blocksize; /* block size for wNAF splitting */
|
||||
size_t numblocks; /* max. number of blocks for which we have
|
||||
@@ -86,12 +43,8 @@ typedef struct ec_pre_comp_st {
|
||||
* objects followed by a NULL */
|
||||
size_t num; /* numblocks * 2^(w-1) */
|
||||
int references;
|
||||
} EC_PRE_COMP;
|
||||
|
||||
/* functions to manage EC_PRE_COMP within the EC_GROUP extra_data framework */
|
||||
static void *ec_pre_comp_dup(void *);
|
||||
static void ec_pre_comp_free(void *);
|
||||
static void ec_pre_comp_clear_free(void *);
|
||||
CRYPTO_RWLOCK *lock;
|
||||
};
|
||||
|
||||
static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group)
|
||||
{
|
||||
@@ -100,212 +53,58 @@ static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group)
|
||||
if (!group)
|
||||
return NULL;
|
||||
|
||||
ret = (EC_PRE_COMP *)OPENSSL_malloc(sizeof(EC_PRE_COMP));
|
||||
if (!ret) {
|
||||
ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
if (ret == NULL) {
|
||||
ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret->group = group;
|
||||
ret->blocksize = 8; /* default */
|
||||
ret->numblocks = 0;
|
||||
ret->w = 4; /* default */
|
||||
ret->points = NULL;
|
||||
ret->num = 0;
|
||||
ret->references = 1;
|
||||
|
||||
ret->lock = CRYPTO_THREAD_lock_new();
|
||||
if (ret->lock == NULL) {
|
||||
ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *ec_pre_comp_dup(void *src_)
|
||||
{
|
||||
EC_PRE_COMP *src = src_;
|
||||
|
||||
/* no need to actually copy, these objects never change! */
|
||||
|
||||
CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
|
||||
|
||||
return src_;
|
||||
}
|
||||
|
||||
static void ec_pre_comp_free(void *pre_)
|
||||
EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_COMP *pre)
|
||||
{
|
||||
int i;
|
||||
EC_PRE_COMP *pre = pre_;
|
||||
|
||||
if (!pre)
|
||||
return;
|
||||
|
||||
i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
|
||||
if (i > 0)
|
||||
return;
|
||||
|
||||
if (pre->points) {
|
||||
EC_POINT **p;
|
||||
|
||||
for (p = pre->points; *p != NULL; p++)
|
||||
EC_POINT_free(*p);
|
||||
OPENSSL_free(pre->points);
|
||||
}
|
||||
OPENSSL_free(pre);
|
||||
if (pre != NULL)
|
||||
CRYPTO_atomic_add(&pre->references, 1, &i, pre->lock);
|
||||
return pre;
|
||||
}
|
||||
|
||||
static void ec_pre_comp_clear_free(void *pre_)
|
||||
void EC_ec_pre_comp_free(EC_PRE_COMP *pre)
|
||||
{
|
||||
int i;
|
||||
EC_PRE_COMP *pre = pre_;
|
||||
|
||||
if (!pre)
|
||||
if (pre == NULL)
|
||||
return;
|
||||
|
||||
i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
|
||||
CRYPTO_atomic_add(&pre->references, -1, &i, pre->lock);
|
||||
REF_PRINT_COUNT("EC_ec", pre);
|
||||
if (i > 0)
|
||||
return;
|
||||
REF_ASSERT_ISNT(i < 0);
|
||||
|
||||
if (pre->points) {
|
||||
EC_POINT **p;
|
||||
if (pre->points != NULL) {
|
||||
EC_POINT **pts;
|
||||
|
||||
for (p = pre->points; *p != NULL; p++) {
|
||||
EC_POINT_clear_free(*p);
|
||||
OPENSSL_cleanse(p, sizeof *p);
|
||||
}
|
||||
for (pts = pre->points; *pts != NULL; pts++)
|
||||
EC_POINT_free(*pts);
|
||||
OPENSSL_free(pre->points);
|
||||
}
|
||||
OPENSSL_cleanse(pre, sizeof *pre);
|
||||
CRYPTO_THREAD_lock_free(pre->lock);
|
||||
OPENSSL_free(pre);
|
||||
}
|
||||
|
||||
/*-
|
||||
* Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
|
||||
* This is an array r[] of values that are either zero or odd with an
|
||||
* absolute value less than 2^w satisfying
|
||||
* scalar = \sum_j r[j]*2^j
|
||||
* where at most one of any w+1 consecutive digits is non-zero
|
||||
* with the exception that the most significant digit may be only
|
||||
* w-1 zeros away from that next non-zero digit.
|
||||
*/
|
||||
static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
|
||||
{
|
||||
int window_val;
|
||||
int ok = 0;
|
||||
signed char *r = NULL;
|
||||
int sign = 1;
|
||||
int bit, next_bit, mask;
|
||||
size_t len = 0, j;
|
||||
|
||||
if (BN_is_zero(scalar)) {
|
||||
r = OPENSSL_malloc(1);
|
||||
if (!r) {
|
||||
ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
r[0] = 0;
|
||||
*ret_len = 1;
|
||||
return r;
|
||||
}
|
||||
|
||||
if (w <= 0 || w > 7) { /* 'signed char' can represent integers with
|
||||
* absolute values less than 2^7 */
|
||||
ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
bit = 1 << w; /* at most 128 */
|
||||
next_bit = bit << 1; /* at most 256 */
|
||||
mask = next_bit - 1; /* at most 255 */
|
||||
|
||||
if (BN_is_negative(scalar)) {
|
||||
sign = -1;
|
||||
}
|
||||
|
||||
if (scalar->d == NULL || scalar->top == 0) {
|
||||
ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
len = BN_num_bits(scalar);
|
||||
r = OPENSSL_malloc(len + 1); /* modified wNAF may be one digit longer
|
||||
* than binary representation (*ret_len will
|
||||
* be set to the actual length, i.e. at most
|
||||
* BN_num_bits(scalar) + 1) */
|
||||
if (r == NULL) {
|
||||
ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
window_val = scalar->d[0] & mask;
|
||||
j = 0;
|
||||
while ((window_val != 0) || (j + w + 1 < len)) { /* if j+w+1 >= len,
|
||||
* window_val will not
|
||||
* increase */
|
||||
int digit = 0;
|
||||
|
||||
/* 0 <= window_val <= 2^(w+1) */
|
||||
|
||||
if (window_val & 1) {
|
||||
/* 0 < window_val < 2^(w+1) */
|
||||
|
||||
if (window_val & bit) {
|
||||
digit = window_val - next_bit; /* -2^w < digit < 0 */
|
||||
|
||||
#if 1 /* modified wNAF */
|
||||
if (j + w + 1 >= len) {
|
||||
/*
|
||||
* special case for generating modified wNAFs: no new
|
||||
* bits will be added into window_val, so using a
|
||||
* positive digit here will decrease the total length of
|
||||
* the representation
|
||||
*/
|
||||
|
||||
digit = window_val & (mask >> 1); /* 0 < digit < 2^w */
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
digit = window_val; /* 0 < digit < 2^w */
|
||||
}
|
||||
|
||||
if (digit <= -bit || digit >= bit || !(digit & 1)) {
|
||||
ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
window_val -= digit;
|
||||
|
||||
/*
|
||||
* now window_val is 0 or 2^(w+1) in standard wNAF generation;
|
||||
* for modified window NAFs, it may also be 2^w
|
||||
*/
|
||||
if (window_val != 0 && window_val != next_bit
|
||||
&& window_val != bit) {
|
||||
ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
r[j++] = sign * digit;
|
||||
|
||||
window_val >>= 1;
|
||||
window_val += bit * BN_is_bit_set(scalar, j + w);
|
||||
|
||||
if (window_val > next_bit) {
|
||||
ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (j > len + 1) {
|
||||
ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
len = j;
|
||||
ok = 1;
|
||||
|
||||
err:
|
||||
if (!ok) {
|
||||
OPENSSL_free(r);
|
||||
r = NULL;
|
||||
}
|
||||
if (ok)
|
||||
*ret_len = len;
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: table should be optimised for the wNAF-based implementation,
|
||||
* sometimes smaller windows will give better performance (thus the
|
||||
@@ -387,10 +186,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
|
||||
/* look if we can use precomputed multiples of generator */
|
||||
|
||||
pre_comp =
|
||||
EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup,
|
||||
ec_pre_comp_free, ec_pre_comp_clear_free);
|
||||
|
||||
pre_comp = group->pre_comp.ec;
|
||||
if (pre_comp && pre_comp->numblocks
|
||||
&& (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) ==
|
||||
0)) {
|
||||
@@ -433,10 +229,10 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]);
|
||||
|
||||
/* Ensure wNAF is initialised in case we end up going to err */
|
||||
if (wNAF)
|
||||
if (wNAF != NULL)
|
||||
wNAF[0] = NULL; /* preliminary pivot */
|
||||
|
||||
if (!wsize || !wNAF_len || !wNAF || !val_sub) {
|
||||
if (wsize == NULL || wNAF_len == NULL || wNAF == NULL || val_sub == NULL) {
|
||||
ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
@@ -454,8 +250,8 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
num_val += (size_t)1 << (wsize[i] - 1);
|
||||
wNAF[i + 1] = NULL; /* make sure we always have a pivot */
|
||||
wNAF[i] =
|
||||
compute_wNAF((i < num ? scalars[i] : scalar), wsize[i],
|
||||
&wNAF_len[i]);
|
||||
bn_compute_wNAF((i < num ? scalars[i] : scalar), wsize[i],
|
||||
&wNAF_len[i]);
|
||||
if (wNAF[i] == NULL)
|
||||
goto err;
|
||||
if (wNAF_len[i] > max_len)
|
||||
@@ -484,7 +280,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
* use the window size for which we have precomputation
|
||||
*/
|
||||
wsize[num] = pre_comp->w;
|
||||
tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len);
|
||||
tmp_wNAF = bn_compute_wNAF(scalar, wsize[num], &tmp_len);
|
||||
if (!tmp_wNAF)
|
||||
goto err;
|
||||
|
||||
@@ -500,8 +296,6 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
wNAF[num] = tmp_wNAF;
|
||||
wNAF[num + 1] = NULL;
|
||||
wNAF_len[num] = tmp_len;
|
||||
if (tmp_len > max_len)
|
||||
max_len = tmp_len;
|
||||
/*
|
||||
* pre_comp->points starts with the points that we need here:
|
||||
*/
|
||||
@@ -522,6 +316,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
numblocks = (tmp_len + blocksize - 1) / blocksize;
|
||||
if (numblocks > pre_comp->numblocks) {
|
||||
ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
|
||||
OPENSSL_free(tmp_wNAF);
|
||||
goto err;
|
||||
}
|
||||
totalnum = num + numblocks;
|
||||
@@ -536,6 +331,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
wNAF_len[i] = blocksize;
|
||||
if (tmp_len < blocksize) {
|
||||
ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
|
||||
OPENSSL_free(tmp_wNAF);
|
||||
goto err;
|
||||
}
|
||||
tmp_len -= blocksize;
|
||||
@@ -599,7 +395,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!(tmp = EC_POINT_new(group)))
|
||||
if ((tmp = EC_POINT_new(group)) == NULL)
|
||||
goto err;
|
||||
|
||||
/*-
|
||||
@@ -629,11 +425,8 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
}
|
||||
}
|
||||
|
||||
#if 1 /* optional; EC_window_bits_for_scalar_size
|
||||
* assumes we do this step */
|
||||
if (!EC_POINTs_make_affine(group, num_val, val, ctx))
|
||||
goto err;
|
||||
#endif
|
||||
|
||||
r_is_at_infinity = 1;
|
||||
|
||||
@@ -690,14 +483,10 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
if (tmp != NULL)
|
||||
EC_POINT_free(tmp);
|
||||
if (wsize != NULL)
|
||||
OPENSSL_free(wsize);
|
||||
if (wNAF_len != NULL)
|
||||
OPENSSL_free(wNAF_len);
|
||||
BN_CTX_free(new_ctx);
|
||||
EC_POINT_free(tmp);
|
||||
OPENSSL_free(wsize);
|
||||
OPENSSL_free(wNAF_len);
|
||||
if (wNAF != NULL) {
|
||||
signed char **w;
|
||||
|
||||
@@ -712,9 +501,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
|
||||
OPENSSL_free(val);
|
||||
}
|
||||
if (val_sub != NULL) {
|
||||
OPENSSL_free(val_sub);
|
||||
}
|
||||
OPENSSL_free(val_sub);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -743,16 +530,14 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
const EC_POINT *generator;
|
||||
EC_POINT *tmp_point = NULL, *base = NULL, **var;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
BIGNUM *order;
|
||||
const BIGNUM *order;
|
||||
size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num;
|
||||
EC_POINT **points = NULL;
|
||||
EC_PRE_COMP *pre_comp;
|
||||
int ret = 0;
|
||||
|
||||
/* if there is an old EC_PRE_COMP object, throw it away */
|
||||
EC_EX_DATA_free_data(&group->extra_data, ec_pre_comp_dup,
|
||||
ec_pre_comp_free, ec_pre_comp_clear_free);
|
||||
|
||||
EC_pre_comp_free(group);
|
||||
if ((pre_comp = ec_pre_comp_new(group)) == NULL)
|
||||
return 0;
|
||||
|
||||
@@ -769,11 +554,9 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
}
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
order = BN_CTX_get(ctx);
|
||||
if (order == NULL)
|
||||
goto err;
|
||||
|
||||
if (!EC_GROUP_get_order(group, order, ctx))
|
||||
order = EC_GROUP_get0_order(group);
|
||||
if (order == NULL)
|
||||
goto err;
|
||||
if (BN_is_zero(order)) {
|
||||
ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER);
|
||||
@@ -802,8 +585,8 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
num = pre_points_per_block * numblocks; /* number of points to compute
|
||||
* and store */
|
||||
|
||||
points = OPENSSL_malloc(sizeof(EC_POINT *) * (num + 1));
|
||||
if (!points) {
|
||||
points = OPENSSL_malloc(sizeof(*points) * (num + 1));
|
||||
if (points == NULL) {
|
||||
ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
@@ -817,7 +600,8 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) {
|
||||
if ((tmp_point = EC_POINT_new(group)) == NULL
|
||||
|| (base = EC_POINT_new(group)) == NULL) {
|
||||
ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
@@ -873,21 +657,15 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
pre_comp->points = points;
|
||||
points = NULL;
|
||||
pre_comp->num = num;
|
||||
|
||||
if (!EC_EX_DATA_set_data(&group->extra_data, pre_comp,
|
||||
ec_pre_comp_dup, ec_pre_comp_free,
|
||||
ec_pre_comp_clear_free))
|
||||
goto err;
|
||||
SETPRECOMP(group, ec, pre_comp);
|
||||
pre_comp = NULL;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
if (pre_comp)
|
||||
ec_pre_comp_free(pre_comp);
|
||||
BN_CTX_free(new_ctx);
|
||||
EC_ec_pre_comp_free(pre_comp);
|
||||
if (points) {
|
||||
EC_POINT **p;
|
||||
|
||||
@@ -895,19 +673,12 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
EC_POINT_free(*p);
|
||||
OPENSSL_free(points);
|
||||
}
|
||||
if (tmp_point)
|
||||
EC_POINT_free(tmp_point);
|
||||
if (base)
|
||||
EC_POINT_free(base);
|
||||
EC_POINT_free(tmp_point);
|
||||
EC_POINT_free(base);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ec_wNAF_have_precompute_mult(const EC_GROUP *group)
|
||||
{
|
||||
if (EC_EX_DATA_get_data
|
||||
(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free,
|
||||
ec_pre_comp_clear_free) != NULL)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
return HAVEPRECOMP(group, ec);
|
||||
}
|
||||
|
||||
@@ -1,60 +1,12 @@
|
||||
/* crypto/ec/ec_lib.c */
|
||||
/*
|
||||
* Originally written by Bodo Moeller for the OpenSSL project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright 2011-2016 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* Binary polynomial ECC support in OpenSSL originally developed by
|
||||
@@ -190,3 +142,24 @@ int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
|
||||
}
|
||||
return group->meth->oct2point(group, point, buf, len, ctx);
|
||||
}
|
||||
|
||||
size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point,
|
||||
point_conversion_form_t form,
|
||||
unsigned char **pbuf, BN_CTX *ctx)
|
||||
{
|
||||
size_t len;
|
||||
unsigned char *buf;
|
||||
len = EC_POINT_point2oct(group, point, form, NULL, 0, NULL);
|
||||
if (len == 0)
|
||||
return 0;
|
||||
buf = OPENSSL_malloc(len);
|
||||
if (buf == NULL)
|
||||
return 0;
|
||||
len = EC_POINT_point2oct(group, point, form, buf, len, ctx);
|
||||
if (len == 0) {
|
||||
OPENSSL_free(buf);
|
||||
return 0;
|
||||
}
|
||||
*pbuf = buf;
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -1,70 +1,20 @@
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2006.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
* Copyright 2006-2016 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
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/ec.h>
|
||||
#include "ec_lcl.h"
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "evp_locl.h"
|
||||
#include "internal/evp_int.h"
|
||||
|
||||
/* EC pkey context structure */
|
||||
|
||||
@@ -91,22 +41,14 @@ typedef struct {
|
||||
static int pkey_ec_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
EC_PKEY_CTX *dctx;
|
||||
dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX));
|
||||
if (!dctx)
|
||||
|
||||
dctx = OPENSSL_zalloc(sizeof(*dctx));
|
||||
if (dctx == NULL)
|
||||
return 0;
|
||||
dctx->gen_group = NULL;
|
||||
dctx->md = NULL;
|
||||
|
||||
dctx->cofactor_mode = -1;
|
||||
dctx->co_key = NULL;
|
||||
dctx->kdf_type = EVP_PKEY_ECDH_KDF_NONE;
|
||||
dctx->kdf_md = NULL;
|
||||
dctx->kdf_outlen = 0;
|
||||
dctx->kdf_ukm = NULL;
|
||||
dctx->kdf_ukmlen = 0;
|
||||
|
||||
ctx->data = dctx;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -133,7 +75,7 @@ static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
|
||||
dctx->kdf_md = sctx->kdf_md;
|
||||
dctx->kdf_outlen = sctx->kdf_outlen;
|
||||
if (sctx->kdf_ukm) {
|
||||
dctx->kdf_ukm = BUF_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
|
||||
dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
|
||||
if (!dctx->kdf_ukm)
|
||||
return 0;
|
||||
} else
|
||||
@@ -146,12 +88,9 @@ static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
EC_PKEY_CTX *dctx = ctx->data;
|
||||
if (dctx) {
|
||||
if (dctx->gen_group)
|
||||
EC_GROUP_free(dctx->gen_group);
|
||||
if (dctx->co_key)
|
||||
EC_KEY_free(dctx->co_key);
|
||||
if (dctx->kdf_ukm)
|
||||
OPENSSL_free(dctx->kdf_ukm);
|
||||
EC_GROUP_free(dctx->gen_group);
|
||||
EC_KEY_free(dctx->co_key);
|
||||
OPENSSL_free(dctx->kdf_ukm);
|
||||
OPENSSL_free(dctx);
|
||||
}
|
||||
}
|
||||
@@ -203,7 +142,7 @@ static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_ECDH
|
||||
#ifndef OPENSSL_NO_EC
|
||||
static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
|
||||
size_t *keylen)
|
||||
{
|
||||
@@ -259,7 +198,7 @@ static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx,
|
||||
if (!pkey_ec_derive(ctx, NULL, &ktmplen))
|
||||
return 0;
|
||||
ktmp = OPENSSL_malloc(ktmplen);
|
||||
if (!ktmp)
|
||||
if (ktmp == NULL)
|
||||
return 0;
|
||||
if (!pkey_ec_derive(ctx, ktmp, &ktmplen))
|
||||
goto err;
|
||||
@@ -270,10 +209,7 @@ static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx,
|
||||
rv = 1;
|
||||
|
||||
err:
|
||||
if (ktmp) {
|
||||
OPENSSL_cleanse(ktmp, ktmplen);
|
||||
OPENSSL_free(ktmp);
|
||||
}
|
||||
OPENSSL_clear_free(ktmp, ktmplen);
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
@@ -289,8 +225,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
|
||||
return 0;
|
||||
}
|
||||
if (dctx->gen_group)
|
||||
EC_GROUP_free(dctx->gen_group);
|
||||
EC_GROUP_free(dctx->gen_group);
|
||||
dctx->gen_group = group;
|
||||
return 1;
|
||||
|
||||
@@ -302,7 +237,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
EC_GROUP_set_asn1_flag(dctx->gen_group, p1);
|
||||
return 1;
|
||||
|
||||
#ifndef OPENSSL_NO_ECDH
|
||||
#ifndef OPENSSL_NO_EC
|
||||
case EVP_PKEY_CTRL_EC_ECDH_COFACTOR:
|
||||
if (p1 == -2) {
|
||||
if (dctx->cofactor_mode != -1)
|
||||
@@ -320,7 +255,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
if (!ec_key->group)
|
||||
return -2;
|
||||
/* If cofactor is 1 cofactor mode does nothing */
|
||||
if (BN_is_one(&ec_key->group->cofactor))
|
||||
if (BN_is_one(ec_key->group->cofactor))
|
||||
return 1;
|
||||
if (!dctx->co_key) {
|
||||
dctx->co_key = EC_KEY_dup(ec_key);
|
||||
@@ -331,7 +266,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
EC_KEY_set_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH);
|
||||
else
|
||||
EC_KEY_clear_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH);
|
||||
} else if (dctx->co_key) {
|
||||
} else {
|
||||
EC_KEY_free(dctx->co_key);
|
||||
dctx->co_key = NULL;
|
||||
}
|
||||
@@ -365,8 +300,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_EC_KDF_UKM:
|
||||
if (dctx->kdf_ukm)
|
||||
OPENSSL_free(dctx->kdf_ukm);
|
||||
OPENSSL_free(dctx->kdf_ukm);
|
||||
dctx->kdf_ukm = p2;
|
||||
if (p2)
|
||||
dctx->kdf_ukmlen = p1;
|
||||
@@ -411,7 +345,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
|
||||
const char *type, const char *value)
|
||||
{
|
||||
if (!strcmp(type, "ec_paramgen_curve")) {
|
||||
if (strcmp(type, "ec_paramgen_curve") == 0) {
|
||||
int nid;
|
||||
nid = EC_curve_nist2nid(value);
|
||||
if (nid == NID_undef)
|
||||
@@ -423,23 +357,23 @@ static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
|
||||
return 0;
|
||||
}
|
||||
return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
|
||||
} else if (!strcmp(type, "ec_param_enc")) {
|
||||
} else if (strcmp(type, "ec_param_enc") == 0) {
|
||||
int param_enc;
|
||||
if (!strcmp(value, "explicit"))
|
||||
if (strcmp(value, "explicit") == 0)
|
||||
param_enc = 0;
|
||||
else if (!strcmp(value, "named_curve"))
|
||||
else if (strcmp(value, "named_curve") == 0)
|
||||
param_enc = OPENSSL_EC_NAMED_CURVE;
|
||||
else
|
||||
return -2;
|
||||
return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc);
|
||||
} else if (!strcmp(type, "ecdh_kdf_md")) {
|
||||
} else if (strcmp(type, "ecdh_kdf_md") == 0) {
|
||||
const EVP_MD *md;
|
||||
if (!(md = EVP_get_digestbyname(value))) {
|
||||
if ((md = EVP_get_digestbyname(value)) == NULL) {
|
||||
ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_DIGEST);
|
||||
return 0;
|
||||
}
|
||||
return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md);
|
||||
} else if (!strcmp(type, "ecdh_cofactor_mode")) {
|
||||
} else if (strcmp(type, "ecdh_cofactor_mode") == 0) {
|
||||
int co_mode;
|
||||
co_mode = atoi(value);
|
||||
return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, co_mode);
|
||||
@@ -458,7 +392,7 @@ static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
return 0;
|
||||
}
|
||||
ec = EC_KEY_new();
|
||||
if (!ec)
|
||||
if (ec == NULL)
|
||||
return 0;
|
||||
ret = EC_KEY_set_group(ec, dctx->gen_group);
|
||||
if (ret)
|
||||
@@ -519,12 +453,11 @@ const EVP_PKEY_METHOD ec_pkey_meth = {
|
||||
0, 0,
|
||||
|
||||
0,
|
||||
#ifndef OPENSSL_NO_ECDH
|
||||
#ifndef OPENSSL_NO_EC
|
||||
pkey_ec_kdf_derive,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
|
||||
pkey_ec_ctrl,
|
||||
pkey_ec_ctrl_str
|
||||
};
|
||||
|
||||
@@ -1,56 +1,10 @@
|
||||
/* crypto/ec/ec_print.c */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
/*
|
||||
* Copyright 2002-2016 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
|
||||
*/
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
@@ -64,18 +18,11 @@ BIGNUM *EC_POINT_point2bn(const EC_GROUP *group,
|
||||
size_t buf_len = 0;
|
||||
unsigned char *buf;
|
||||
|
||||
buf_len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx);
|
||||
buf_len = EC_POINT_point2buf(group, point, form, &buf, ctx);
|
||||
|
||||
if (buf_len == 0)
|
||||
return NULL;
|
||||
|
||||
if ((buf = OPENSSL_malloc(buf_len)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) {
|
||||
OPENSSL_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = BN_bin2bn(buf, buf_len, ret);
|
||||
|
||||
OPENSSL_free(buf);
|
||||
@@ -110,7 +57,7 @@ EC_POINT *EC_POINT_bn2point(const EC_GROUP *group,
|
||||
ret = point;
|
||||
|
||||
if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) {
|
||||
if (point == NULL)
|
||||
if (ret != point)
|
||||
EC_POINT_clear_free(ret);
|
||||
OPENSSL_free(buf);
|
||||
return NULL;
|
||||
@@ -129,21 +76,14 @@ char *EC_POINT_point2hex(const EC_GROUP *group,
|
||||
{
|
||||
char *ret, *p;
|
||||
size_t buf_len = 0, i;
|
||||
unsigned char *buf, *pbuf;
|
||||
unsigned char *buf = NULL, *pbuf;
|
||||
|
||||
buf_len = EC_POINT_point2buf(group, point, form, &buf, ctx);
|
||||
|
||||
buf_len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx);
|
||||
if (buf_len == 0)
|
||||
return NULL;
|
||||
|
||||
if ((buf = OPENSSL_malloc(buf_len)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) {
|
||||
OPENSSL_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = (char *)OPENSSL_malloc(buf_len * 2 + 2);
|
||||
ret = OPENSSL_malloc(buf_len * 2 + 2);
|
||||
if (ret == NULL) {
|
||||
OPENSSL_free(buf);
|
||||
return NULL;
|
||||
|
||||
68
crypto/ec/ecdh_kdf.c
Normal file
68
crypto/ec/ecdh_kdf.c
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2015-2016 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
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
/* Key derivation function from X9.62/SECG */
|
||||
/* Way more than we will ever need */
|
||||
#define ECDH_KDF_MAX (1 << 30)
|
||||
|
||||
int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
|
||||
const unsigned char *Z, size_t Zlen,
|
||||
const unsigned char *sinfo, size_t sinfolen,
|
||||
const EVP_MD *md)
|
||||
{
|
||||
EVP_MD_CTX *mctx = NULL;
|
||||
int rv = 0;
|
||||
unsigned int i;
|
||||
size_t mdlen;
|
||||
unsigned char ctr[4];
|
||||
if (sinfolen > ECDH_KDF_MAX || outlen > ECDH_KDF_MAX
|
||||
|| Zlen > ECDH_KDF_MAX)
|
||||
return 0;
|
||||
mctx = EVP_MD_CTX_new();
|
||||
if (mctx == NULL)
|
||||
return 0;
|
||||
mdlen = EVP_MD_size(md);
|
||||
for (i = 1;; i++) {
|
||||
unsigned char mtmp[EVP_MAX_MD_SIZE];
|
||||
if (!EVP_DigestInit_ex(mctx, md, NULL))
|
||||
goto err;
|
||||
ctr[3] = i & 0xFF;
|
||||
ctr[2] = (i >> 8) & 0xFF;
|
||||
ctr[1] = (i >> 16) & 0xFF;
|
||||
ctr[0] = (i >> 24) & 0xFF;
|
||||
if (!EVP_DigestUpdate(mctx, Z, Zlen))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(mctx, ctr, sizeof(ctr)))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(mctx, sinfo, sinfolen))
|
||||
goto err;
|
||||
if (outlen >= mdlen) {
|
||||
if (!EVP_DigestFinal(mctx, out, NULL))
|
||||
goto err;
|
||||
outlen -= mdlen;
|
||||
if (outlen == 0)
|
||||
break;
|
||||
out += mdlen;
|
||||
} else {
|
||||
if (!EVP_DigestFinal(mctx, mtmp, NULL))
|
||||
goto err;
|
||||
memcpy(out, mtmp, outlen);
|
||||
OPENSSL_cleanse(mtmp, mdlen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
rv = 1;
|
||||
err:
|
||||
EVP_MD_CTX_free(mctx);
|
||||
return rv;
|
||||
}
|
||||
143
crypto/ec/ecdh_ossl.c
Normal file
143
crypto/ec/ecdh_ossl.c
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
*
|
||||
* The Elliptic Curve Public-Key Crypto Library (ECC Code) included
|
||||
* herein is developed by SUN MICROSYSTEMS, INC., and is contributed
|
||||
* to the OpenSSL project.
|
||||
*
|
||||
* The ECC Code is licensed pursuant to the OpenSSL open source
|
||||
* license provided below.
|
||||
*
|
||||
* The ECDH software is originally written by Douglas Stebila of
|
||||
* Sun Microsystems Laboratories.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/ec.h>
|
||||
#include "ec_lcl.h"
|
||||
|
||||
int ossl_ecdh_compute_key(unsigned char **psec, size_t *pseclen,
|
||||
const EC_POINT *pub_key, const EC_KEY *ecdh)
|
||||
{
|
||||
if (ecdh->group->meth->ecdh_compute_key == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDH_COMPUTE_KEY, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ecdh->group->meth->ecdh_compute_key(psec, pseclen, pub_key, ecdh);
|
||||
}
|
||||
|
||||
/*-
|
||||
* This implementation is based on the following primitives in the IEEE 1363 standard:
|
||||
* - ECKAS-DH1
|
||||
* - ECSVDP-DH
|
||||
*/
|
||||
int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
|
||||
const EC_POINT *pub_key, const EC_KEY *ecdh)
|
||||
{
|
||||
BN_CTX *ctx;
|
||||
EC_POINT *tmp = NULL;
|
||||
BIGNUM *x = NULL, *y = NULL;
|
||||
const BIGNUM *priv_key;
|
||||
const EC_GROUP *group;
|
||||
int ret = 0;
|
||||
size_t buflen, len;
|
||||
unsigned char *buf = NULL;
|
||||
|
||||
if ((ctx = BN_CTX_new()) == NULL)
|
||||
goto err;
|
||||
BN_CTX_start(ctx);
|
||||
x = BN_CTX_get(ctx);
|
||||
y = BN_CTX_get(ctx);
|
||||
|
||||
priv_key = EC_KEY_get0_private_key(ecdh);
|
||||
if (priv_key == NULL) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_NO_PRIVATE_VALUE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
group = EC_KEY_get0_group(ecdh);
|
||||
|
||||
if (EC_KEY_get_flags(ecdh) & EC_FLAG_COFACTOR_ECDH) {
|
||||
if (!EC_GROUP_get_cofactor(group, x, NULL) ||
|
||||
!BN_mul(x, x, priv_key, ctx)) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
priv_key = x;
|
||||
}
|
||||
|
||||
if ((tmp = EC_POINT_new(group)) == NULL) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
|
||||
NID_X9_62_prime_field) {
|
||||
if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx)) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
else {
|
||||
if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx)) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
buflen = (EC_GROUP_get_degree(group) + 7) / 8;
|
||||
len = BN_num_bytes(x);
|
||||
if (len > buflen) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if ((buf = OPENSSL_malloc(buflen)) == NULL) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
memset(buf, 0, buflen - len);
|
||||
if (len != (size_t)BN_bn2bin(x, buf + buflen - len)) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
*pout = buf;
|
||||
*poutlen = buflen;
|
||||
buf = NULL;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EC_POINT_free(tmp);
|
||||
if (ctx)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
OPENSSL_free(buf);
|
||||
return ret;
|
||||
}
|
||||
462
crypto/ec/ecdsa_ossl.c
Normal file
462
crypto/ec/ecdsa_ossl.c
Normal file
@@ -0,0 +1,462 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/ec.h>
|
||||
#include "ec_lcl.h"
|
||||
|
||||
int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen,
|
||||
unsigned char *sig, unsigned int *siglen,
|
||||
const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey)
|
||||
{
|
||||
ECDSA_SIG *s;
|
||||
RAND_seed(dgst, dlen);
|
||||
s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey);
|
||||
if (s == NULL) {
|
||||
*siglen = 0;
|
||||
return 0;
|
||||
}
|
||||
*siglen = i2d_ECDSA_SIG(s, &sig);
|
||||
ECDSA_SIG_free(s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
|
||||
BIGNUM **kinvp, BIGNUM **rp,
|
||||
const unsigned char *dgst, int dlen)
|
||||
{
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *k = NULL, *r = NULL, *X = NULL;
|
||||
const BIGNUM *order;
|
||||
EC_POINT *tmp_point = NULL;
|
||||
const EC_GROUP *group;
|
||||
int ret = 0;
|
||||
|
||||
if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!EC_KEY_can_sign(eckey)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx_in == NULL) {
|
||||
if ((ctx = BN_CTX_new()) == NULL) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
ctx = ctx_in;
|
||||
|
||||
k = BN_new(); /* this value is later returned in *kinvp */
|
||||
r = BN_new(); /* this value is later returned in *rp */
|
||||
X = BN_new();
|
||||
if (k == NULL || r == NULL || X == NULL) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if ((tmp_point = EC_POINT_new(group)) == NULL) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
order = EC_GROUP_get0_order(group);
|
||||
if (order == NULL) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
do {
|
||||
/* get random k */
|
||||
do
|
||||
if (dgst != NULL) {
|
||||
if (!BN_generate_dsa_nonce
|
||||
(k, order, EC_KEY_get0_private_key(eckey), dgst, dlen,
|
||||
ctx)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP,
|
||||
EC_R_RANDOM_NUMBER_GENERATION_FAILED);
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
if (!BN_rand_range(k, order)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP,
|
||||
EC_R_RANDOM_NUMBER_GENERATION_FAILED);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
while (BN_is_zero(k));
|
||||
|
||||
/*
|
||||
* We do not want timing information to leak the length of k, so we
|
||||
* compute G*k using an equivalent scalar of fixed bit-length.
|
||||
*/
|
||||
|
||||
if (!BN_add(k, k, order))
|
||||
goto err;
|
||||
if (BN_num_bits(k) <= BN_num_bits(order))
|
||||
if (!BN_add(k, k, order))
|
||||
goto err;
|
||||
|
||||
/* compute r the x-coordinate of generator * k */
|
||||
if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
|
||||
NID_X9_62_prime_field) {
|
||||
if (!EC_POINT_get_affine_coordinates_GFp
|
||||
(group, tmp_point, X, NULL, ctx)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
else { /* NID_X9_62_characteristic_two_field */
|
||||
|
||||
if (!EC_POINT_get_affine_coordinates_GF2m(group,
|
||||
tmp_point, X, NULL,
|
||||
ctx)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!BN_nnmod(r, X, order, ctx)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
while (BN_is_zero(r));
|
||||
|
||||
/* compute the inverse of k */
|
||||
if (EC_GROUP_get_mont_data(group) != NULL) {
|
||||
/*
|
||||
* We want inverse in constant time, therefore we utilize the fact
|
||||
* order must be prime and use Fermats Little Theorem instead.
|
||||
*/
|
||||
if (!BN_set_word(X, 2)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (!BN_mod_sub(X, order, X, order, ctx)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
BN_set_flags(X, BN_FLG_CONSTTIME);
|
||||
if (!BN_mod_exp_mont_consttime
|
||||
(k, k, X, order, ctx, EC_GROUP_get_mont_data(group))) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
if (!BN_mod_inverse(k, k, order, ctx)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* clear old values if necessary */
|
||||
BN_clear_free(*rp);
|
||||
BN_clear_free(*kinvp);
|
||||
/* save the pre-computed values */
|
||||
*rp = r;
|
||||
*kinvp = k;
|
||||
ret = 1;
|
||||
err:
|
||||
if (!ret) {
|
||||
BN_clear_free(k);
|
||||
BN_clear_free(r);
|
||||
}
|
||||
if (ctx != ctx_in)
|
||||
BN_CTX_free(ctx);
|
||||
EC_POINT_free(tmp_point);
|
||||
BN_clear_free(X);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
|
||||
BIGNUM **rp)
|
||||
{
|
||||
return ecdsa_sign_setup(eckey, ctx_in, kinvp, rp, NULL, 0);
|
||||
}
|
||||
|
||||
ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
|
||||
const BIGNUM *in_kinv, const BIGNUM *in_r,
|
||||
EC_KEY *eckey)
|
||||
{
|
||||
int ok = 0, i;
|
||||
BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL;
|
||||
const BIGNUM *order, *ckinv;
|
||||
BN_CTX *ctx = NULL;
|
||||
const EC_GROUP *group;
|
||||
ECDSA_SIG *ret;
|
||||
const BIGNUM *priv_key;
|
||||
|
||||
group = EC_KEY_get0_group(eckey);
|
||||
priv_key = EC_KEY_get0_private_key(eckey);
|
||||
|
||||
if (group == NULL || priv_key == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!EC_KEY_can_sign(eckey)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = ECDSA_SIG_new();
|
||||
if (ret == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
ret->r = BN_new();
|
||||
ret->s = BN_new();
|
||||
if (ret->r == NULL || ret->s == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
s = ret->s;
|
||||
|
||||
if ((ctx = BN_CTX_new()) == NULL ||
|
||||
(tmp = BN_new()) == NULL || (m = BN_new()) == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
order = EC_GROUP_get0_order(group);
|
||||
if (order == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
i = BN_num_bits(order);
|
||||
/*
|
||||
* Need to truncate digest if it is too long: first truncate whole bytes.
|
||||
*/
|
||||
if (8 * dgst_len > i)
|
||||
dgst_len = (i + 7) / 8;
|
||||
if (!BN_bin2bn(dgst, dgst_len, m)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
/* If still too long truncate remaining bits with a shift */
|
||||
if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
do {
|
||||
if (in_kinv == NULL || in_r == NULL) {
|
||||
if (!ecdsa_sign_setup(eckey, ctx, &kinv, &ret->r, dgst, dgst_len)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_ECDSA_LIB);
|
||||
goto err;
|
||||
}
|
||||
ckinv = kinv;
|
||||
} else {
|
||||
ckinv = in_kinv;
|
||||
if (BN_copy(ret->r, in_r) == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (!BN_mod_add_quick(s, tmp, m, order)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (!BN_mod_mul(s, s, ckinv, order, ctx)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (BN_is_zero(s)) {
|
||||
/*
|
||||
* if kinv and r have been supplied by the caller don't to
|
||||
* generate new kinv and r values
|
||||
*/
|
||||
if (in_kinv != NULL && in_r != NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_NEED_NEW_SETUP_VALUES);
|
||||
goto err;
|
||||
}
|
||||
} else
|
||||
/* s != 0 => we have a valid signature */
|
||||
break;
|
||||
}
|
||||
while (1);
|
||||
|
||||
ok = 1;
|
||||
err:
|
||||
if (!ok) {
|
||||
ECDSA_SIG_free(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
BN_CTX_free(ctx);
|
||||
BN_clear_free(m);
|
||||
BN_clear_free(tmp);
|
||||
BN_clear_free(kinv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-
|
||||
* returns
|
||||
* 1: correct signature
|
||||
* 0: incorrect signature
|
||||
* -1: error
|
||||
*/
|
||||
int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
|
||||
const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
|
||||
{
|
||||
ECDSA_SIG *s;
|
||||
const unsigned char *p = sigbuf;
|
||||
unsigned char *der = NULL;
|
||||
int derlen = -1;
|
||||
int ret = -1;
|
||||
|
||||
s = ECDSA_SIG_new();
|
||||
if (s == NULL)
|
||||
return (ret);
|
||||
if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL)
|
||||
goto err;
|
||||
/* Ensure signature uses DER and doesn't have trailing garbage */
|
||||
derlen = i2d_ECDSA_SIG(s, &der);
|
||||
if (derlen != sig_len || memcmp(sigbuf, der, derlen) != 0)
|
||||
goto err;
|
||||
ret = ECDSA_do_verify(dgst, dgst_len, s, eckey);
|
||||
err:
|
||||
OPENSSL_clear_free(der, derlen);
|
||||
ECDSA_SIG_free(s);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
|
||||
const ECDSA_SIG *sig, EC_KEY *eckey)
|
||||
{
|
||||
int ret = -1, i;
|
||||
BN_CTX *ctx;
|
||||
const BIGNUM *order;
|
||||
BIGNUM *u1, *u2, *m, *X;
|
||||
EC_POINT *point = NULL;
|
||||
const EC_GROUP *group;
|
||||
const EC_POINT *pub_key;
|
||||
|
||||
/* check input values */
|
||||
if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
|
||||
(pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_MISSING_PARAMETERS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!EC_KEY_can_sign(eckey)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx = BN_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
BN_CTX_start(ctx);
|
||||
u1 = BN_CTX_get(ctx);
|
||||
u2 = BN_CTX_get(ctx);
|
||||
m = BN_CTX_get(ctx);
|
||||
X = BN_CTX_get(ctx);
|
||||
if (X == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
order = EC_GROUP_get0_order(group);
|
||||
if (order == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
|
||||
BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
|
||||
BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_BAD_SIGNATURE);
|
||||
ret = 0; /* signature is invalid */
|
||||
goto err;
|
||||
}
|
||||
/* calculate tmp1 = inv(S) mod order */
|
||||
if (!BN_mod_inverse(u2, sig->s, order, ctx)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
/* digest -> m */
|
||||
i = BN_num_bits(order);
|
||||
/*
|
||||
* Need to truncate digest if it is too long: first truncate whole bytes.
|
||||
*/
|
||||
if (8 * dgst_len > i)
|
||||
dgst_len = (i + 7) / 8;
|
||||
if (!BN_bin2bn(dgst, dgst_len, m)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
/* If still too long truncate remaining bits with a shift */
|
||||
if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
/* u1 = m * tmp mod order */
|
||||
if (!BN_mod_mul(u1, m, u2, order, ctx)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
/* u2 = r * w mod q */
|
||||
if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((point = EC_POINT_new(group)) == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
|
||||
NID_X9_62_prime_field) {
|
||||
if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
else { /* NID_X9_62_characteristic_two_field */
|
||||
|
||||
if (!EC_POINT_get_affine_coordinates_GF2m(group, point, X, NULL, ctx)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!BN_nnmod(u1, X, order, ctx)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
/* if the signature is correct u1 is equal to sig->r */
|
||||
ret = (BN_ucmp(u1, sig->r) == 0);
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
EC_POINT_free(point);
|
||||
return ret;
|
||||
}
|
||||
52
crypto/ec/ecdsa_sign.c
Normal file
52
crypto/ec/ecdsa_sign.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2015-2016 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
|
||||
*/
|
||||
|
||||
#include <openssl/ec.h>
|
||||
#include "ec_lcl.h"
|
||||
#include <openssl/err.h>
|
||||
|
||||
ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
|
||||
{
|
||||
return ECDSA_do_sign_ex(dgst, dlen, NULL, NULL, eckey);
|
||||
}
|
||||
|
||||
ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dlen,
|
||||
const BIGNUM *kinv, const BIGNUM *rp,
|
||||
EC_KEY *eckey)
|
||||
{
|
||||
if (eckey->meth->sign_sig != NULL)
|
||||
return eckey->meth->sign_sig(dgst, dlen, kinv, rp, eckey);
|
||||
ECerr(EC_F_ECDSA_DO_SIGN_EX, EC_R_OPERATION_NOT_SUPPORTED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ECDSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char
|
||||
*sig, unsigned int *siglen, EC_KEY *eckey)
|
||||
{
|
||||
return ECDSA_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey);
|
||||
}
|
||||
|
||||
int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen,
|
||||
unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv,
|
||||
const BIGNUM *r, EC_KEY *eckey)
|
||||
{
|
||||
if (eckey->meth->sign != NULL)
|
||||
return eckey->meth->sign(type, dgst, dlen, sig, siglen, kinv, r, eckey);
|
||||
ECerr(EC_F_ECDSA_SIGN_EX, EC_R_OPERATION_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
|
||||
BIGNUM **rp)
|
||||
{
|
||||
if (eckey->meth->sign_setup != NULL)
|
||||
return eckey->meth->sign_setup(eckey, ctx_in, kinvp, rp);
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_OPERATION_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
43
crypto/ec/ecdsa_vrf.c
Normal file
43
crypto/ec/ecdsa_vrf.c
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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
|
||||
*/
|
||||
|
||||
#include <openssl/ec.h>
|
||||
#include "ec_lcl.h"
|
||||
#include <openssl/err.h>
|
||||
|
||||
/*-
|
||||
* returns
|
||||
* 1: correct signature
|
||||
* 0: incorrect signature
|
||||
* -1: error
|
||||
*/
|
||||
int ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
|
||||
const ECDSA_SIG *sig, EC_KEY *eckey)
|
||||
{
|
||||
if (eckey->meth->verify_sig != NULL)
|
||||
return eckey->meth->verify_sig(dgst, dgst_len, sig, eckey);
|
||||
ECerr(EC_F_ECDSA_DO_VERIFY, EC_R_OPERATION_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-
|
||||
* returns
|
||||
* 1: correct signature
|
||||
* 0: incorrect signature
|
||||
* -1: error
|
||||
*/
|
||||
int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
|
||||
const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
|
||||
{
|
||||
if (eckey->meth->verify != NULL)
|
||||
return eckey->meth->verify(type, dgst, dgst_len, sigbuf, sig_len,
|
||||
eckey);
|
||||
ECerr(EC_F_ECDSA_VERIFY, EC_R_OPERATION_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,60 +1,12 @@
|
||||
/* crypto/ec/eck_prn.c */
|
||||
/*
|
||||
* Written by Nils Larsch for the OpenSSL project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright 2006-2016 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* Portions originally developed by SUN MICROSYSTEMS, INC., and
|
||||
@@ -62,12 +14,12 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#ifndef OPENSSL_NO_FP_API
|
||||
#ifndef OPENSSL_NO_STDIO
|
||||
int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
|
||||
{
|
||||
BIO *b;
|
||||
@@ -114,42 +66,16 @@ int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
|
||||
}
|
||||
#endif
|
||||
|
||||
int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
|
||||
{
|
||||
EVP_PKEY *pk;
|
||||
int ret;
|
||||
pk = EVP_PKEY_new();
|
||||
if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x))
|
||||
return 0;
|
||||
ret = EVP_PKEY_print_private(bp, pk, off, NULL);
|
||||
EVP_PKEY_free(pk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ECParameters_print(BIO *bp, const EC_KEY *x)
|
||||
{
|
||||
EVP_PKEY *pk;
|
||||
int ret;
|
||||
pk = EVP_PKEY_new();
|
||||
if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x))
|
||||
return 0;
|
||||
ret = EVP_PKEY_print_params(bp, pk, 4, NULL);
|
||||
EVP_PKEY_free(pk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int print_bin(BIO *fp, const char *str, const unsigned char *num,
|
||||
size_t len, int off);
|
||||
|
||||
int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
|
||||
{
|
||||
unsigned char *buffer = NULL;
|
||||
size_t buf_len = 0, i;
|
||||
int ret = 0, reason = ERR_R_BIO_LIB;
|
||||
BN_CTX *ctx = NULL;
|
||||
const EC_POINT *point = NULL;
|
||||
BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL,
|
||||
*order = NULL, *cofactor = NULL;
|
||||
BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL;
|
||||
const BIGNUM *order = NULL, *cofactor = NULL;
|
||||
const unsigned char *seed;
|
||||
size_t seed_len = 0;
|
||||
|
||||
@@ -179,7 +105,6 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
|
||||
nid = EC_GROUP_get_curve_name(x);
|
||||
if (nid == 0)
|
||||
goto err;
|
||||
|
||||
if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
|
||||
goto err;
|
||||
if (BIO_printf(bp, "\n") <= 0)
|
||||
@@ -201,8 +126,7 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
|
||||
is_char_two = 1;
|
||||
|
||||
if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
|
||||
(b = BN_new()) == NULL || (order = BN_new()) == NULL ||
|
||||
(cofactor = BN_new()) == NULL) {
|
||||
(b = BN_new()) == NULL) {
|
||||
reason = ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
@@ -225,8 +149,9 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
|
||||
reason = ERR_R_EC_LIB;
|
||||
goto err;
|
||||
}
|
||||
if (!EC_GROUP_get_order(x, order, NULL) ||
|
||||
!EC_GROUP_get_cofactor(x, cofactor, NULL)) {
|
||||
order = EC_GROUP_get0_order(x);
|
||||
cofactor = EC_GROUP_get0_cofactor(x);
|
||||
if (order == NULL) {
|
||||
reason = ERR_R_EC_LIB;
|
||||
goto err;
|
||||
}
|
||||
@@ -238,27 +163,9 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
|
||||
goto err;
|
||||
}
|
||||
|
||||
buf_len = (size_t)BN_num_bytes(p);
|
||||
if (buf_len < (i = (size_t)BN_num_bytes(a)))
|
||||
buf_len = i;
|
||||
if (buf_len < (i = (size_t)BN_num_bytes(b)))
|
||||
buf_len = i;
|
||||
if (buf_len < (i = (size_t)BN_num_bytes(gen)))
|
||||
buf_len = i;
|
||||
if (buf_len < (i = (size_t)BN_num_bytes(order)))
|
||||
buf_len = i;
|
||||
if (buf_len < (i = (size_t)BN_num_bytes(cofactor)))
|
||||
buf_len = i;
|
||||
|
||||
if ((seed = EC_GROUP_get0_seed(x)) != NULL)
|
||||
seed_len = EC_GROUP_get_seed_len(x);
|
||||
|
||||
buf_len += 10;
|
||||
if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
|
||||
reason = ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BIO_indent(bp, off, 128))
|
||||
goto err;
|
||||
|
||||
@@ -281,36 +188,36 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
|
||||
goto err;
|
||||
|
||||
/* print the polynomial */
|
||||
if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer,
|
||||
if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, NULL,
|
||||
off))
|
||||
goto err;
|
||||
} else {
|
||||
if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer, off))
|
||||
if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, NULL, off))
|
||||
goto err;
|
||||
}
|
||||
if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off))
|
||||
if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, NULL, off))
|
||||
goto err;
|
||||
if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off))
|
||||
if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, NULL, off))
|
||||
goto err;
|
||||
if (form == POINT_CONVERSION_COMPRESSED) {
|
||||
if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
|
||||
buffer, off))
|
||||
NULL, off))
|
||||
goto err;
|
||||
} else if (form == POINT_CONVERSION_UNCOMPRESSED) {
|
||||
if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
|
||||
buffer, off))
|
||||
NULL, off))
|
||||
goto err;
|
||||
} else { /* form == POINT_CONVERSION_HYBRID */
|
||||
|
||||
if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
|
||||
buffer, off))
|
||||
NULL, off))
|
||||
goto err;
|
||||
}
|
||||
if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order,
|
||||
buffer, off))
|
||||
NULL, off))
|
||||
goto err;
|
||||
if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor,
|
||||
buffer, off))
|
||||
NULL, off))
|
||||
goto err;
|
||||
if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
|
||||
goto err;
|
||||
@@ -319,22 +226,11 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
|
||||
err:
|
||||
if (!ret)
|
||||
ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
|
||||
if (p)
|
||||
BN_free(p);
|
||||
if (a)
|
||||
BN_free(a);
|
||||
if (b)
|
||||
BN_free(b);
|
||||
if (gen)
|
||||
BN_free(gen);
|
||||
if (order)
|
||||
BN_free(order);
|
||||
if (cofactor)
|
||||
BN_free(cofactor);
|
||||
if (ctx)
|
||||
BN_CTX_free(ctx);
|
||||
if (buffer != NULL)
|
||||
OPENSSL_free(buffer);
|
||||
BN_free(p);
|
||||
BN_free(a);
|
||||
BN_free(b);
|
||||
BN_free(gen);
|
||||
BN_CTX_free(ctx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@@ -342,7 +238,7 @@ static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
|
||||
size_t len, int off)
|
||||
{
|
||||
size_t i;
|
||||
char str[128];
|
||||
char str[128 + 1 + 4];
|
||||
|
||||
if (buf == NULL)
|
||||
return 1;
|
||||
|
||||
@@ -1,60 +1,12 @@
|
||||
/* crypto/ec/ecp_mont.c */
|
||||
/*
|
||||
* Originally written by Bodo Moeller for the OpenSSL project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright 2001-2016 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* Portions of this software developed by SUN MICROSYSTEMS, INC.,
|
||||
@@ -63,10 +15,6 @@
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
# include <openssl/fips.h>
|
||||
#endif
|
||||
|
||||
#include "ec_lcl.h"
|
||||
|
||||
const EC_METHOD *EC_GFp_mont_method(void)
|
||||
@@ -81,6 +29,7 @@ const EC_METHOD *EC_GFp_mont_method(void)
|
||||
ec_GFp_mont_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,
|
||||
@@ -108,14 +57,18 @@ const EC_METHOD *EC_GFp_mont_method(void)
|
||||
0 /* field_div */ ,
|
||||
ec_GFp_mont_field_encode,
|
||||
ec_GFp_mont_field_decode,
|
||||
ec_GFp_mont_field_set_to_one
|
||||
ec_GFp_mont_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
|
||||
};
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
if (FIPS_mode())
|
||||
return fips_ec_gfp_mont_method();
|
||||
#endif
|
||||
|
||||
return &ret;
|
||||
}
|
||||
|
||||
@@ -131,40 +84,28 @@ int ec_GFp_mont_group_init(EC_GROUP *group)
|
||||
|
||||
void ec_GFp_mont_group_finish(EC_GROUP *group)
|
||||
{
|
||||
if (group->field_data1 != NULL) {
|
||||
BN_MONT_CTX_free(group->field_data1);
|
||||
group->field_data1 = NULL;
|
||||
}
|
||||
if (group->field_data2 != NULL) {
|
||||
BN_free(group->field_data2);
|
||||
group->field_data2 = NULL;
|
||||
}
|
||||
BN_MONT_CTX_free(group->field_data1);
|
||||
group->field_data1 = NULL;
|
||||
BN_free(group->field_data2);
|
||||
group->field_data2 = NULL;
|
||||
ec_GFp_simple_group_finish(group);
|
||||
}
|
||||
|
||||
void ec_GFp_mont_group_clear_finish(EC_GROUP *group)
|
||||
{
|
||||
if (group->field_data1 != NULL) {
|
||||
BN_MONT_CTX_free(group->field_data1);
|
||||
group->field_data1 = NULL;
|
||||
}
|
||||
if (group->field_data2 != NULL) {
|
||||
BN_clear_free(group->field_data2);
|
||||
group->field_data2 = NULL;
|
||||
}
|
||||
BN_MONT_CTX_free(group->field_data1);
|
||||
group->field_data1 = NULL;
|
||||
BN_clear_free(group->field_data2);
|
||||
group->field_data2 = NULL;
|
||||
ec_GFp_simple_group_clear_finish(group);
|
||||
}
|
||||
|
||||
int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src)
|
||||
{
|
||||
if (dest->field_data1 != NULL) {
|
||||
BN_MONT_CTX_free(dest->field_data1);
|
||||
dest->field_data1 = NULL;
|
||||
}
|
||||
if (dest->field_data2 != NULL) {
|
||||
BN_clear_free(dest->field_data2);
|
||||
dest->field_data2 = NULL;
|
||||
}
|
||||
BN_MONT_CTX_free(dest->field_data1);
|
||||
dest->field_data1 = NULL;
|
||||
BN_clear_free(dest->field_data2);
|
||||
dest->field_data2 = NULL;
|
||||
|
||||
if (!ec_GFp_simple_group_copy(dest, src))
|
||||
return 0;
|
||||
@@ -185,10 +126,8 @@ int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src)
|
||||
return 1;
|
||||
|
||||
err:
|
||||
if (dest->field_data1 != NULL) {
|
||||
BN_MONT_CTX_free(dest->field_data1);
|
||||
dest->field_data1 = NULL;
|
||||
}
|
||||
BN_MONT_CTX_free(dest->field_data1);
|
||||
dest->field_data1 = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -200,14 +139,10 @@ int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
BIGNUM *one = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (group->field_data1 != NULL) {
|
||||
BN_MONT_CTX_free(group->field_data1);
|
||||
group->field_data1 = NULL;
|
||||
}
|
||||
if (group->field_data2 != NULL) {
|
||||
BN_free(group->field_data2);
|
||||
group->field_data2 = NULL;
|
||||
}
|
||||
BN_MONT_CTX_free(group->field_data1);
|
||||
group->field_data1 = NULL;
|
||||
BN_free(group->field_data2);
|
||||
group->field_data2 = NULL;
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
@@ -243,10 +178,9 @@ int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
}
|
||||
|
||||
err:
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
if (mont != NULL)
|
||||
BN_MONT_CTX_free(mont);
|
||||
BN_free(one);
|
||||
BN_CTX_free(new_ctx);
|
||||
BN_MONT_CTX_free(mont);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,60 +1,12 @@
|
||||
/* crypto/ec/ecp_nist.c */
|
||||
/*
|
||||
* Written by Nils Larsch for the OpenSSL project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright 2001-2016 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* Portions of this software developed by SUN MICROSYSTEMS, INC.,
|
||||
@@ -67,10 +19,6 @@
|
||||
#include <openssl/obj_mac.h>
|
||||
#include "ec_lcl.h"
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
# include <openssl/fips.h>
|
||||
#endif
|
||||
|
||||
const EC_METHOD *EC_GFp_nist_method(void)
|
||||
{
|
||||
static const EC_METHOD ret = {
|
||||
@@ -83,6 +31,7 @@ const EC_METHOD *EC_GFp_nist_method(void)
|
||||
ec_GFp_nist_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,
|
||||
@@ -110,14 +59,18 @@ const EC_METHOD *EC_GFp_nist_method(void)
|
||||
0 /* field_div */ ,
|
||||
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
|
||||
};
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
if (FIPS_mode())
|
||||
return fips_ec_gfp_nist_method();
|
||||
#endif
|
||||
|
||||
return &ret;
|
||||
}
|
||||
|
||||
@@ -133,15 +86,12 @@ int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
{
|
||||
int ret = 0;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
BIGNUM *tmp_bn;
|
||||
|
||||
if (ctx == NULL)
|
||||
if ((ctx = new_ctx = BN_CTX_new()) == NULL)
|
||||
return 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
if ((tmp_bn = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
|
||||
group->field_mod_func = BN_nist_mod_192;
|
||||
@@ -162,8 +112,7 @@ int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -183,13 +132,12 @@ int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
|
||||
|
||||
if (!BN_mul(r, a, b, ctx))
|
||||
goto err;
|
||||
if (!group->field_mod_func(r, r, &group->field, ctx))
|
||||
if (!group->field_mod_func(r, r, group->field, ctx))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
if (ctx_new)
|
||||
BN_CTX_free(ctx_new);
|
||||
BN_CTX_free(ctx_new);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -209,12 +157,11 @@ int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
|
||||
|
||||
if (!BN_sqr(r, a, ctx))
|
||||
goto err;
|
||||
if (!group->field_mod_func(r, r, &group->field, ctx))
|
||||
if (!group->field_mod_func(r, r, group->field, ctx))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
if (ctx_new)
|
||||
BN_CTX_free(ctx_new);
|
||||
BN_CTX_free(ctx_new);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
/* crypto/ec/ecp_nistp224.c */
|
||||
/*
|
||||
* Written by Emilia Kasper (Google) for the OpenSSL project.
|
||||
* Copyright 2010-2016 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,14 +31,11 @@
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
|
||||
# ifndef OPENSSL_SYS_VMS
|
||||
# include <stdint.h>
|
||||
# else
|
||||
# include <inttypes.h>
|
||||
# endif
|
||||
#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"
|
||||
@@ -132,84 +134,55 @@ static const felem_bytearray nistp224_curve_params[5] = {
|
||||
* locations when doing simple scalar multiplies against the base point,
|
||||
* and then another four locations using the second 16 elements.
|
||||
*/
|
||||
static const felem gmul[2][16][3] = { {{{0, 0, 0, 0},
|
||||
{0, 0, 0, 0},
|
||||
{0, 0, 0, 0}},
|
||||
{{0x3280d6115c1d21, 0xc1d356c2112234,
|
||||
0x7f321390b94a03, 0xb70e0cbd6bb4bf},
|
||||
{0xd5819985007e34, 0x75a05a07476444,
|
||||
0xfb4c22dfe6cd43, 0xbd376388b5f723},
|
||||
{1, 0, 0, 0}},
|
||||
{{0xfd9675666ebbe9, 0xbca7664d40ce5e,
|
||||
0x2242df8d8a2a43, 0x1f49bbb0f99bc5},
|
||||
{0x29e0b892dc9c43, 0xece8608436e662,
|
||||
0xdc858f185310d0, 0x9812dd4eb8d321},
|
||||
{1, 0, 0, 0}},
|
||||
{{0x6d3e678d5d8eb8, 0x559eed1cb362f1,
|
||||
0x16e9a3bbce8a3f, 0xeedcccd8c2a748},
|
||||
{0xf19f90ed50266d, 0xabf2b4bf65f9df,
|
||||
0x313865468fafec, 0x5cb379ba910a17},
|
||||
{1, 0, 0, 0}},
|
||||
{{0x0641966cab26e3, 0x91fb2991fab0a0,
|
||||
0xefec27a4e13a0b, 0x0499aa8a5f8ebe},
|
||||
{0x7510407766af5d, 0x84d929610d5450,
|
||||
0x81d77aae82f706, 0x6916f6d4338c5b},
|
||||
{1, 0, 0, 0}},
|
||||
{{0xea95ac3b1f15c6, 0x086000905e82d4,
|
||||
0xdd323ae4d1c8b1, 0x932b56be7685a3},
|
||||
{0x9ef93dea25dbbf, 0x41665960f390f0,
|
||||
0xfdec76dbe2a8a7, 0x523e80f019062a},
|
||||
{1, 0, 0, 0}},
|
||||
{{0x822fdd26732c73, 0xa01c83531b5d0f,
|
||||
0x363f37347c1ba4, 0xc391b45c84725c},
|
||||
{0xbbd5e1b2d6ad24, 0xddfbcde19dfaec,
|
||||
0xc393da7e222a7f, 0x1efb7890ede244},
|
||||
{1, 0, 0, 0}},
|
||||
{{0x4c9e90ca217da1, 0xd11beca79159bb,
|
||||
0xff8d33c2c98b7c, 0x2610b39409f849},
|
||||
{0x44d1352ac64da0, 0xcdbb7b2c46b4fb,
|
||||
0x966c079b753c89, 0xfe67e4e820b112},
|
||||
{1, 0, 0, 0}},
|
||||
{{0xe28cae2df5312d, 0xc71b61d16f5c6e,
|
||||
0x79b7619a3e7c4c, 0x05c73240899b47},
|
||||
{0x9f7f6382c73e3a, 0x18615165c56bda,
|
||||
0x641fab2116fd56, 0x72855882b08394},
|
||||
{1, 0, 0, 0}},
|
||||
{{0x0469182f161c09, 0x74a98ca8d00fb5,
|
||||
0xb89da93489a3e0, 0x41c98768fb0c1d},
|
||||
{0xe5ea05fb32da81, 0x3dce9ffbca6855,
|
||||
0x1cfe2d3fbf59e6, 0x0e5e03408738a7},
|
||||
{1, 0, 0, 0}},
|
||||
{{0xdab22b2333e87f, 0x4430137a5dd2f6,
|
||||
0xe03ab9f738beb8, 0xcb0c5d0dc34f24},
|
||||
{0x764a7df0c8fda5, 0x185ba5c3fa2044,
|
||||
0x9281d688bcbe50, 0xc40331df893881},
|
||||
{1, 0, 0, 0}},
|
||||
{{0xb89530796f0f60, 0xade92bd26909a3,
|
||||
0x1a0c83fb4884da, 0x1765bf22a5a984},
|
||||
{0x772a9ee75db09e, 0x23bc6c67cec16f,
|
||||
0x4c1edba8b14e2f, 0xe2a215d9611369},
|
||||
{1, 0, 0, 0}},
|
||||
{{0x571e509fb5efb3, 0xade88696410552,
|
||||
0xc8ae85fada74fe, 0x6c7e4be83bbde3},
|
||||
{0xff9f51160f4652, 0xb47ce2495a6539,
|
||||
0xa2946c53b582f4, 0x286d2db3ee9a60},
|
||||
{1, 0, 0, 0}},
|
||||
{{0x40bbd5081a44af, 0x0995183b13926c,
|
||||
0xbcefba6f47f6d0, 0x215619e9cc0057},
|
||||
{0x8bc94d3b0df45e, 0xf11c54a3694f6f,
|
||||
0x8631b93cdfe8b5, 0xe7e3f4b0982db9},
|
||||
{1, 0, 0, 0}},
|
||||
{{0xb17048ab3e1c7b, 0xac38f36ff8a1d8,
|
||||
0x1c29819435d2c6, 0xc813132f4c07e9},
|
||||
{0x2891425503b11f, 0x08781030579fea,
|
||||
0xf5426ba5cc9674, 0x1e28ebf18562bc},
|
||||
{1, 0, 0, 0}},
|
||||
{{0x9f31997cc864eb, 0x06cd91d28b5e4c,
|
||||
0xff17036691a973, 0xf1aef351497c58},
|
||||
{0xdd1f2d600564ff, 0xdead073b1402db,
|
||||
0x74a684435bd693, 0xeea7471f962558},
|
||||
{1, 0, 0, 0}}},
|
||||
static const felem gmul[2][16][3] = {
|
||||
{{{0, 0, 0, 0},
|
||||
{0, 0, 0, 0},
|
||||
{0, 0, 0, 0}},
|
||||
{{0x3280d6115c1d21, 0xc1d356c2112234, 0x7f321390b94a03, 0xb70e0cbd6bb4bf},
|
||||
{0xd5819985007e34, 0x75a05a07476444, 0xfb4c22dfe6cd43, 0xbd376388b5f723},
|
||||
{1, 0, 0, 0}},
|
||||
{{0xfd9675666ebbe9, 0xbca7664d40ce5e, 0x2242df8d8a2a43, 0x1f49bbb0f99bc5},
|
||||
{0x29e0b892dc9c43, 0xece8608436e662, 0xdc858f185310d0, 0x9812dd4eb8d321},
|
||||
{1, 0, 0, 0}},
|
||||
{{0x6d3e678d5d8eb8, 0x559eed1cb362f1, 0x16e9a3bbce8a3f, 0xeedcccd8c2a748},
|
||||
{0xf19f90ed50266d, 0xabf2b4bf65f9df, 0x313865468fafec, 0x5cb379ba910a17},
|
||||
{1, 0, 0, 0}},
|
||||
{{0x0641966cab26e3, 0x91fb2991fab0a0, 0xefec27a4e13a0b, 0x0499aa8a5f8ebe},
|
||||
{0x7510407766af5d, 0x84d929610d5450, 0x81d77aae82f706, 0x6916f6d4338c5b},
|
||||
{1, 0, 0, 0}},
|
||||
{{0xea95ac3b1f15c6, 0x086000905e82d4, 0xdd323ae4d1c8b1, 0x932b56be7685a3},
|
||||
{0x9ef93dea25dbbf, 0x41665960f390f0, 0xfdec76dbe2a8a7, 0x523e80f019062a},
|
||||
{1, 0, 0, 0}},
|
||||
{{0x822fdd26732c73, 0xa01c83531b5d0f, 0x363f37347c1ba4, 0xc391b45c84725c},
|
||||
{0xbbd5e1b2d6ad24, 0xddfbcde19dfaec, 0xc393da7e222a7f, 0x1efb7890ede244},
|
||||
{1, 0, 0, 0}},
|
||||
{{0x4c9e90ca217da1, 0xd11beca79159bb, 0xff8d33c2c98b7c, 0x2610b39409f849},
|
||||
{0x44d1352ac64da0, 0xcdbb7b2c46b4fb, 0x966c079b753c89, 0xfe67e4e820b112},
|
||||
{1, 0, 0, 0}},
|
||||
{{0xe28cae2df5312d, 0xc71b61d16f5c6e, 0x79b7619a3e7c4c, 0x05c73240899b47},
|
||||
{0x9f7f6382c73e3a, 0x18615165c56bda, 0x641fab2116fd56, 0x72855882b08394},
|
||||
{1, 0, 0, 0}},
|
||||
{{0x0469182f161c09, 0x74a98ca8d00fb5, 0xb89da93489a3e0, 0x41c98768fb0c1d},
|
||||
{0xe5ea05fb32da81, 0x3dce9ffbca6855, 0x1cfe2d3fbf59e6, 0x0e5e03408738a7},
|
||||
{1, 0, 0, 0}},
|
||||
{{0xdab22b2333e87f, 0x4430137a5dd2f6, 0xe03ab9f738beb8, 0xcb0c5d0dc34f24},
|
||||
{0x764a7df0c8fda5, 0x185ba5c3fa2044, 0x9281d688bcbe50, 0xc40331df893881},
|
||||
{1, 0, 0, 0}},
|
||||
{{0xb89530796f0f60, 0xade92bd26909a3, 0x1a0c83fb4884da, 0x1765bf22a5a984},
|
||||
{0x772a9ee75db09e, 0x23bc6c67cec16f, 0x4c1edba8b14e2f, 0xe2a215d9611369},
|
||||
{1, 0, 0, 0}},
|
||||
{{0x571e509fb5efb3, 0xade88696410552, 0xc8ae85fada74fe, 0x6c7e4be83bbde3},
|
||||
{0xff9f51160f4652, 0xb47ce2495a6539, 0xa2946c53b582f4, 0x286d2db3ee9a60},
|
||||
{1, 0, 0, 0}},
|
||||
{{0x40bbd5081a44af, 0x0995183b13926c, 0xbcefba6f47f6d0, 0x215619e9cc0057},
|
||||
{0x8bc94d3b0df45e, 0xf11c54a3694f6f, 0x8631b93cdfe8b5, 0xe7e3f4b0982db9},
|
||||
{1, 0, 0, 0}},
|
||||
{{0xb17048ab3e1c7b, 0xac38f36ff8a1d8, 0x1c29819435d2c6, 0xc813132f4c07e9},
|
||||
{0x2891425503b11f, 0x08781030579fea, 0xf5426ba5cc9674, 0x1e28ebf18562bc},
|
||||
{1, 0, 0, 0}},
|
||||
{{0x9f31997cc864eb, 0x06cd91d28b5e4c, 0xff17036691a973, 0xf1aef351497c58},
|
||||
{0xdd1f2d600564ff, 0xdead073b1402db, 0x74a684435bd693, 0xeea7471f962558},
|
||||
{1, 0, 0, 0}}},
|
||||
{{{0, 0, 0, 0},
|
||||
{0, 0, 0, 0},
|
||||
{0, 0, 0, 0}},
|
||||
@@ -261,10 +234,11 @@ static const felem gmul[2][16][3] = { {{{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
/* Precomputation for the group generator. */
|
||||
typedef struct {
|
||||
struct nistp224_pre_comp_st {
|
||||
felem g_pre_comp[2][16][3];
|
||||
int references;
|
||||
} NISTP224_PRE_COMP;
|
||||
CRYPTO_RWLOCK *lock;
|
||||
};
|
||||
|
||||
const EC_METHOD *EC_GFp_nistp224_method(void)
|
||||
{
|
||||
@@ -278,6 +252,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,
|
||||
@@ -307,7 +282,16 @@ const EC_METHOD *EC_GFp_nistp224_method(void)
|
||||
0 /* field_div */ ,
|
||||
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
|
||||
};
|
||||
|
||||
return &ret;
|
||||
@@ -351,7 +335,7 @@ static int BN_to_felem(felem out, const BIGNUM *bn)
|
||||
unsigned num_bytes;
|
||||
|
||||
/* BN_bn2bin eats leading zeroes */
|
||||
memset(b_out, 0, sizeof b_out);
|
||||
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);
|
||||
@@ -549,11 +533,11 @@ static void felem_mul(widefelem out, const felem in1, const felem in2)
|
||||
out[0] = ((widelimb) in1[0]) * in2[0];
|
||||
out[1] = ((widelimb) in1[0]) * in2[1] + ((widelimb) in1[1]) * in2[0];
|
||||
out[2] = ((widelimb) in1[0]) * in2[2] + ((widelimb) in1[1]) * in2[1] +
|
||||
((widelimb) in1[2]) * in2[0];
|
||||
((widelimb) in1[2]) * in2[0];
|
||||
out[3] = ((widelimb) in1[0]) * in2[3] + ((widelimb) in1[1]) * in2[2] +
|
||||
((widelimb) in1[2]) * in2[1] + ((widelimb) in1[3]) * in2[0];
|
||||
((widelimb) in1[2]) * in2[1] + ((widelimb) in1[3]) * in2[0];
|
||||
out[4] = ((widelimb) in1[1]) * in2[3] + ((widelimb) in1[2]) * in2[2] +
|
||||
((widelimb) in1[3]) * in2[1];
|
||||
((widelimb) in1[3]) * in2[1];
|
||||
out[5] = ((widelimb) in1[2]) * in2[3] + ((widelimb) in1[3]) * in2[2];
|
||||
out[6] = ((widelimb) in1[3]) * in2[3];
|
||||
}
|
||||
@@ -1103,8 +1087,8 @@ static void select_point(const u64 idx, unsigned int size,
|
||||
{
|
||||
unsigned i, j;
|
||||
limb *outlimbs = &out[0][0];
|
||||
memset(outlimbs, 0, 3 * sizeof(felem));
|
||||
|
||||
memset(out, 0, sizeof(*out) * 3);
|
||||
for (i = 0; i < size; i++) {
|
||||
const limb *inlimbs = &pre_comp[i][0][0];
|
||||
u64 mask = i ^ idx;
|
||||
@@ -1147,7 +1131,7 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
|
||||
u8 sign, digit;
|
||||
|
||||
/* set nq to the point at infinity */
|
||||
memset(nq, 0, 3 * sizeof(felem));
|
||||
memset(nq, 0, sizeof(nq));
|
||||
|
||||
/*
|
||||
* Loop over all scalars msb-to-lsb, interleaving additions of multiples
|
||||
@@ -1233,56 +1217,47 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
|
||||
|
||||
static NISTP224_PRE_COMP *nistp224_pre_comp_new()
|
||||
{
|
||||
NISTP224_PRE_COMP *ret = NULL;
|
||||
ret = (NISTP224_PRE_COMP *) OPENSSL_malloc(sizeof *ret);
|
||||
NISTP224_PRE_COMP *ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
|
||||
if (!ret) {
|
||||
ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return ret;
|
||||
}
|
||||
memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static void *nistp224_pre_comp_dup(void *src_)
|
||||
{
|
||||
NISTP224_PRE_COMP *src = src_;
|
||||
|
||||
/* no need to actually copy, these objects never change! */
|
||||
CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
|
||||
|
||||
return src_;
|
||||
}
|
||||
|
||||
static void nistp224_pre_comp_free(void *pre_)
|
||||
NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *p)
|
||||
{
|
||||
int i;
|
||||
NISTP224_PRE_COMP *pre = pre_;
|
||||
|
||||
if (!pre)
|
||||
return;
|
||||
|
||||
i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
|
||||
if (i > 0)
|
||||
return;
|
||||
|
||||
OPENSSL_free(pre);
|
||||
if (p != NULL)
|
||||
CRYPTO_atomic_add(&p->references, 1, &i, p->lock);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void nistp224_pre_comp_clear_free(void *pre_)
|
||||
void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *p)
|
||||
{
|
||||
int i;
|
||||
NISTP224_PRE_COMP *pre = pre_;
|
||||
|
||||
if (!pre)
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
|
||||
CRYPTO_atomic_add(&p->references, -1, &i, p->lock);
|
||||
REF_PRINT_COUNT("EC_nistp224", x);
|
||||
if (i > 0)
|
||||
return;
|
||||
REF_ASSERT_ISNT(i < 0);
|
||||
|
||||
OPENSSL_cleanse(pre, sizeof *pre);
|
||||
OPENSSL_free(pre);
|
||||
CRYPTO_THREAD_lock_free(p->lock);
|
||||
OPENSSL_free(p);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -1326,8 +1301,7 @@ int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1348,8 +1322,8 @@ int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
|
||||
EC_R_POINT_AT_INFINITY);
|
||||
return 0;
|
||||
}
|
||||
if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) ||
|
||||
(!BN_to_felem(z1, &point->Z)))
|
||||
if ((!BN_to_felem(x_in, point->X)) || (!BN_to_felem(y_in, point->Y)) ||
|
||||
(!BN_to_felem(z1, point->Z)))
|
||||
return 0;
|
||||
felem_inv(z2, z1);
|
||||
felem_square(tmp, z2);
|
||||
@@ -1426,7 +1400,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
BIGNUM *x, *y, *z, *tmp_scalar;
|
||||
felem_bytearray g_secret;
|
||||
felem_bytearray *secrets = NULL;
|
||||
felem(*pre_comp)[17][3] = NULL;
|
||||
felem (*pre_comp)[17][3] = NULL;
|
||||
felem *tmp_felems = NULL;
|
||||
felem_bytearray tmp;
|
||||
unsigned num_bytes;
|
||||
@@ -1450,10 +1424,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
goto err;
|
||||
|
||||
if (scalar != NULL) {
|
||||
pre = EC_EX_DATA_get_data(group->extra_data,
|
||||
nistp224_pre_comp_dup,
|
||||
nistp224_pre_comp_free,
|
||||
nistp224_pre_comp_clear_free);
|
||||
pre = group->pre_comp.nistp224;
|
||||
if (pre)
|
||||
/* we have precomputation, try to use it */
|
||||
g_pre_comp = (const felem(*)[16][3])pre->g_pre_comp;
|
||||
@@ -1493,11 +1464,11 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
*/
|
||||
mixed = 1;
|
||||
}
|
||||
secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
|
||||
pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem));
|
||||
secrets = OPENSSL_zalloc(sizeof(*secrets) * num_points);
|
||||
pre_comp = OPENSSL_zalloc(sizeof(*pre_comp) * num_points);
|
||||
if (mixed)
|
||||
tmp_felems =
|
||||
OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem));
|
||||
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);
|
||||
@@ -1508,8 +1479,6 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
* we treat NULL scalars as 0, and NULL points as points at infinity,
|
||||
* i.e., they contribute nothing to the linear combination
|
||||
*/
|
||||
memset(secrets, 0, num_points * sizeof(felem_bytearray));
|
||||
memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem));
|
||||
for (i = 0; i < num_points; ++i) {
|
||||
if (i == num)
|
||||
/* the generator */
|
||||
@@ -1530,7 +1499,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
* this is an unusual input, and we don't guarantee
|
||||
* constant-timeness
|
||||
*/
|
||||
if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) {
|
||||
if (!BN_nnmod(tmp_scalar, p_scalar, group->order, ctx)) {
|
||||
ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
@@ -1539,9 +1508,9 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
num_bytes = BN_bn2bin(p_scalar, tmp);
|
||||
flip_endian(secrets[i], tmp, num_bytes);
|
||||
/* precompute multiples */
|
||||
if ((!BN_to_felem(x_out, &p->X)) ||
|
||||
(!BN_to_felem(y_out, &p->Y)) ||
|
||||
(!BN_to_felem(z_out, &p->Z)))
|
||||
if ((!BN_to_felem(x_out, p->X)) ||
|
||||
(!BN_to_felem(y_out, p->Y)) ||
|
||||
(!BN_to_felem(z_out, p->Z)))
|
||||
goto err;
|
||||
felem_assign(pre_comp[i][1][0], x_out);
|
||||
felem_assign(pre_comp[i][1][1], y_out);
|
||||
@@ -1569,14 +1538,14 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
|
||||
/* the scalar for the generator */
|
||||
if ((scalar != NULL) && (have_pre_comp)) {
|
||||
memset(g_secret, 0, sizeof g_secret);
|
||||
memset(g_secret, 0, sizeof(g_secret));
|
||||
/* reduce scalar to 0 <= scalar < 2^224 */
|
||||
if ((BN_num_bits(scalar) > 224) || (BN_is_negative(scalar))) {
|
||||
/*
|
||||
* this is an unusual input, and we don't guarantee
|
||||
* constant-timeness
|
||||
*/
|
||||
if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
|
||||
if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) {
|
||||
ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
@@ -1607,16 +1576,11 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
if (generator != NULL)
|
||||
EC_POINT_free(generator);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
if (secrets != NULL)
|
||||
OPENSSL_free(secrets);
|
||||
if (pre_comp != NULL)
|
||||
OPENSSL_free(pre_comp);
|
||||
if (tmp_felems != NULL)
|
||||
OPENSSL_free(tmp_felems);
|
||||
EC_POINT_free(generator);
|
||||
BN_CTX_free(new_ctx);
|
||||
OPENSSL_free(secrets);
|
||||
OPENSSL_free(pre_comp);
|
||||
OPENSSL_free(tmp_felems);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1631,9 +1595,7 @@ int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
felem tmp_felems[32];
|
||||
|
||||
/* throw away old precomputation */
|
||||
EC_EX_DATA_free_data(&group->extra_data, nistp224_pre_comp_dup,
|
||||
nistp224_pre_comp_free,
|
||||
nistp224_pre_comp_clear_free);
|
||||
EC_pre_comp_free(group);
|
||||
if (ctx == NULL)
|
||||
if ((ctx = new_ctx = BN_CTX_new()) == NULL)
|
||||
return 0;
|
||||
@@ -1659,9 +1621,9 @@ int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
|
||||
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)) ||
|
||||
(!BN_to_felem(pre->g_pre_comp[0][1][2], &group->generator->Z)))
|
||||
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)) ||
|
||||
(!BN_to_felem(pre->g_pre_comp[0][1][2], group->generator->Z)))
|
||||
goto err;
|
||||
/*
|
||||
* compute 2^56*G, 2^112*G, 2^168*G for the first table, 2^28*G, 2^84*G,
|
||||
@@ -1736,34 +1698,20 @@ 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:
|
||||
if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp224_pre_comp_dup,
|
||||
nistp224_pre_comp_free,
|
||||
nistp224_pre_comp_clear_free))
|
||||
goto err;
|
||||
ret = 1;
|
||||
SETPRECOMP(group, nistp224, pre);
|
||||
pre = NULL;
|
||||
ret = 1;
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
if (generator != NULL)
|
||||
EC_POINT_free(generator);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
if (pre)
|
||||
nistp224_pre_comp_free(pre);
|
||||
EC_POINT_free(generator);
|
||||
BN_CTX_free(new_ctx);
|
||||
EC_nistp224_pre_comp_free(pre);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group)
|
||||
{
|
||||
if (EC_EX_DATA_get_data(group->extra_data, nistp224_pre_comp_dup,
|
||||
nistp224_pre_comp_free,
|
||||
nistp224_pre_comp_clear_free)
|
||||
!= NULL)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
return HAVEPRECOMP(group, nistp224);
|
||||
}
|
||||
|
||||
#else
|
||||
static void *dummy = &dummy;
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
/* crypto/ec/ecp_nistp256.c */
|
||||
/*
|
||||
* Written by Adam Langley (Google) for the OpenSSL project
|
||||
* Copyright 2011-2016 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");
|
||||
@@ -27,14 +32,11 @@
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
|
||||
# ifndef OPENSSL_SYS_VMS
|
||||
# include <stdint.h>
|
||||
# else
|
||||
# include <inttypes.h>
|
||||
# endif
|
||||
#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"
|
||||
@@ -161,7 +163,7 @@ static int BN_to_felem(felem out, const BIGNUM *bn)
|
||||
unsigned num_bytes;
|
||||
|
||||
/* BN_bn2bin eats leading zeroes */
|
||||
memset(b_out, 0, sizeof b_out);
|
||||
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);
|
||||
@@ -1232,7 +1234,7 @@ static void copy_small_conditional(felem out, const smallfelem in, limb mask)
|
||||
}
|
||||
|
||||
/*-
|
||||
* point_add calcuates (x1, y1, z1) + (x2, y2, z2)
|
||||
* point_add calculates (x1, y1, z1) + (x2, y2, z2)
|
||||
*
|
||||
* The method is taken from:
|
||||
* http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
|
||||
@@ -1629,7 +1631,8 @@ static void select_point(const u64 idx, unsigned int size,
|
||||
{
|
||||
unsigned i, j;
|
||||
u64 *outlimbs = &out[0][0];
|
||||
memset(outlimbs, 0, 3 * sizeof(smallfelem));
|
||||
|
||||
memset(out, 0, sizeof(*out) * 3);
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
const u64 *inlimbs = (u64 *)&pre_comp[i][0][0];
|
||||
@@ -1673,7 +1676,7 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
|
||||
u8 sign, digit;
|
||||
|
||||
/* set nq to the point at infinity */
|
||||
memset(nq, 0, 3 * sizeof(felem));
|
||||
memset(nq, 0, sizeof(nq));
|
||||
|
||||
/*
|
||||
* Loop over all scalars msb-to-lsb, interleaving additions of multiples
|
||||
@@ -1760,10 +1763,11 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
|
||||
}
|
||||
|
||||
/* Precomputation for the group generator. */
|
||||
typedef struct {
|
||||
struct nistp256_pre_comp_st {
|
||||
smallfelem g_pre_comp[2][16][3];
|
||||
int references;
|
||||
} NISTP256_PRE_COMP;
|
||||
CRYPTO_RWLOCK *lock;
|
||||
};
|
||||
|
||||
const EC_METHOD *EC_GFp_nistp256_method(void)
|
||||
{
|
||||
@@ -1777,6 +1781,7 @@ const EC_METHOD *EC_GFp_nistp256_method(void)
|
||||
ec_GFp_nistp256_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,
|
||||
@@ -1806,7 +1811,16 @@ const EC_METHOD *EC_GFp_nistp256_method(void)
|
||||
0 /* field_div */ ,
|
||||
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
|
||||
};
|
||||
|
||||
return &ret;
|
||||
@@ -1819,55 +1833,46 @@ const EC_METHOD *EC_GFp_nistp256_method(void)
|
||||
|
||||
static NISTP256_PRE_COMP *nistp256_pre_comp_new()
|
||||
{
|
||||
NISTP256_PRE_COMP *ret = NULL;
|
||||
ret = (NISTP256_PRE_COMP *) OPENSSL_malloc(sizeof *ret);
|
||||
if (!ret) {
|
||||
NISTP256_PRE_COMP *ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
|
||||
if (ret == NULL) {
|
||||
ECerr(EC_F_NISTP256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return ret;
|
||||
}
|
||||
memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp));
|
||||
|
||||
ret->references = 1;
|
||||
|
||||
ret->lock = CRYPTO_THREAD_lock_new();
|
||||
if (ret->lock == NULL) {
|
||||
ECerr(EC_F_NISTP256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *nistp256_pre_comp_dup(void *src_)
|
||||
{
|
||||
NISTP256_PRE_COMP *src = src_;
|
||||
|
||||
/* no need to actually copy, these objects never change! */
|
||||
CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
|
||||
|
||||
return src_;
|
||||
}
|
||||
|
||||
static void nistp256_pre_comp_free(void *pre_)
|
||||
NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *p)
|
||||
{
|
||||
int i;
|
||||
NISTP256_PRE_COMP *pre = pre_;
|
||||
|
||||
if (!pre)
|
||||
return;
|
||||
|
||||
i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
|
||||
if (i > 0)
|
||||
return;
|
||||
|
||||
OPENSSL_free(pre);
|
||||
if (p != NULL)
|
||||
CRYPTO_atomic_add(&p->references, 1, &i, p->lock);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void nistp256_pre_comp_clear_free(void *pre_)
|
||||
void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *pre)
|
||||
{
|
||||
int i;
|
||||
NISTP256_PRE_COMP *pre = pre_;
|
||||
|
||||
if (!pre)
|
||||
if (pre == NULL)
|
||||
return;
|
||||
|
||||
i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
|
||||
CRYPTO_atomic_add(&pre->references, -1, &i, pre->lock);
|
||||
REF_PRINT_COUNT("EC_nistp256", x);
|
||||
if (i > 0)
|
||||
return;
|
||||
REF_ASSERT_ISNT(i < 0);
|
||||
|
||||
OPENSSL_cleanse(pre, sizeof *pre);
|
||||
CRYPTO_THREAD_lock_free(pre->lock);
|
||||
OPENSSL_free(pre);
|
||||
}
|
||||
|
||||
@@ -1912,8 +1917,7 @@ int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1935,8 +1939,8 @@ int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
|
||||
EC_R_POINT_AT_INFINITY);
|
||||
return 0;
|
||||
}
|
||||
if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) ||
|
||||
(!BN_to_felem(z1, &point->Z)))
|
||||
if ((!BN_to_felem(x_in, point->X)) || (!BN_to_felem(y_in, point->Y)) ||
|
||||
(!BN_to_felem(z1, point->Z)))
|
||||
return 0;
|
||||
felem_inv(z2, z1);
|
||||
felem_square(tmp, z2);
|
||||
@@ -2012,7 +2016,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
BIGNUM *x, *y, *z, *tmp_scalar;
|
||||
felem_bytearray g_secret;
|
||||
felem_bytearray *secrets = NULL;
|
||||
smallfelem(*pre_comp)[17][3] = NULL;
|
||||
smallfelem (*pre_comp)[17][3] = NULL;
|
||||
smallfelem *tmp_smallfelems = NULL;
|
||||
felem_bytearray tmp;
|
||||
unsigned i, num_bytes;
|
||||
@@ -2037,10 +2041,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
goto err;
|
||||
|
||||
if (scalar != NULL) {
|
||||
pre = EC_EX_DATA_get_data(group->extra_data,
|
||||
nistp256_pre_comp_dup,
|
||||
nistp256_pre_comp_free,
|
||||
nistp256_pre_comp_clear_free);
|
||||
pre = group->pre_comp.nistp256;
|
||||
if (pre)
|
||||
/* we have precomputation, try to use it */
|
||||
g_pre_comp = (const smallfelem(*)[16][3])pre->g_pre_comp;
|
||||
@@ -2079,11 +2080,11 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
*/
|
||||
mixed = 1;
|
||||
}
|
||||
secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
|
||||
pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(smallfelem));
|
||||
secrets = OPENSSL_malloc(sizeof(*secrets) * num_points);
|
||||
pre_comp = OPENSSL_malloc(sizeof(*pre_comp) * num_points);
|
||||
if (mixed)
|
||||
tmp_smallfelems =
|
||||
OPENSSL_malloc((num_points * 17 + 1) * sizeof(smallfelem));
|
||||
OPENSSL_malloc(sizeof(*tmp_smallfelems) * (num_points * 17 + 1));
|
||||
if ((secrets == NULL) || (pre_comp == NULL)
|
||||
|| (mixed && (tmp_smallfelems == NULL))) {
|
||||
ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_MALLOC_FAILURE);
|
||||
@@ -2094,8 +2095,8 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
* we treat NULL scalars as 0, and NULL points as points at infinity,
|
||||
* i.e., they contribute nothing to the linear combination
|
||||
*/
|
||||
memset(secrets, 0, num_points * sizeof(felem_bytearray));
|
||||
memset(pre_comp, 0, num_points * 17 * 3 * sizeof(smallfelem));
|
||||
memset(secrets, 0, sizeof(*secrets) * num_points);
|
||||
memset(pre_comp, 0, sizeof(*pre_comp) * num_points);
|
||||
for (i = 0; i < num_points; ++i) {
|
||||
if (i == num)
|
||||
/*
|
||||
@@ -2119,7 +2120,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
* this is an unusual input, and we don't guarantee
|
||||
* constant-timeness
|
||||
*/
|
||||
if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) {
|
||||
if (!BN_nnmod(tmp_scalar, p_scalar, group->order, ctx)) {
|
||||
ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
@@ -2128,9 +2129,9 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
num_bytes = BN_bn2bin(p_scalar, tmp);
|
||||
flip_endian(secrets[i], tmp, num_bytes);
|
||||
/* precompute multiples */
|
||||
if ((!BN_to_felem(x_out, &p->X)) ||
|
||||
(!BN_to_felem(y_out, &p->Y)) ||
|
||||
(!BN_to_felem(z_out, &p->Z)))
|
||||
if ((!BN_to_felem(x_out, p->X)) ||
|
||||
(!BN_to_felem(y_out, p->Y)) ||
|
||||
(!BN_to_felem(z_out, p->Z)))
|
||||
goto err;
|
||||
felem_shrink(pre_comp[i][1][0], x_out);
|
||||
felem_shrink(pre_comp[i][1][1], y_out);
|
||||
@@ -2167,7 +2168,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
* this is an unusual input, and we don't guarantee
|
||||
* constant-timeness
|
||||
*/
|
||||
if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
|
||||
if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) {
|
||||
ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
@@ -2198,16 +2199,11 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
if (generator != NULL)
|
||||
EC_POINT_free(generator);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
if (secrets != NULL)
|
||||
OPENSSL_free(secrets);
|
||||
if (pre_comp != NULL)
|
||||
OPENSSL_free(pre_comp);
|
||||
if (tmp_smallfelems != NULL)
|
||||
OPENSSL_free(tmp_smallfelems);
|
||||
EC_POINT_free(generator);
|
||||
BN_CTX_free(new_ctx);
|
||||
OPENSSL_free(secrets);
|
||||
OPENSSL_free(pre_comp);
|
||||
OPENSSL_free(tmp_smallfelems);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2223,9 +2219,7 @@ int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
felem x_tmp, y_tmp, z_tmp;
|
||||
|
||||
/* throw away old precomputation */
|
||||
EC_EX_DATA_free_data(&group->extra_data, nistp256_pre_comp_dup,
|
||||
nistp256_pre_comp_free,
|
||||
nistp256_pre_comp_clear_free);
|
||||
EC_pre_comp_free(group);
|
||||
if (ctx == NULL)
|
||||
if ((ctx = new_ctx = BN_CTX_new()) == NULL)
|
||||
return 0;
|
||||
@@ -2251,9 +2245,9 @@ int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
|
||||
goto done;
|
||||
}
|
||||
if ((!BN_to_felem(x_tmp, &group->generator->X)) ||
|
||||
(!BN_to_felem(y_tmp, &group->generator->Y)) ||
|
||||
(!BN_to_felem(z_tmp, &group->generator->Z)))
|
||||
if ((!BN_to_felem(x_tmp, group->generator->X)) ||
|
||||
(!BN_to_felem(y_tmp, group->generator->Y)) ||
|
||||
(!BN_to_felem(z_tmp, group->generator->Z)))
|
||||
goto err;
|
||||
felem_shrink(pre->g_pre_comp[0][1][0], x_tmp);
|
||||
felem_shrink(pre->g_pre_comp[0][1][1], y_tmp);
|
||||
@@ -2337,33 +2331,20 @@ int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_smallfelems);
|
||||
|
||||
done:
|
||||
if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp256_pre_comp_dup,
|
||||
nistp256_pre_comp_free,
|
||||
nistp256_pre_comp_clear_free))
|
||||
goto err;
|
||||
ret = 1;
|
||||
SETPRECOMP(group, nistp256, pre);
|
||||
pre = NULL;
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
if (generator != NULL)
|
||||
EC_POINT_free(generator);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
if (pre)
|
||||
nistp256_pre_comp_free(pre);
|
||||
EC_POINT_free(generator);
|
||||
BN_CTX_free(new_ctx);
|
||||
EC_nistp256_pre_comp_free(pre);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group)
|
||||
{
|
||||
if (EC_EX_DATA_get_data(group->extra_data, nistp256_pre_comp_dup,
|
||||
nistp256_pre_comp_free,
|
||||
nistp256_pre_comp_clear_free)
|
||||
!= NULL)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
return HAVEPRECOMP(group, nistp256);
|
||||
}
|
||||
#else
|
||||
static void *dummy = &dummy;
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
/* crypto/ec/ecp_nistp521.c */
|
||||
/*
|
||||
* Written by Adam Langley (Google) for the OpenSSL project
|
||||
* Copyright 2011-2016 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,14 +31,10 @@
|
||||
* work which got its smarts from Daniel J. Bernstein's work on the same.
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
|
||||
# ifndef OPENSSL_SYS_VMS
|
||||
# include <stdint.h>
|
||||
# else
|
||||
# include <inttypes.h>
|
||||
# endif
|
||||
#include <openssl/e_os2.h>
|
||||
#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
|
||||
# include <string.h>
|
||||
# include <openssl/err.h>
|
||||
@@ -185,7 +186,7 @@ static int BN_to_felem(felem out, const BIGNUM *bn)
|
||||
unsigned num_bytes;
|
||||
|
||||
/* BN_bn2bin eats leading zeroes */
|
||||
memset(b_out, 0, sizeof b_out);
|
||||
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);
|
||||
@@ -430,19 +431,19 @@ static void felem_square(largefelem out, const felem in)
|
||||
out[2] = ((uint128_t) in[0]) * inx2[2] + ((uint128_t) in[1]) * in[1];
|
||||
out[3] = ((uint128_t) in[0]) * inx2[3] + ((uint128_t) in[1]) * inx2[2];
|
||||
out[4] = ((uint128_t) in[0]) * inx2[4] +
|
||||
((uint128_t) in[1]) * inx2[3] + ((uint128_t) in[2]) * in[2];
|
||||
((uint128_t) in[1]) * inx2[3] + ((uint128_t) in[2]) * in[2];
|
||||
out[5] = ((uint128_t) in[0]) * inx2[5] +
|
||||
((uint128_t) in[1]) * inx2[4] + ((uint128_t) in[2]) * inx2[3];
|
||||
((uint128_t) in[1]) * inx2[4] + ((uint128_t) in[2]) * inx2[3];
|
||||
out[6] = ((uint128_t) in[0]) * inx2[6] +
|
||||
((uint128_t) in[1]) * inx2[5] +
|
||||
((uint128_t) in[2]) * inx2[4] + ((uint128_t) in[3]) * in[3];
|
||||
((uint128_t) in[1]) * inx2[5] +
|
||||
((uint128_t) in[2]) * inx2[4] + ((uint128_t) in[3]) * in[3];
|
||||
out[7] = ((uint128_t) in[0]) * inx2[7] +
|
||||
((uint128_t) in[1]) * inx2[6] +
|
||||
((uint128_t) in[2]) * inx2[5] + ((uint128_t) in[3]) * inx2[4];
|
||||
((uint128_t) in[1]) * inx2[6] +
|
||||
((uint128_t) in[2]) * inx2[5] + ((uint128_t) in[3]) * inx2[4];
|
||||
out[8] = ((uint128_t) in[0]) * inx2[8] +
|
||||
((uint128_t) in[1]) * inx2[7] +
|
||||
((uint128_t) in[2]) * inx2[6] +
|
||||
((uint128_t) in[3]) * inx2[5] + ((uint128_t) in[4]) * in[4];
|
||||
((uint128_t) in[1]) * inx2[7] +
|
||||
((uint128_t) in[2]) * inx2[6] +
|
||||
((uint128_t) in[3]) * inx2[5] + ((uint128_t) in[4]) * in[4];
|
||||
|
||||
/*
|
||||
* The remaining limbs fall above 2^521, with the first falling at 2^522.
|
||||
@@ -455,21 +456,21 @@ static void felem_square(largefelem out, const felem in)
|
||||
|
||||
/* 9 */
|
||||
out[0] += ((uint128_t) in[1]) * inx4[8] +
|
||||
((uint128_t) in[2]) * inx4[7] +
|
||||
((uint128_t) in[3]) * inx4[6] + ((uint128_t) in[4]) * inx4[5];
|
||||
((uint128_t) in[2]) * inx4[7] +
|
||||
((uint128_t) in[3]) * inx4[6] + ((uint128_t) in[4]) * inx4[5];
|
||||
|
||||
/* 10 */
|
||||
out[1] += ((uint128_t) in[2]) * inx4[8] +
|
||||
((uint128_t) in[3]) * inx4[7] +
|
||||
((uint128_t) in[4]) * inx4[6] + ((uint128_t) in[5]) * inx2[5];
|
||||
((uint128_t) in[3]) * inx4[7] +
|
||||
((uint128_t) in[4]) * inx4[6] + ((uint128_t) in[5]) * inx2[5];
|
||||
|
||||
/* 11 */
|
||||
out[2] += ((uint128_t) in[3]) * inx4[8] +
|
||||
((uint128_t) in[4]) * inx4[7] + ((uint128_t) in[5]) * inx4[6];
|
||||
((uint128_t) in[4]) * inx4[7] + ((uint128_t) in[5]) * inx4[6];
|
||||
|
||||
/* 12 */
|
||||
out[3] += ((uint128_t) in[4]) * inx4[8] +
|
||||
((uint128_t) in[5]) * inx4[7] + ((uint128_t) in[6]) * inx2[6];
|
||||
((uint128_t) in[5]) * inx4[7] + ((uint128_t) in[6]) * inx2[6];
|
||||
|
||||
/* 13 */
|
||||
out[4] += ((uint128_t) in[5]) * inx4[8] + ((uint128_t) in[6]) * inx4[7];
|
||||
@@ -499,87 +500,101 @@ static void felem_mul(largefelem out, const felem in1, const felem in2)
|
||||
|
||||
out[0] = ((uint128_t) in1[0]) * in2[0];
|
||||
|
||||
out[1] = ((uint128_t) in1[0]) * in2[1] + ((uint128_t) in1[1]) * in2[0];
|
||||
out[1] = ((uint128_t) in1[0]) * in2[1] +
|
||||
((uint128_t) in1[1]) * in2[0];
|
||||
|
||||
out[2] = ((uint128_t) in1[0]) * in2[2] +
|
||||
((uint128_t) in1[1]) * in2[1] + ((uint128_t) in1[2]) * in2[0];
|
||||
((uint128_t) in1[1]) * in2[1] +
|
||||
((uint128_t) in1[2]) * in2[0];
|
||||
|
||||
out[3] = ((uint128_t) in1[0]) * in2[3] +
|
||||
((uint128_t) in1[1]) * in2[2] +
|
||||
((uint128_t) in1[2]) * in2[1] + ((uint128_t) in1[3]) * in2[0];
|
||||
((uint128_t) in1[1]) * in2[2] +
|
||||
((uint128_t) in1[2]) * in2[1] +
|
||||
((uint128_t) in1[3]) * in2[0];
|
||||
|
||||
out[4] = ((uint128_t) in1[0]) * in2[4] +
|
||||
((uint128_t) in1[1]) * in2[3] +
|
||||
((uint128_t) in1[2]) * in2[2] +
|
||||
((uint128_t) in1[3]) * in2[1] + ((uint128_t) in1[4]) * in2[0];
|
||||
((uint128_t) in1[1]) * in2[3] +
|
||||
((uint128_t) in1[2]) * in2[2] +
|
||||
((uint128_t) in1[3]) * in2[1] +
|
||||
((uint128_t) in1[4]) * in2[0];
|
||||
|
||||
out[5] = ((uint128_t) in1[0]) * in2[5] +
|
||||
((uint128_t) in1[1]) * in2[4] +
|
||||
((uint128_t) in1[2]) * in2[3] +
|
||||
((uint128_t) in1[3]) * in2[2] +
|
||||
((uint128_t) in1[4]) * in2[1] + ((uint128_t) in1[5]) * in2[0];
|
||||
((uint128_t) in1[1]) * in2[4] +
|
||||
((uint128_t) in1[2]) * in2[3] +
|
||||
((uint128_t) in1[3]) * in2[2] +
|
||||
((uint128_t) in1[4]) * in2[1] +
|
||||
((uint128_t) in1[5]) * in2[0];
|
||||
|
||||
out[6] = ((uint128_t) in1[0]) * in2[6] +
|
||||
((uint128_t) in1[1]) * in2[5] +
|
||||
((uint128_t) in1[2]) * in2[4] +
|
||||
((uint128_t) in1[3]) * in2[3] +
|
||||
((uint128_t) in1[4]) * in2[2] +
|
||||
((uint128_t) in1[5]) * in2[1] + ((uint128_t) in1[6]) * in2[0];
|
||||
((uint128_t) in1[1]) * in2[5] +
|
||||
((uint128_t) in1[2]) * in2[4] +
|
||||
((uint128_t) in1[3]) * in2[3] +
|
||||
((uint128_t) in1[4]) * in2[2] +
|
||||
((uint128_t) in1[5]) * in2[1] +
|
||||
((uint128_t) in1[6]) * in2[0];
|
||||
|
||||
out[7] = ((uint128_t) in1[0]) * in2[7] +
|
||||
((uint128_t) in1[1]) * in2[6] +
|
||||
((uint128_t) in1[2]) * in2[5] +
|
||||
((uint128_t) in1[3]) * in2[4] +
|
||||
((uint128_t) in1[4]) * in2[3] +
|
||||
((uint128_t) in1[5]) * in2[2] +
|
||||
((uint128_t) in1[6]) * in2[1] + ((uint128_t) in1[7]) * in2[0];
|
||||
((uint128_t) in1[1]) * in2[6] +
|
||||
((uint128_t) in1[2]) * in2[5] +
|
||||
((uint128_t) in1[3]) * in2[4] +
|
||||
((uint128_t) in1[4]) * in2[3] +
|
||||
((uint128_t) in1[5]) * in2[2] +
|
||||
((uint128_t) in1[6]) * in2[1] +
|
||||
((uint128_t) in1[7]) * in2[0];
|
||||
|
||||
out[8] = ((uint128_t) in1[0]) * in2[8] +
|
||||
((uint128_t) in1[1]) * in2[7] +
|
||||
((uint128_t) in1[2]) * in2[6] +
|
||||
((uint128_t) in1[3]) * in2[5] +
|
||||
((uint128_t) in1[4]) * in2[4] +
|
||||
((uint128_t) in1[5]) * in2[3] +
|
||||
((uint128_t) in1[6]) * in2[2] +
|
||||
((uint128_t) in1[7]) * in2[1] + ((uint128_t) in1[8]) * in2[0];
|
||||
((uint128_t) in1[1]) * in2[7] +
|
||||
((uint128_t) in1[2]) * in2[6] +
|
||||
((uint128_t) in1[3]) * in2[5] +
|
||||
((uint128_t) in1[4]) * in2[4] +
|
||||
((uint128_t) in1[5]) * in2[3] +
|
||||
((uint128_t) in1[6]) * in2[2] +
|
||||
((uint128_t) in1[7]) * in2[1] +
|
||||
((uint128_t) in1[8]) * in2[0];
|
||||
|
||||
/* See comment in felem_square about the use of in2x2 here */
|
||||
|
||||
out[0] += ((uint128_t) in1[1]) * in2x2[8] +
|
||||
((uint128_t) in1[2]) * in2x2[7] +
|
||||
((uint128_t) in1[3]) * in2x2[6] +
|
||||
((uint128_t) in1[4]) * in2x2[5] +
|
||||
((uint128_t) in1[5]) * in2x2[4] +
|
||||
((uint128_t) in1[6]) * in2x2[3] +
|
||||
((uint128_t) in1[7]) * in2x2[2] + ((uint128_t) in1[8]) * in2x2[1];
|
||||
((uint128_t) in1[2]) * in2x2[7] +
|
||||
((uint128_t) in1[3]) * in2x2[6] +
|
||||
((uint128_t) in1[4]) * in2x2[5] +
|
||||
((uint128_t) in1[5]) * in2x2[4] +
|
||||
((uint128_t) in1[6]) * in2x2[3] +
|
||||
((uint128_t) in1[7]) * in2x2[2] +
|
||||
((uint128_t) in1[8]) * in2x2[1];
|
||||
|
||||
out[1] += ((uint128_t) in1[2]) * in2x2[8] +
|
||||
((uint128_t) in1[3]) * in2x2[7] +
|
||||
((uint128_t) in1[4]) * in2x2[6] +
|
||||
((uint128_t) in1[5]) * in2x2[5] +
|
||||
((uint128_t) in1[6]) * in2x2[4] +
|
||||
((uint128_t) in1[7]) * in2x2[3] + ((uint128_t) in1[8]) * in2x2[2];
|
||||
((uint128_t) in1[3]) * in2x2[7] +
|
||||
((uint128_t) in1[4]) * in2x2[6] +
|
||||
((uint128_t) in1[5]) * in2x2[5] +
|
||||
((uint128_t) in1[6]) * in2x2[4] +
|
||||
((uint128_t) in1[7]) * in2x2[3] +
|
||||
((uint128_t) in1[8]) * in2x2[2];
|
||||
|
||||
out[2] += ((uint128_t) in1[3]) * in2x2[8] +
|
||||
((uint128_t) in1[4]) * in2x2[7] +
|
||||
((uint128_t) in1[5]) * in2x2[6] +
|
||||
((uint128_t) in1[6]) * in2x2[5] +
|
||||
((uint128_t) in1[7]) * in2x2[4] + ((uint128_t) in1[8]) * in2x2[3];
|
||||
((uint128_t) in1[4]) * in2x2[7] +
|
||||
((uint128_t) in1[5]) * in2x2[6] +
|
||||
((uint128_t) in1[6]) * in2x2[5] +
|
||||
((uint128_t) in1[7]) * in2x2[4] +
|
||||
((uint128_t) in1[8]) * in2x2[3];
|
||||
|
||||
out[3] += ((uint128_t) in1[4]) * in2x2[8] +
|
||||
((uint128_t) in1[5]) * in2x2[7] +
|
||||
((uint128_t) in1[6]) * in2x2[6] +
|
||||
((uint128_t) in1[7]) * in2x2[5] + ((uint128_t) in1[8]) * in2x2[4];
|
||||
((uint128_t) in1[5]) * in2x2[7] +
|
||||
((uint128_t) in1[6]) * in2x2[6] +
|
||||
((uint128_t) in1[7]) * in2x2[5] +
|
||||
((uint128_t) in1[8]) * in2x2[4];
|
||||
|
||||
out[4] += ((uint128_t) in1[5]) * in2x2[8] +
|
||||
((uint128_t) in1[6]) * in2x2[7] +
|
||||
((uint128_t) in1[7]) * in2x2[6] + ((uint128_t) in1[8]) * in2x2[5];
|
||||
((uint128_t) in1[6]) * in2x2[7] +
|
||||
((uint128_t) in1[7]) * in2x2[6] +
|
||||
((uint128_t) in1[8]) * in2x2[5];
|
||||
|
||||
out[5] += ((uint128_t) in1[6]) * in2x2[8] +
|
||||
((uint128_t) in1[7]) * in2x2[7] + ((uint128_t) in1[8]) * in2x2[6];
|
||||
((uint128_t) in1[7]) * in2x2[7] +
|
||||
((uint128_t) in1[8]) * in2x2[6];
|
||||
|
||||
out[6] += ((uint128_t) in1[7]) * in2x2[8] +
|
||||
((uint128_t) in1[8]) * in2x2[7];
|
||||
((uint128_t) in1[8]) * in2x2[7];
|
||||
|
||||
out[7] += ((uint128_t) in1[8]) * in2x2[8];
|
||||
}
|
||||
@@ -1019,7 +1034,7 @@ static void felem_contract(felem out, const felem in)
|
||||
* coordinates */
|
||||
|
||||
/*-
|
||||
* point_double calcuates 2*(x_in, y_in, z_in)
|
||||
* point_double calculates 2*(x_in, y_in, z_in)
|
||||
*
|
||||
* The method is taken from:
|
||||
* http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
|
||||
@@ -1135,7 +1150,7 @@ static void copy_conditional(felem out, const felem in, limb mask)
|
||||
}
|
||||
|
||||
/*-
|
||||
* point_add calcuates (x1, y1, z1) + (x2, y2, z2)
|
||||
* point_add calculates (x1, y1, z1) + (x2, y2, z2)
|
||||
*
|
||||
* The method is taken from
|
||||
* http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
|
||||
@@ -1335,9 +1350,10 @@ static void point_add(felem x3, felem y3, felem z3,
|
||||
* Tables for other points have table[i] = iG for i in 0 .. 16. */
|
||||
|
||||
/* gmul is the table of precomputed base points */
|
||||
static const felem gmul[16][3] = { {{0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0}},
|
||||
static const felem gmul[16][3] = {
|
||||
{{0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0}},
|
||||
{{0x017e7e31c2e5bd66, 0x022cf0615a90a6fe, 0x00127a2ffa8de334,
|
||||
0x01dfbf9d64a3f877, 0x006b4d3dbaa14b5e, 0x014fed487e0a2bd8,
|
||||
0x015b4429c6481390, 0x03a73678fb2d988e, 0x00c6858e06b70404},
|
||||
@@ -1455,7 +1471,8 @@ static void select_point(const limb idx, unsigned int size,
|
||||
{
|
||||
unsigned i, j;
|
||||
limb *outlimbs = &out[0][0];
|
||||
memset(outlimbs, 0, 3 * sizeof(felem));
|
||||
|
||||
memset(out, 0, sizeof(*out) * 3);
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
const limb *inlimbs = &pre_comp[i][0][0];
|
||||
@@ -1498,7 +1515,7 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
|
||||
u8 sign, digit;
|
||||
|
||||
/* set nq to the point at infinity */
|
||||
memset(nq, 0, 3 * sizeof(felem));
|
||||
memset(nq, 0, sizeof(nq));
|
||||
|
||||
/*
|
||||
* Loop over all scalars msb-to-lsb, interleaving additions of multiples
|
||||
@@ -1569,10 +1586,11 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
|
||||
}
|
||||
|
||||
/* Precomputation for the group generator. */
|
||||
typedef struct {
|
||||
struct nistp521_pre_comp_st {
|
||||
felem g_pre_comp[16][3];
|
||||
int references;
|
||||
} NISTP521_PRE_COMP;
|
||||
CRYPTO_RWLOCK *lock;
|
||||
};
|
||||
|
||||
const EC_METHOD *EC_GFp_nistp521_method(void)
|
||||
{
|
||||
@@ -1586,6 +1604,7 @@ const EC_METHOD *EC_GFp_nistp521_method(void)
|
||||
ec_GFp_nistp521_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,
|
||||
@@ -1615,7 +1634,16 @@ const EC_METHOD *EC_GFp_nistp521_method(void)
|
||||
0 /* field_div */ ,
|
||||
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
|
||||
};
|
||||
|
||||
return &ret;
|
||||
@@ -1628,56 +1656,47 @@ const EC_METHOD *EC_GFp_nistp521_method(void)
|
||||
|
||||
static NISTP521_PRE_COMP *nistp521_pre_comp_new()
|
||||
{
|
||||
NISTP521_PRE_COMP *ret = NULL;
|
||||
ret = (NISTP521_PRE_COMP *) OPENSSL_malloc(sizeof(NISTP521_PRE_COMP));
|
||||
if (!ret) {
|
||||
NISTP521_PRE_COMP *ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
|
||||
if (ret == NULL) {
|
||||
ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return ret;
|
||||
}
|
||||
memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp));
|
||||
|
||||
ret->references = 1;
|
||||
|
||||
ret->lock = CRYPTO_THREAD_lock_new();
|
||||
if (ret->lock == NULL) {
|
||||
ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *nistp521_pre_comp_dup(void *src_)
|
||||
{
|
||||
NISTP521_PRE_COMP *src = src_;
|
||||
|
||||
/* no need to actually copy, these objects never change! */
|
||||
CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
|
||||
|
||||
return src_;
|
||||
}
|
||||
|
||||
static void nistp521_pre_comp_free(void *pre_)
|
||||
NISTP521_PRE_COMP *EC_nistp521_pre_comp_dup(NISTP521_PRE_COMP *p)
|
||||
{
|
||||
int i;
|
||||
NISTP521_PRE_COMP *pre = pre_;
|
||||
|
||||
if (!pre)
|
||||
return;
|
||||
|
||||
i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
|
||||
if (i > 0)
|
||||
return;
|
||||
|
||||
OPENSSL_free(pre);
|
||||
if (p != NULL)
|
||||
CRYPTO_atomic_add(&p->references, 1, &i, p->lock);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void nistp521_pre_comp_clear_free(void *pre_)
|
||||
void EC_nistp521_pre_comp_free(NISTP521_PRE_COMP *p)
|
||||
{
|
||||
int i;
|
||||
NISTP521_PRE_COMP *pre = pre_;
|
||||
|
||||
if (!pre)
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
|
||||
CRYPTO_atomic_add(&p->references, -1, &i, p->lock);
|
||||
REF_PRINT_COUNT("EC_nistp521", x);
|
||||
if (i > 0)
|
||||
return;
|
||||
REF_ASSERT_ISNT(i < 0);
|
||||
|
||||
OPENSSL_cleanse(pre, sizeof(*pre));
|
||||
OPENSSL_free(pre);
|
||||
CRYPTO_THREAD_lock_free(p->lock);
|
||||
OPENSSL_free(p);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -1721,8 +1740,7 @@ int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1743,8 +1761,8 @@ int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
|
||||
EC_R_POINT_AT_INFINITY);
|
||||
return 0;
|
||||
}
|
||||
if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) ||
|
||||
(!BN_to_felem(z1, &point->Z)))
|
||||
if ((!BN_to_felem(x_in, point->X)) || (!BN_to_felem(y_in, point->Y)) ||
|
||||
(!BN_to_felem(z1, point->Z)))
|
||||
return 0;
|
||||
felem_inv(z2, z1);
|
||||
felem_square(tmp, z2);
|
||||
@@ -1821,7 +1839,7 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
BIGNUM *x, *y, *z, *tmp_scalar;
|
||||
felem_bytearray g_secret;
|
||||
felem_bytearray *secrets = NULL;
|
||||
felem(*pre_comp)[17][3] = NULL;
|
||||
felem (*pre_comp)[17][3] = NULL;
|
||||
felem *tmp_felems = NULL;
|
||||
felem_bytearray tmp;
|
||||
unsigned i, num_bytes;
|
||||
@@ -1845,10 +1863,7 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
goto err;
|
||||
|
||||
if (scalar != NULL) {
|
||||
pre = EC_EX_DATA_get_data(group->extra_data,
|
||||
nistp521_pre_comp_dup,
|
||||
nistp521_pre_comp_free,
|
||||
nistp521_pre_comp_clear_free);
|
||||
pre = group->pre_comp.nistp521;
|
||||
if (pre)
|
||||
/* we have precomputation, try to use it */
|
||||
g_pre_comp = &pre->g_pre_comp[0];
|
||||
@@ -1888,11 +1903,11 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
*/
|
||||
mixed = 1;
|
||||
}
|
||||
secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
|
||||
pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem));
|
||||
secrets = OPENSSL_zalloc(sizeof(*secrets) * num_points);
|
||||
pre_comp = OPENSSL_zalloc(sizeof(*pre_comp) * num_points);
|
||||
if (mixed)
|
||||
tmp_felems =
|
||||
OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem));
|
||||
OPENSSL_malloc(sizeof(*tmp_felems) * (num_points * 17 + 1));
|
||||
if ((secrets == NULL) || (pre_comp == NULL)
|
||||
|| (mixed && (tmp_felems == NULL))) {
|
||||
ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_MALLOC_FAILURE);
|
||||
@@ -1903,8 +1918,6 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
* we treat NULL scalars as 0, and NULL points as points at infinity,
|
||||
* i.e., they contribute nothing to the linear combination
|
||||
*/
|
||||
memset(secrets, 0, num_points * sizeof(felem_bytearray));
|
||||
memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem));
|
||||
for (i = 0; i < num_points; ++i) {
|
||||
if (i == num)
|
||||
/*
|
||||
@@ -1928,7 +1941,7 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
* this is an unusual input, and we don't guarantee
|
||||
* constant-timeness
|
||||
*/
|
||||
if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) {
|
||||
if (!BN_nnmod(tmp_scalar, p_scalar, group->order, ctx)) {
|
||||
ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
@@ -1937,9 +1950,9 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
num_bytes = BN_bn2bin(p_scalar, tmp);
|
||||
flip_endian(secrets[i], tmp, num_bytes);
|
||||
/* precompute multiples */
|
||||
if ((!BN_to_felem(x_out, &p->X)) ||
|
||||
(!BN_to_felem(y_out, &p->Y)) ||
|
||||
(!BN_to_felem(z_out, &p->Z)))
|
||||
if ((!BN_to_felem(x_out, p->X)) ||
|
||||
(!BN_to_felem(y_out, p->Y)) ||
|
||||
(!BN_to_felem(z_out, p->Z)))
|
||||
goto err;
|
||||
memcpy(pre_comp[i][1][0], x_out, sizeof(felem));
|
||||
memcpy(pre_comp[i][1][1], y_out, sizeof(felem));
|
||||
@@ -1974,7 +1987,7 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
* this is an unusual input, and we don't guarantee
|
||||
* constant-timeness
|
||||
*/
|
||||
if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
|
||||
if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) {
|
||||
ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
@@ -2006,16 +2019,11 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
if (generator != NULL)
|
||||
EC_POINT_free(generator);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
if (secrets != NULL)
|
||||
OPENSSL_free(secrets);
|
||||
if (pre_comp != NULL)
|
||||
OPENSSL_free(pre_comp);
|
||||
if (tmp_felems != NULL)
|
||||
OPENSSL_free(tmp_felems);
|
||||
EC_POINT_free(generator);
|
||||
BN_CTX_free(new_ctx);
|
||||
OPENSSL_free(secrets);
|
||||
OPENSSL_free(pre_comp);
|
||||
OPENSSL_free(tmp_felems);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2030,9 +2038,7 @@ int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
felem tmp_felems[16];
|
||||
|
||||
/* throw away old precomputation */
|
||||
EC_EX_DATA_free_data(&group->extra_data, nistp521_pre_comp_dup,
|
||||
nistp521_pre_comp_free,
|
||||
nistp521_pre_comp_clear_free);
|
||||
EC_pre_comp_free(group);
|
||||
if (ctx == NULL)
|
||||
if ((ctx = new_ctx = BN_CTX_new()) == NULL)
|
||||
return 0;
|
||||
@@ -2058,9 +2064,9 @@ int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
|
||||
goto done;
|
||||
}
|
||||
if ((!BN_to_felem(pre->g_pre_comp[1][0], &group->generator->X)) ||
|
||||
(!BN_to_felem(pre->g_pre_comp[1][1], &group->generator->Y)) ||
|
||||
(!BN_to_felem(pre->g_pre_comp[1][2], &group->generator->Z)))
|
||||
if ((!BN_to_felem(pre->g_pre_comp[1][0], group->generator->X)) ||
|
||||
(!BN_to_felem(pre->g_pre_comp[1][1], group->generator->Y)) ||
|
||||
(!BN_to_felem(pre->g_pre_comp[1][2], group->generator->Z)))
|
||||
goto err;
|
||||
/* compute 2^130*G, 2^260*G, 2^390*G */
|
||||
for (i = 1; i <= 4; i <<= 1) {
|
||||
@@ -2115,34 +2121,20 @@ int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
make_points_affine(15, &(pre->g_pre_comp[1]), tmp_felems);
|
||||
|
||||
done:
|
||||
if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp521_pre_comp_dup,
|
||||
nistp521_pre_comp_free,
|
||||
nistp521_pre_comp_clear_free))
|
||||
goto err;
|
||||
SETPRECOMP(group, nistp521, pre);
|
||||
ret = 1;
|
||||
pre = NULL;
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
if (generator != NULL)
|
||||
EC_POINT_free(generator);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
if (pre)
|
||||
nistp521_pre_comp_free(pre);
|
||||
EC_POINT_free(generator);
|
||||
BN_CTX_free(new_ctx);
|
||||
EC_nistp521_pre_comp_free(pre);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group)
|
||||
{
|
||||
if (EC_EX_DATA_get_data(group->extra_data, nistp521_pre_comp_dup,
|
||||
nistp521_pre_comp_free,
|
||||
nistp521_pre_comp_clear_free)
|
||||
!= NULL)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
return HAVEPRECOMP(group, nistp521);
|
||||
}
|
||||
|
||||
#else
|
||||
static void *dummy = &dummy;
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
/* crypto/ec/ecp_nistputil.c */
|
||||
/*
|
||||
* Written by Bodo Moeller for the OpenSSL project.
|
||||
* Copyright 2011-2016 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");
|
||||
@@ -19,7 +24,9 @@
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
|
||||
/*
|
||||
* Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c.
|
||||
@@ -213,6 +220,4 @@ void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
|
||||
*sign = s & 1;
|
||||
*digit = d;
|
||||
}
|
||||
#else
|
||||
static void *dummy = &dummy;
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* Copyright 2014-2016 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is the precomputed constant time access table for the code in
|
||||
* ecp_montp256.c, for the default generator. The table consists of 37
|
||||
@@ -17,7 +26,7 @@ __attribute((aligned(4096)))
|
||||
#elif defined(_MSC_VER)
|
||||
__declspec(align(4096))
|
||||
#elif defined(__SUNPRO_C)
|
||||
# pragma align 64(ecp_nistz256_precomputed)
|
||||
# pragma align 4096(ecp_nistz256_precomputed)
|
||||
#endif
|
||||
static const BN_ULONG ecp_nistz256_precomputed[37][64 *
|
||||
sizeof(P256_POINT_AFFINE) /
|
||||
|
||||
@@ -1,62 +1,12 @@
|
||||
/* crypto/ec/ecp_oct.c */
|
||||
/*
|
||||
* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
|
||||
* for the OpenSSL project. Includes code written by Bodo Moeller for the
|
||||
* OpenSSL project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright 2011-2016 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* Portions of this software developed by SUN MICROSYSTEMS, INC.,
|
||||
@@ -103,7 +53,7 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
|
||||
*/
|
||||
|
||||
/* tmp1 := x^3 */
|
||||
if (!BN_nnmod(x, x_, &group->field, ctx))
|
||||
if (!BN_nnmod(x, x_, group->field, ctx))
|
||||
goto err;
|
||||
if (group->meth->field_decode == 0) {
|
||||
/* field_{sqr,mul} work on standard representation */
|
||||
@@ -112,48 +62,48 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
|
||||
if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_mod_sqr(tmp2, x_, &group->field, ctx))
|
||||
if (!BN_mod_sqr(tmp2, x_, group->field, ctx))
|
||||
goto err;
|
||||
if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx))
|
||||
if (!BN_mod_mul(tmp1, tmp2, x_, group->field, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* tmp1 := tmp1 + a*x */
|
||||
if (group->a_is_minus3) {
|
||||
if (!BN_mod_lshift1_quick(tmp2, x, &group->field))
|
||||
if (!BN_mod_lshift1_quick(tmp2, x, group->field))
|
||||
goto err;
|
||||
if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field))
|
||||
if (!BN_mod_add_quick(tmp2, tmp2, x, group->field))
|
||||
goto err;
|
||||
if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field))
|
||||
if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, group->field))
|
||||
goto err;
|
||||
} else {
|
||||
if (group->meth->field_decode) {
|
||||
if (!group->meth->field_decode(group, tmp2, &group->a, ctx))
|
||||
if (!group->meth->field_decode(group, tmp2, group->a, ctx))
|
||||
goto err;
|
||||
if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx))
|
||||
if (!BN_mod_mul(tmp2, tmp2, x, group->field, ctx))
|
||||
goto err;
|
||||
} else {
|
||||
/* field_mul works on standard representation */
|
||||
if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx))
|
||||
if (!group->meth->field_mul(group, tmp2, group->a, x, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field))
|
||||
if (!BN_mod_add_quick(tmp1, tmp1, tmp2, group->field))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* tmp1 := tmp1 + b */
|
||||
if (group->meth->field_decode) {
|
||||
if (!group->meth->field_decode(group, tmp2, &group->b, ctx))
|
||||
if (!group->meth->field_decode(group, tmp2, group->b, ctx))
|
||||
goto err;
|
||||
if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field))
|
||||
if (!BN_mod_add_quick(tmp1, tmp1, tmp2, group->field))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field))
|
||||
if (!BN_mod_add_quick(tmp1, tmp1, group->b, group->field))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) {
|
||||
if (!BN_mod_sqrt(y, tmp1, group->field, ctx)) {
|
||||
unsigned long err = ERR_peek_last_error();
|
||||
|
||||
if (ERR_GET_LIB(err) == ERR_LIB_BN
|
||||
@@ -171,7 +121,7 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
|
||||
if (BN_is_zero(y)) {
|
||||
int kron;
|
||||
|
||||
kron = BN_kronecker(x, &group->field, ctx);
|
||||
kron = BN_kronecker(x, group->field, ctx);
|
||||
if (kron == -2)
|
||||
goto err;
|
||||
|
||||
@@ -186,7 +136,7 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
|
||||
EC_R_INVALID_COMPRESSED_POINT);
|
||||
goto err;
|
||||
}
|
||||
if (!BN_usub(y, &group->field, y))
|
||||
if (!BN_usub(y, group->field, y))
|
||||
goto err;
|
||||
}
|
||||
if (y_bit != BN_is_odd(y)) {
|
||||
@@ -202,8 +152,7 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -237,7 +186,7 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
|
||||
}
|
||||
|
||||
/* ret := required output buffer length */
|
||||
field_len = BN_num_bytes(&group->field);
|
||||
field_len = BN_num_bytes(group->field);
|
||||
ret =
|
||||
(form ==
|
||||
POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
|
||||
@@ -312,15 +261,13 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
|
||||
|
||||
if (used_ctx)
|
||||
BN_CTX_end(ctx);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
|
||||
err:
|
||||
if (used_ctx)
|
||||
BN_CTX_end(ctx);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -361,7 +308,7 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
||||
return EC_POINT_set_to_infinity(group, point);
|
||||
}
|
||||
|
||||
field_len = BN_num_bytes(&group->field);
|
||||
field_len = BN_num_bytes(group->field);
|
||||
enc_len =
|
||||
(form ==
|
||||
POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
|
||||
@@ -385,7 +332,7 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
||||
|
||||
if (!BN_bin2bn(buf + 1, field_len, x))
|
||||
goto err;
|
||||
if (BN_ucmp(x, &group->field) >= 0) {
|
||||
if (BN_ucmp(x, group->field) >= 0) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
goto err;
|
||||
}
|
||||
@@ -397,7 +344,7 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
||||
} else {
|
||||
if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
|
||||
goto err;
|
||||
if (BN_ucmp(y, &group->field) >= 0) {
|
||||
if (BN_ucmp(y, group->field) >= 0) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
goto err;
|
||||
}
|
||||
@@ -408,21 +355,18 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* EC_POINT_set_affine_coordinates_GFp is responsible for checking that
|
||||
* the point is on the curve.
|
||||
*/
|
||||
if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* test required by X9.62 */
|
||||
if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
if (new_ctx != NULL)
|
||||
BN_CTX_free(new_ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1870
crypto/ec/ectest.c
1870
crypto/ec/ectest.c
File diff suppressed because it is too large
Load Diff
373
crypto/ec/ecx_meth.c
Normal file
373
crypto/ec/ecx_meth.c
Normal file
@@ -0,0 +1,373 @@
|
||||
/*
|
||||
* Copyright 2006-2016 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
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "internal/asn1_int.h"
|
||||
#include "internal/evp_int.h"
|
||||
#include "ec_lcl.h"
|
||||
|
||||
#define X25519_KEYLEN 32
|
||||
#define X25519_BITS 253
|
||||
#define X25519_SECURITY_BITS 128
|
||||
|
||||
typedef struct {
|
||||
unsigned char pubkey[X25519_KEYLEN];
|
||||
unsigned char *privkey;
|
||||
} X25519_KEY;
|
||||
|
||||
typedef enum {
|
||||
X25519_PUBLIC,
|
||||
X25519_PRIVATE,
|
||||
X25519_KEYGEN
|
||||
} ecx_key_op_t;
|
||||
|
||||
/* Setup EVP_PKEY using public, private or generation */
|
||||
static int ecx_key_op(EVP_PKEY *pkey, const X509_ALGOR *palg,
|
||||
const unsigned char *p, int plen, ecx_key_op_t op)
|
||||
{
|
||||
X25519_KEY *xkey;
|
||||
|
||||
if (op != X25519_KEYGEN) {
|
||||
if (palg != NULL) {
|
||||
int ptype;
|
||||
|
||||
/* Algorithm parameters must be absent */
|
||||
X509_ALGOR_get0(NULL, &ptype, NULL, palg);
|
||||
if (ptype != V_ASN1_UNDEF) {
|
||||
ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (p == NULL || plen != X25519_KEYLEN) {
|
||||
ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
xkey = OPENSSL_zalloc(sizeof(*xkey));
|
||||
if (xkey == NULL) {
|
||||
ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (op == X25519_PUBLIC) {
|
||||
memcpy(xkey->pubkey, p, plen);
|
||||
} else {
|
||||
xkey->privkey = OPENSSL_secure_malloc(X25519_KEYLEN);
|
||||
if (xkey->privkey == NULL) {
|
||||
ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(xkey);
|
||||
return 0;
|
||||
}
|
||||
if (op == X25519_KEYGEN) {
|
||||
if (RAND_bytes(xkey->privkey, X25519_KEYLEN) <= 0) {
|
||||
OPENSSL_secure_free(xkey->privkey);
|
||||
OPENSSL_free(xkey);
|
||||
return 0;
|
||||
}
|
||||
xkey->privkey[0] &= 248;
|
||||
xkey->privkey[31] &= 127;
|
||||
xkey->privkey[31] |= 64;
|
||||
} else {
|
||||
memcpy(xkey->privkey, p, X25519_KEYLEN);
|
||||
}
|
||||
X25519_public_from_private(xkey->pubkey, xkey->privkey);
|
||||
}
|
||||
|
||||
EVP_PKEY_assign(pkey, NID_X25519, xkey);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
|
||||
{
|
||||
const X25519_KEY *xkey = pkey->pkey.ptr;
|
||||
unsigned char *penc;
|
||||
|
||||
if (xkey == NULL) {
|
||||
ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
penc = OPENSSL_memdup(xkey->pubkey, X25519_KEYLEN);
|
||||
if (penc == NULL) {
|
||||
ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(NID_X25519), V_ASN1_UNDEF,
|
||||
NULL, penc, X25519_KEYLEN)) {
|
||||
OPENSSL_free(penc);
|
||||
ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
|
||||
{
|
||||
const unsigned char *p;
|
||||
int pklen;
|
||||
X509_ALGOR *palg;
|
||||
|
||||
if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
|
||||
return 0;
|
||||
return ecx_key_op(pkey, palg, p, pklen, X25519_PUBLIC);
|
||||
}
|
||||
|
||||
static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
{
|
||||
const X25519_KEY *akey = a->pkey.ptr;
|
||||
const X25519_KEY *bkey = b->pkey.ptr;
|
||||
|
||||
if (akey == NULL || bkey == NULL)
|
||||
return -2;
|
||||
return !CRYPTO_memcmp(akey->pubkey, bkey->pubkey, X25519_KEYLEN);
|
||||
}
|
||||
|
||||
static int ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
|
||||
{
|
||||
const unsigned char *p;
|
||||
int plen;
|
||||
ASN1_OCTET_STRING *oct = NULL;
|
||||
const X509_ALGOR *palg;
|
||||
int rv;
|
||||
|
||||
if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8))
|
||||
return 0;
|
||||
|
||||
oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
|
||||
if (oct == NULL) {
|
||||
p = NULL;
|
||||
plen = 0;
|
||||
} else {
|
||||
p = ASN1_STRING_get0_data(oct);
|
||||
plen = ASN1_STRING_length(oct);
|
||||
}
|
||||
|
||||
rv = ecx_key_op(pkey, palg, p, plen, X25519_PRIVATE);
|
||||
ASN1_OCTET_STRING_free(oct);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
|
||||
{
|
||||
const X25519_KEY *xkey = pkey->pkey.ptr;
|
||||
ASN1_OCTET_STRING oct;
|
||||
unsigned char *penc = NULL;
|
||||
int penclen;
|
||||
|
||||
if (xkey == NULL || xkey->privkey == NULL) {
|
||||
ECerr(EC_F_ECX_PRIV_ENCODE, EC_R_INVALID_PRIVATE_KEY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
oct.data = xkey->privkey;
|
||||
oct.length = X25519_KEYLEN;
|
||||
oct.flags = 0;
|
||||
|
||||
penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
|
||||
if (penclen < 0) {
|
||||
ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X25519), 0,
|
||||
V_ASN1_UNDEF, NULL, penc, penclen)) {
|
||||
OPENSSL_clear_free(penc, penclen);
|
||||
ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ecx_size(const EVP_PKEY *pkey)
|
||||
{
|
||||
return X25519_KEYLEN;
|
||||
}
|
||||
|
||||
static int ecx_bits(const EVP_PKEY *pkey)
|
||||
{
|
||||
return X25519_BITS;
|
||||
}
|
||||
|
||||
static int ecx_security_bits(const EVP_PKEY *pkey)
|
||||
{
|
||||
return X25519_SECURITY_BITS;
|
||||
}
|
||||
|
||||
static void ecx_free(EVP_PKEY *pkey)
|
||||
{
|
||||
X25519_KEY *xkey = pkey->pkey.ptr;
|
||||
|
||||
if (xkey)
|
||||
OPENSSL_secure_free(xkey->privkey);
|
||||
OPENSSL_free(xkey);
|
||||
}
|
||||
|
||||
/* "parameters" are always equal */
|
||||
static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *ctx, ecx_key_op_t op)
|
||||
{
|
||||
const X25519_KEY *xkey = pkey->pkey.ptr;
|
||||
|
||||
if (op == X25519_PRIVATE) {
|
||||
if (xkey == NULL || xkey->privkey == NULL) {
|
||||
if (BIO_printf(bp, "%*s<INVALID PRIVATE KEY>\n", indent, "") <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
if (BIO_printf(bp, "%*sX25519 Private-Key:\n", indent, "") <= 0)
|
||||
return 0;
|
||||
if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
|
||||
return 0;
|
||||
if (ASN1_buf_print(bp, xkey->privkey, X25519_KEYLEN, indent + 4) == 0)
|
||||
return 0;
|
||||
} else {
|
||||
if (xkey == NULL) {
|
||||
if (BIO_printf(bp, "%*s<INVALID PUBLIC KEY>\n", indent, "") <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
if (BIO_printf(bp, "%*sX25519 Public-Key:\n", indent, "") <= 0)
|
||||
return 0;
|
||||
}
|
||||
if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
|
||||
return 0;
|
||||
if (ASN1_buf_print(bp, xkey->pubkey, X25519_KEYLEN, indent + 4) == 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *ctx)
|
||||
{
|
||||
return ecx_key_print(bp, pkey, indent, ctx, X25519_PRIVATE);
|
||||
}
|
||||
|
||||
static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *ctx)
|
||||
{
|
||||
return ecx_key_print(bp, pkey, indent, ctx, X25519_PUBLIC);
|
||||
}
|
||||
|
||||
static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
|
||||
{
|
||||
switch (op) {
|
||||
|
||||
case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
|
||||
return ecx_key_op(pkey, NULL, arg2, arg1, X25519_PUBLIC);
|
||||
|
||||
case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
|
||||
if (pkey->pkey.ptr != NULL) {
|
||||
const X25519_KEY *xkey = pkey->pkey.ptr;
|
||||
unsigned char **ppt = arg2;
|
||||
*ppt = OPENSSL_memdup(xkey->pubkey, X25519_KEYLEN);
|
||||
if (*ppt != NULL)
|
||||
return X25519_KEYLEN;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
|
||||
*(int *)arg2 = NID_sha256;
|
||||
return 2;
|
||||
|
||||
default:
|
||||
return -2;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
|
||||
NID_X25519,
|
||||
NID_X25519,
|
||||
0,
|
||||
"X25519",
|
||||
"OpenSSL X25519 algorithm",
|
||||
|
||||
ecx_pub_decode,
|
||||
ecx_pub_encode,
|
||||
ecx_pub_cmp,
|
||||
ecx_pub_print,
|
||||
|
||||
ecx_priv_decode,
|
||||
ecx_priv_encode,
|
||||
ecx_priv_print,
|
||||
|
||||
ecx_size,
|
||||
ecx_bits,
|
||||
ecx_security_bits,
|
||||
|
||||
0, 0, 0, 0,
|
||||
ecx_cmp_parameters,
|
||||
0, 0,
|
||||
|
||||
ecx_free,
|
||||
ecx_ctrl,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
{
|
||||
return ecx_key_op(pkey, NULL, NULL, 0, X25519_KEYGEN);
|
||||
}
|
||||
|
||||
static int pkey_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
|
||||
size_t *keylen)
|
||||
{
|
||||
const X25519_KEY *pkey, *peerkey;
|
||||
|
||||
if (ctx->pkey == NULL || ctx->peerkey == NULL) {
|
||||
ECerr(EC_F_PKEY_ECX_DERIVE, EC_R_KEYS_NOT_SET);
|
||||
return 0;
|
||||
}
|
||||
pkey = ctx->pkey->pkey.ptr;
|
||||
peerkey = ctx->peerkey->pkey.ptr;
|
||||
if (pkey == NULL || pkey->privkey == NULL) {
|
||||
ECerr(EC_F_PKEY_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
|
||||
return 0;
|
||||
}
|
||||
if (peerkey == NULL) {
|
||||
ECerr(EC_F_PKEY_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
|
||||
return 0;
|
||||
}
|
||||
*keylen = X25519_KEYLEN;
|
||||
if (key != NULL && X25519(key, pkey->privkey, peerkey->pubkey) == 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
{
|
||||
/* Only need to handle peer key for derivation */
|
||||
if (type == EVP_PKEY_CTRL_PEER_KEY)
|
||||
return 1;
|
||||
return -2;
|
||||
}
|
||||
|
||||
const EVP_PKEY_METHOD ecx25519_pkey_meth = {
|
||||
NID_X25519,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
pkey_ecx_keygen,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
pkey_ecx_derive,
|
||||
pkey_ecx_ctrl,
|
||||
0
|
||||
};
|
||||
Reference in New Issue
Block a user