This commit is contained in:
Zhi Guan
2015-08-15 15:02:15 +08:00
parent 06df2fab54
commit 3bdc0ea895
2536 changed files with 417052 additions and 271997 deletions

View File

@@ -11,6 +11,8 @@ MAKEFILE= Makefile
AR= ar r
CFLAGS= $(INCLUDES) $(CFLAG)
ASFLAGS= $(INCLUDES) $(ASFLAG)
AFLAGS= $(ASFLAGS)
GENERAL=Makefile
TEST=ectest.c
@@ -19,11 +21,15 @@ 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
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
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)
@@ -42,6 +48,12 @@ 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
@@ -66,6 +78,8 @@ tests:
lint:
lint -DLINT $(INCLUDES) $(SRC)>fluff
update: depend
depend:
@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
@@ -87,6 +101,14 @@ 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
@@ -96,14 +118,14 @@ 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/bio.h ../../include/openssl/bn.h
ec_ameth.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
ec_ameth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
ec_ameth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
ec_ameth.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
ec_ameth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
ec_ameth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
ec_ameth.o: ../../include/openssl/opensslconf.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
@@ -174,20 +196,29 @@ 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/buffer.h ../../include/openssl/crypto.h
ec_pmeth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ec_pmeth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
ec_pmeth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
ec_pmeth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
ec_pmeth.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.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_pmeth.c
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
@@ -221,6 +252,18 @@ 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

2093
crypto/ec/asm/ecp_nistz256-avx2.pl Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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
@@ -71,316 +71,393 @@
#include "ec_lcl.h"
#ifndef OPENSSL_NO_EC2M
/* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective
/*-
* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective
* coordinates.
* Uses algorithm Mdouble in appendix of
* Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
* Uses algorithm Mdouble in appendix of
* Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
* GF(2^m) without precomputation" (CHES '99, LNCS 1717).
* modified to not require precomputation of c=b^{2^{m-1}}.
*/
static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, BN_CTX *ctx)
{
BIGNUM *t1;
int ret = 0;
/* Since Mdouble is static we can guarantee that ctx != NULL. */
BN_CTX_start(ctx);
t1 = BN_CTX_get(ctx);
if (t1 == NULL) goto err;
static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z,
BN_CTX *ctx)
{
BIGNUM *t1;
int ret = 0;
if (!group->meth->field_sqr(group, x, x, ctx)) goto err;
if (!group->meth->field_sqr(group, t1, z, ctx)) goto err;
if (!group->meth->field_mul(group, z, x, t1, ctx)) goto err;
if (!group->meth->field_sqr(group, x, x, ctx)) goto err;
if (!group->meth->field_sqr(group, t1, t1, ctx)) goto err;
if (!group->meth->field_mul(group, t1, &group->b, t1, ctx)) goto err;
if (!BN_GF2m_add(x, x, t1)) goto err;
/* Since Mdouble is static we can guarantee that ctx != NULL. */
BN_CTX_start(ctx);
t1 = BN_CTX_get(ctx);
if (t1 == NULL)
goto err;
ret = 1;
if (!group->meth->field_sqr(group, x, x, ctx))
goto err;
if (!group->meth->field_sqr(group, t1, z, ctx))
goto err;
if (!group->meth->field_mul(group, z, x, t1, ctx))
goto err;
if (!group->meth->field_sqr(group, x, x, ctx))
goto err;
if (!group->meth->field_sqr(group, t1, t1, ctx))
goto err;
if (!group->meth->field_mul(group, t1, &group->b, t1, ctx))
goto err;
if (!BN_GF2m_add(x, x, t1))
goto err;
ret = 1;
err:
BN_CTX_end(ctx);
return ret;
}
BN_CTX_end(ctx);
return ret;
}
/* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery
/*-
* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery
* projective coordinates.
* Uses algorithm Madd in appendix of
* Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
* Uses algorithm Madd in appendix of
* Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
* GF(2^m) without precomputation" (CHES '99, LNCS 1717).
*/
static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, BIGNUM *z1,
const BIGNUM *x2, const BIGNUM *z2, BN_CTX *ctx)
{
BIGNUM *t1, *t2;
int ret = 0;
/* Since Madd is static we can guarantee that ctx != NULL. */
BN_CTX_start(ctx);
t1 = BN_CTX_get(ctx);
t2 = BN_CTX_get(ctx);
if (t2 == NULL) goto err;
static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1,
BIGNUM *z1, const BIGNUM *x2, const BIGNUM *z2,
BN_CTX *ctx)
{
BIGNUM *t1, *t2;
int ret = 0;
if (!BN_copy(t1, x)) goto err;
if (!group->meth->field_mul(group, x1, x1, z2, ctx)) goto err;
if (!group->meth->field_mul(group, z1, z1, x2, ctx)) goto err;
if (!group->meth->field_mul(group, t2, x1, z1, ctx)) goto err;
if (!BN_GF2m_add(z1, z1, x1)) goto err;
if (!group->meth->field_sqr(group, z1, z1, ctx)) goto err;
if (!group->meth->field_mul(group, x1, z1, t1, ctx)) goto err;
if (!BN_GF2m_add(x1, x1, t2)) goto err;
/* Since Madd is static we can guarantee that ctx != NULL. */
BN_CTX_start(ctx);
t1 = BN_CTX_get(ctx);
t2 = BN_CTX_get(ctx);
if (t2 == NULL)
goto err;
ret = 1;
if (!BN_copy(t1, x))
goto err;
if (!group->meth->field_mul(group, x1, x1, z2, ctx))
goto err;
if (!group->meth->field_mul(group, z1, z1, x2, ctx))
goto err;
if (!group->meth->field_mul(group, t2, x1, z1, ctx))
goto err;
if (!BN_GF2m_add(z1, z1, x1))
goto err;
if (!group->meth->field_sqr(group, z1, z1, ctx))
goto err;
if (!group->meth->field_mul(group, x1, z1, t1, ctx))
goto err;
if (!BN_GF2m_add(x1, x1, t2))
goto err;
ret = 1;
err:
BN_CTX_end(ctx);
return ret;
}
BN_CTX_end(ctx);
return ret;
}
/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2)
* using Montgomery point multiplication algorithm Mxy() in appendix of
* Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
/*-
* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2)
* using Montgomery point multiplication algorithm Mxy() in appendix of
* Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
* GF(2^m) without precomputation" (CHES '99, LNCS 1717).
* Returns:
* 0 on error
* 1 if return value should be the point at infinity
* 2 otherwise
*/
static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, BIGNUM *x1,
BIGNUM *z1, BIGNUM *x2, BIGNUM *z2, BN_CTX *ctx)
{
BIGNUM *t3, *t4, *t5;
int ret = 0;
if (BN_is_zero(z1))
{
BN_zero(x2);
BN_zero(z2);
return 1;
}
if (BN_is_zero(z2))
{
if (!BN_copy(x2, x)) return 0;
if (!BN_GF2m_add(z2, x, y)) return 0;
return 2;
}
/* Since Mxy is static we can guarantee that ctx != NULL. */
BN_CTX_start(ctx);
t3 = BN_CTX_get(ctx);
t4 = BN_CTX_get(ctx);
t5 = BN_CTX_get(ctx);
if (t5 == NULL) goto err;
static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y,
BIGNUM *x1, BIGNUM *z1, BIGNUM *x2, BIGNUM *z2,
BN_CTX *ctx)
{
BIGNUM *t3, *t4, *t5;
int ret = 0;
if (!BN_one(t5)) goto err;
if (BN_is_zero(z1)) {
BN_zero(x2);
BN_zero(z2);
return 1;
}
if (!group->meth->field_mul(group, t3, z1, z2, ctx)) goto err;
if (BN_is_zero(z2)) {
if (!BN_copy(x2, x))
return 0;
if (!BN_GF2m_add(z2, x, y))
return 0;
return 2;
}
if (!group->meth->field_mul(group, z1, z1, x, ctx)) goto err;
if (!BN_GF2m_add(z1, z1, x1)) goto err;
if (!group->meth->field_mul(group, z2, z2, x, ctx)) goto err;
if (!group->meth->field_mul(group, x1, z2, x1, ctx)) goto err;
if (!BN_GF2m_add(z2, z2, x2)) goto err;
/* Since Mxy is static we can guarantee that ctx != NULL. */
BN_CTX_start(ctx);
t3 = BN_CTX_get(ctx);
t4 = BN_CTX_get(ctx);
t5 = BN_CTX_get(ctx);
if (t5 == NULL)
goto err;
if (!group->meth->field_mul(group, z2, z2, z1, ctx)) goto err;
if (!group->meth->field_sqr(group, t4, x, ctx)) goto err;
if (!BN_GF2m_add(t4, t4, y)) goto err;
if (!group->meth->field_mul(group, t4, t4, t3, ctx)) goto err;
if (!BN_GF2m_add(t4, t4, z2)) goto err;
if (!BN_one(t5))
goto err;
if (!group->meth->field_mul(group, t3, t3, x, ctx)) goto err;
if (!group->meth->field_div(group, t3, t5, t3, ctx)) goto err;
if (!group->meth->field_mul(group, t4, t3, t4, ctx)) goto err;
if (!group->meth->field_mul(group, x2, x1, t3, ctx)) goto err;
if (!BN_GF2m_add(z2, x2, x)) goto err;
if (!group->meth->field_mul(group, t3, z1, z2, ctx))
goto err;
if (!group->meth->field_mul(group, z2, z2, t4, ctx)) goto err;
if (!BN_GF2m_add(z2, z2, y)) goto err;
if (!group->meth->field_mul(group, z1, z1, x, ctx))
goto err;
if (!BN_GF2m_add(z1, z1, x1))
goto err;
if (!group->meth->field_mul(group, z2, z2, x, ctx))
goto err;
if (!group->meth->field_mul(group, x1, z2, x1, ctx))
goto err;
if (!BN_GF2m_add(z2, z2, x2))
goto err;
ret = 2;
if (!group->meth->field_mul(group, z2, z2, z1, ctx))
goto err;
if (!group->meth->field_sqr(group, t4, x, ctx))
goto err;
if (!BN_GF2m_add(t4, t4, y))
goto err;
if (!group->meth->field_mul(group, t4, t4, t3, ctx))
goto err;
if (!BN_GF2m_add(t4, t4, z2))
goto err;
if (!group->meth->field_mul(group, t3, t3, x, ctx))
goto err;
if (!group->meth->field_div(group, t3, t5, t3, ctx))
goto err;
if (!group->meth->field_mul(group, t4, t3, t4, ctx))
goto err;
if (!group->meth->field_mul(group, x2, x1, t3, ctx))
goto err;
if (!BN_GF2m_add(z2, x2, x))
goto err;
if (!group->meth->field_mul(group, z2, z2, t4, ctx))
goto err;
if (!BN_GF2m_add(z2, z2, y))
goto err;
ret = 2;
err:
BN_CTX_end(ctx);
return ret;
}
BN_CTX_end(ctx);
return ret;
}
/* Computes scalar*point and stores the result in r.
/*-
* Computes scalar*point and stores the result in r.
* point can not equal r.
* Uses algorithm 2P of
* Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
* Uses a modified algorithm 2P of
* Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
* GF(2^m) without precomputation" (CHES '99, LNCS 1717).
*
* To protect against side-channel attack the function uses constant time swap,
* avoiding conditional branches.
*/
static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
const EC_POINT *point, BN_CTX *ctx)
{
BIGNUM *x1, *x2, *z1, *z2;
int ret = 0, i;
BN_ULONG mask,word;
static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group,
EC_POINT *r,
const BIGNUM *scalar,
const EC_POINT *point,
BN_CTX *ctx)
{
BIGNUM *x1, *x2, *z1, *z2;
int ret = 0, i;
BN_ULONG mask, word;
if (r == point)
{
ECerr(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, EC_R_INVALID_ARGUMENT);
return 0;
}
/* if result should be point at infinity */
if ((scalar == NULL) || BN_is_zero(scalar) || (point == NULL) ||
EC_POINT_is_at_infinity(group, point))
{
return EC_POINT_set_to_infinity(group, r);
}
if (r == point) {
ECerr(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, EC_R_INVALID_ARGUMENT);
return 0;
}
/* only support affine coordinates */
if (!point->Z_is_one) return 0;
/* if result should be point at infinity */
if ((scalar == NULL) || BN_is_zero(scalar) || (point == NULL) ||
EC_POINT_is_at_infinity(group, point)) {
return EC_POINT_set_to_infinity(group, r);
}
/* Since point_multiply is static we can guarantee that ctx != NULL. */
BN_CTX_start(ctx);
x1 = BN_CTX_get(ctx);
z1 = BN_CTX_get(ctx);
if (z1 == NULL) goto err;
/* only support affine coordinates */
if (!point->Z_is_one)
return 0;
x2 = &r->X;
z2 = &r->Y;
/*
* Since point_multiply is static we can guarantee that ctx != NULL.
*/
BN_CTX_start(ctx);
x1 = BN_CTX_get(ctx);
z1 = BN_CTX_get(ctx);
if (z1 == NULL)
goto err;
if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */
if (!BN_one(z1)) goto err; /* z1 = 1 */
if (!group->meth->field_sqr(group, z2, x1, ctx)) 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)) goto err; /* x2 = x^4 + b */
x2 = &r->X;
z2 = &r->Y;
/* find top most bit and go one past it */
i = scalar->top - 1;
mask = BN_TBIT;
word = scalar->d[i];
while (!(word & mask)) mask >>= 1;
mask >>= 1;
/* if top most bit was at word break, go to next word */
if (!mask)
{
i--;
mask = BN_TBIT;
}
bn_wexpand(x1, group->field.top);
bn_wexpand(z1, group->field.top);
bn_wexpand(x2, group->field.top);
bn_wexpand(z2, group->field.top);
for (; i >= 0; i--)
{
word = scalar->d[i];
while (mask)
{
if (word & mask)
{
if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err;
if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err;
}
else
{
if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err;
if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err;
}
mask >>= 1;
}
mask = BN_TBIT;
}
if (!BN_GF2m_mod_arr(x1, &point->X, group->poly))
goto err; /* x1 = x */
if (!BN_one(z1))
goto err; /* z1 = 1 */
if (!group->meth->field_sqr(group, z2, x1, ctx))
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))
goto err; /* x2 = x^4 + b */
/* convert out of "projective" coordinates */
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)) goto err;
r->Z_is_one = 1;
}
/* find top most bit and go one past it */
i = scalar->top - 1;
mask = BN_TBIT;
word = scalar->d[i];
while (!(word & mask))
mask >>= 1;
mask >>= 1;
/* if top most bit was at word break, go to next word */
if (!mask) {
i--;
mask = BN_TBIT;
}
/* GF(2^m) field elements should always have BIGNUM::neg = 0 */
BN_set_negative(&r->X, 0);
BN_set_negative(&r->Y, 0);
for (; i >= 0; i--) {
word = scalar->d[i];
while (mask) {
BN_consttime_swap(word & mask, x1, x2, group->field.top);
BN_consttime_swap(word & mask, z1, z2, group->field.top);
if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx))
goto err;
if (!gf2m_Mdouble(group, x1, z1, ctx))
goto err;
BN_consttime_swap(word & mask, x1, x2, group->field.top);
BN_consttime_swap(word & mask, z1, z2, group->field.top);
mask >>= 1;
}
mask = BN_TBIT;
}
ret = 1;
/* convert out of "projective" coordinates */
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))
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);
ret = 1;
err:
BN_CTX_end(ctx);
return ret;
}
BN_CTX_end(ctx);
return ret;
}
/* Computes the sum
/*-
* Computes the sum
* scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1]
* gracefully ignoring NULL scalar values.
*/
int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
{
BN_CTX *new_ctx = NULL;
int ret = 0;
size_t i;
EC_POINT *p=NULL;
EC_POINT *acc = NULL;
int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r,
const BIGNUM *scalar, size_t num,
const EC_POINT *points[], const BIGNUM *scalars[],
BN_CTX *ctx)
{
BN_CTX *new_ctx = NULL;
int ret = 0;
size_t i;
EC_POINT *p = NULL;
EC_POINT *acc = NULL;
if (ctx == NULL)
{
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
/* This implementation is more efficient than the wNAF implementation for 2
* or fewer points. Use the ec_wNAF_mul implementation for 3 or more points,
* or if we can perform a fast multiplication based on precomputation.
*/
if ((scalar && (num > 1)) || (num > 2) || (num == 0 && EC_GROUP_have_precompute_mult(group)))
{
ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
goto err;
}
/*
* This implementation is more efficient than the wNAF implementation for
* 2 or fewer points. Use the ec_wNAF_mul implementation for 3 or more
* points, or if we can perform a fast multiplication based on
* precomputation.
*/
if ((scalar && (num > 1)) || (num > 2)
|| (num == 0 && EC_GROUP_have_precompute_mult(group))) {
ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
goto err;
}
if ((p = EC_POINT_new(group)) == NULL) goto err;
if ((acc = EC_POINT_new(group)) == NULL) goto err;
if ((p = EC_POINT_new(group)) == NULL)
goto err;
if ((acc = EC_POINT_new(group)) == NULL)
goto err;
if (!EC_POINT_set_to_infinity(group, acc)) goto err;
if (!EC_POINT_set_to_infinity(group, acc))
goto err;
if (scalar)
{
if (!ec_GF2m_montgomery_point_multiply(group, p, scalar, group->generator, ctx)) goto err;
if (BN_is_negative(scalar))
if (!group->meth->invert(group, p, ctx)) goto err;
if (!group->meth->add(group, acc, acc, p, ctx)) goto err;
}
if (scalar) {
if (!ec_GF2m_montgomery_point_multiply
(group, p, scalar, group->generator, ctx))
goto err;
if (BN_is_negative(scalar))
if (!group->meth->invert(group, p, ctx))
goto err;
if (!group->meth->add(group, acc, acc, p, ctx))
goto err;
}
for (i = 0; i < num; i++)
{
if (!ec_GF2m_montgomery_point_multiply(group, p, scalars[i], points[i], ctx)) goto err;
if (BN_is_negative(scalars[i]))
if (!group->meth->invert(group, p, ctx)) goto err;
if (!group->meth->add(group, acc, acc, p, ctx)) goto err;
}
for (i = 0; i < num; i++) {
if (!ec_GF2m_montgomery_point_multiply
(group, p, scalars[i], points[i], ctx))
goto err;
if (BN_is_negative(scalars[i]))
if (!group->meth->invert(group, p, ctx))
goto err;
if (!group->meth->add(group, acc, acc, p, ctx))
goto err;
}
if (!EC_POINT_copy(r, acc)) goto err;
if (!EC_POINT_copy(r, acc))
goto err;
ret = 1;
ret = 1;
err:
if (p) EC_POINT_free(p);
if (acc) EC_POINT_free(acc);
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
return ret;
}
err:
if (p)
EC_POINT_free(p);
if (acc)
EC_POINT_free(acc);
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
return ret;
}
/* Precomputation for point multiplication: fall back to wNAF methods
* because ec_GF2m_simple_mul() uses ec_wNAF_mul() if appropriate */
/*
* Precomputation for point multiplication: fall back to wNAF methods because
* ec_GF2m_simple_mul() uses ec_wNAF_mul() if appropriate
*/
int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
{
return ec_wNAF_precompute_mult(group, ctx);
}
{
return ec_wNAF_precompute_mult(group, ctx);
}
int ec_GF2m_have_precompute_mult(const EC_GROUP *group)
{
return ec_wNAF_have_precompute_mult(group);
}
{
return ec_wNAF_have_precompute_mult(group);
}
#endif

Binary file not shown.

403
crypto/ec/ec2_oct.c Normal file
View File

@@ -0,0 +1,403 @@
/* crypto/ec/ec2_oct.c */
/* ====================================================================
* 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 software is originally written by Sheueling Chang Shantz and
* 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 "ec_lcl.h"
#ifndef OPENSSL_NO_EC2M
/*-
* Calculates and sets the affine coordinates of an EC_POINT from the given
* compressed coordinates. Uses algorithm 2.3.4 of SEC 1.
* Note that the simple implementation only uses affine coordinates.
*
* The method is from the following publication:
*
* Harper, Menezes, Vanstone:
* "Public-Key Cryptosystems with Very Small Key Lengths",
* EUROCRYPT '92, Springer-Verlag LNCS 658,
* published February 1993
*
* US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe
* the same method, but claim no priority date earlier than July 29, 1994
* (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
*/
int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group,
EC_POINT *point,
const BIGNUM *x_, int y_bit,
BN_CTX *ctx)
{
BN_CTX *new_ctx = NULL;
BIGNUM *tmp, *x, *y, *z;
int ret = 0, z0;
/* clear error queue */
ERR_clear_error();
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
y_bit = (y_bit != 0) ? 1 : 0;
BN_CTX_start(ctx);
tmp = BN_CTX_get(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
z = BN_CTX_get(ctx);
if (z == NULL)
goto err;
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))
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))
goto err;
if (!BN_GF2m_add(tmp, &group->a, tmp))
goto err;
if (!BN_GF2m_add(tmp, x, tmp))
goto err;
if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx)) {
unsigned long err = ERR_peek_last_error();
if (ERR_GET_LIB(err) == ERR_LIB_BN
&& ERR_GET_REASON(err) == BN_R_NO_SOLUTION) {
ERR_clear_error();
ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES,
EC_R_INVALID_COMPRESSED_POINT);
} else
ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES,
ERR_R_BN_LIB);
goto err;
}
z0 = (BN_is_odd(z)) ? 1 : 0;
if (!group->meth->field_mul(group, y, x, z, ctx))
goto err;
if (z0 != y_bit) {
if (!BN_GF2m_add(y, y, x))
goto err;
}
}
if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx))
goto err;
ret = 1;
err:
BN_CTX_end(ctx);
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
return ret;
}
/*
* Converts an EC_POINT to an octet string. If buf is NULL, the encoded
* length will be returned. If the length len of buf is smaller than required
* an error will be returned.
*/
size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
point_conversion_form_t form,
unsigned char *buf, size_t len, BN_CTX *ctx)
{
size_t ret;
BN_CTX *new_ctx = NULL;
int used_ctx = 0;
BIGNUM *x, *y, *yxi;
size_t field_len, i, skip;
if ((form != POINT_CONVERSION_COMPRESSED)
&& (form != POINT_CONVERSION_UNCOMPRESSED)
&& (form != POINT_CONVERSION_HYBRID)) {
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
goto err;
}
if (EC_POINT_is_at_infinity(group, point)) {
/* encodes to a single 0 octet */
if (buf != NULL) {
if (len < 1) {
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
return 0;
}
buf[0] = 0;
}
return 1;
}
/* ret := required output buffer length */
field_len = (EC_GROUP_get_degree(group) + 7) / 8;
ret =
(form ==
POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
/* if 'buf' is NULL, just return required length */
if (buf != NULL) {
if (len < ret) {
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
goto err;
}
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
BN_CTX_start(ctx);
used_ctx = 1;
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
yxi = BN_CTX_get(ctx);
if (yxi == NULL)
goto err;
if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx))
goto err;
buf[0] = form;
if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x)) {
if (!group->meth->field_div(group, yxi, y, x, ctx))
goto err;
if (BN_is_odd(yxi))
buf[0]++;
}
i = 1;
skip = field_len - BN_num_bytes(x);
if (skip > field_len) {
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
goto err;
}
while (skip > 0) {
buf[i++] = 0;
skip--;
}
skip = BN_bn2bin(x, buf + i);
i += skip;
if (i != 1 + field_len) {
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
goto err;
}
if (form == POINT_CONVERSION_UNCOMPRESSED
|| form == POINT_CONVERSION_HYBRID) {
skip = field_len - BN_num_bytes(y);
if (skip > field_len) {
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
goto err;
}
while (skip > 0) {
buf[i++] = 0;
skip--;
}
skip = BN_bn2bin(y, buf + i);
i += skip;
}
if (i != ret) {
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
goto err;
}
}
if (used_ctx)
BN_CTX_end(ctx);
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
return ret;
err:
if (used_ctx)
BN_CTX_end(ctx);
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
return 0;
}
/*
* Converts an octet string representation to an EC_POINT. Note that the
* simple implementation only uses affine coordinates.
*/
int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
const unsigned char *buf, size_t len,
BN_CTX *ctx)
{
point_conversion_form_t form;
int y_bit;
BN_CTX *new_ctx = NULL;
BIGNUM *x, *y, *yxi;
size_t field_len, enc_len;
int ret = 0;
if (len == 0) {
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
return 0;
}
form = buf[0];
y_bit = form & 1;
form = form & ~1U;
if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
&& (form != POINT_CONVERSION_UNCOMPRESSED)
&& (form != POINT_CONVERSION_HYBRID)) {
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
return 0;
}
if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
return 0;
}
if (form == 0) {
if (len != 1) {
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
return 0;
}
return EC_POINT_set_to_infinity(group, point);
}
field_len = (EC_GROUP_get_degree(group) + 7) / 8;
enc_len =
(form ==
POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
if (len != enc_len) {
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
return 0;
}
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
BN_CTX_start(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
yxi = BN_CTX_get(ctx);
if (yxi == NULL)
goto err;
if (!BN_bin2bn(buf + 1, field_len, x))
goto err;
if (BN_ucmp(x, &group->field) >= 0) {
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
goto err;
}
if (form == POINT_CONVERSION_COMPRESSED) {
if (!EC_POINT_set_compressed_coordinates_GF2m
(group, point, x, y_bit, ctx))
goto err;
} else {
if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
goto err;
if (BN_ucmp(y, &group->field) >= 0) {
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
goto err;
}
if (form == POINT_CONVERSION_HYBRID) {
if (!group->meth->field_div(group, yxi, y, x, ctx))
goto err;
if (y_bit != BN_is_odd(yxi)) {
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
goto err;
}
}
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);
return ret;
}
#endif

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -7,7 +7,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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
@@ -57,67 +57,64 @@
#include <openssl/err.h>
int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
{
int ret = 0;
BIGNUM *order;
BN_CTX *new_ctx = NULL;
EC_POINT *point = NULL;
{
int ret = 0;
BIGNUM *order;
BN_CTX *new_ctx = NULL;
EC_POINT *point = NULL;
if (ctx == NULL)
{
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
{
ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE);
goto err;
}
}
BN_CTX_start(ctx);
if ((order = BN_CTX_get(ctx)) == NULL) goto err;
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL) {
ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE);
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))
{
ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);
goto err;
}
/* check the discriminant */
if (!EC_GROUP_check_discriminant(group, ctx)) {
ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);
goto err;
}
/* check the generator */
if (group->generator == NULL)
{
ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
goto err;
}
if (!EC_POINT_is_on_curve(group, group->generator, ctx))
{
ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
goto err;
}
/* check the generator */
if (group->generator == NULL) {
ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
goto err;
}
if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) {
ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
goto err;
}
/* check the order of the generator */
if ((point = EC_POINT_new(group)) == NULL) goto err;
if (!EC_GROUP_get_order(group, order, ctx)) goto err;
if (BN_is_zero(order))
{
ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER);
goto err;
}
if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx)) goto err;
if (!EC_POINT_is_at_infinity(group, point))
{
ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER);
goto err;
}
/* check the order of the generator */
if ((point = EC_POINT_new(group)) == NULL)
goto err;
if (!EC_GROUP_get_order(group, order, ctx))
goto err;
if (BN_is_zero(order)) {
ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER);
goto err;
}
ret = 1;
if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx))
goto err;
if (!EC_POINT_is_at_infinity(group, point)) {
ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER);
goto err;
}
err:
if (ctx != NULL)
BN_CTX_end(ctx);
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
if (point)
EC_POINT_free(point);
return ret;
}
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);
return ret;
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -10,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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
@@ -58,7 +58,7 @@
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* Portions of the attached software ("Contribution") are developed by
* Portions of the attached software ("Contribution") are developed by
* SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
*
* The Contribution is licensed pursuant to the OpenSSL open source
@@ -72,73 +72,109 @@
#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;
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;
meth = EC_GFp_nist_method();
ret = EC_GROUP_new(meth);
if (ret == NULL)
return NULL;
#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
* prime method was observed to deliver better performance even
* for NIST primes on a range of platforms, e.g.: 60%-15%
* improvement on IA-64, ~25% on ARM, 30%-90% on P4, 20%-25%
* in 32-bit build and 35%--12% in 64-bit build on Core2...
* Coefficients are relative to optimized bn_nist.c for most
* intensive ECDSA verify and ECDH operations for 192- and 521-
* bit keys respectively. Choice of these boundary values is
* arguable, because the dependency of improvement coefficient
* from key length is not a "monotone" curve. For example while
* 571-bit result is 23% on ARM, 384-bit one is -1%. But it's
* generally faster, sometimes "respectfully" faster, sometimes
* "tolerably" slower... What effectively happens is that loop
* with bn_mul_add_words is put against bn_mul_mont, and the
* latter "wins" on short vectors. Correct solution should be
* implementing dedicated NxN multiplication subroutines for
* small N. But till it materializes, let's stick to generic
* prime method...
* <appro>
*/
meth = EC_GFp_mont_method();
#else
meth = EC_GFp_nist_method();
#endif
if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx))
{
unsigned long err;
err = ERR_peek_last_error();
ret = EC_GROUP_new(meth);
if (ret == NULL)
return NULL;
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 */
if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) {
unsigned long err;
ERR_clear_error();
err = ERR_peek_last_error();
EC_GROUP_clear_free(ret);
meth = EC_GFp_mont_method();
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 */
ret = EC_GROUP_new(meth);
if (ret == NULL)
return NULL;
EC_GROUP_clear_free(ret);
return NULL;
}
if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx))
{
EC_GROUP_clear_free(ret);
return NULL;
}
}
/*
* not an actual error, we just cannot use EC_GFp_nist_method
*/
return ret;
}
ERR_clear_error();
EC_GROUP_clear_free(ret);
meth = EC_GFp_mont_method();
EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
const EC_METHOD *meth;
EC_GROUP *ret;
meth = EC_GF2m_simple_method();
ret = EC_GROUP_new(meth);
if (ret == NULL)
return NULL;
ret = EC_GROUP_new(meth);
if (ret == NULL)
return NULL;
if (!EC_GROUP_set_curve_GF2m(ret, p, a, b, ctx))
{
EC_GROUP_clear_free(ret);
return NULL;
}
if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) {
EC_GROUP_clear_free(ret);
return NULL;
}
}
return ret;
}
return ret;
}
#ifndef OPENSSL_NO_EC2M
EC_GROUP *EC_GROUP_new_curve_GF2m(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_gf2m(p, a, b, ctx);
# endif
meth = EC_GF2m_simple_method();
ret = EC_GROUP_new(meth);
if (ret == NULL)
return NULL;
if (!EC_GROUP_set_curve_GF2m(ret, p, a, b, ctx)) {
EC_GROUP_clear_free(ret);
return NULL;
}
return ret;
}
#endif

Binary file not shown.

View File

@@ -1,13 +1,13 @@
/* crypto/ec/ec_err.c */
/* ====================================================================
* Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
* 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.
* 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
@@ -53,7 +53,8 @@
*
*/
/* NOTE: this file was auto generated by the mkerr.pl script: any changes
/*
* 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.
*/
@@ -65,194 +66,267 @@
/* BEGIN ERROR CODES */
#ifndef OPENSSL_NO_ERR
#define ERR_FUNC(func) ERR_PACK(ERR_LIB_EC,func,0)
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_EC,0,reason)
# define ERR_FUNC(func) ERR_PACK(ERR_LIB_EC,func,0)
# define ERR_REASON(reason) ERR_PACK(ERR_LIB_EC,0,reason)
static ERR_STRING_DATA EC_str_functs[]=
{
{ERR_FUNC(EC_F_COMPUTE_WNAF), "COMPUTE_WNAF"},
{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_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"},
{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT_FP), "ECPKParameters_print_fp"},
{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_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), "ec_GF2m_simple_group_set_curve"},
{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_OCT2POINT), "ec_GF2m_simple_oct2point"},
{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT2OCT), "ec_GF2m_simple_point2oct"},
{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES), "ec_GF2m_simple_point_get_affine_coordinates"},
{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES), "ec_GF2m_simple_point_set_affine_coordinates"},
{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES), "ec_GF2m_simple_set_compressed_coordinates"},
{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_DECODE), "ec_GFp_mont_field_decode"},
{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_ENCODE), "ec_GFp_mont_field_encode"},
{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_MUL), "ec_GFp_mont_field_mul"},
{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE), "ec_GFp_mont_field_set_to_one"},
{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_NIST_FIELD_MUL), "ec_GFp_nist_field_mul"},
{ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR), "ec_GFp_nist_field_sqr"},
{ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE), "ec_GFp_nist_group_set_curve"},
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT), "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"},
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE), "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_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_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_PRINT), "EC_KEY_print"},
{ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"},
{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"},
{ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"},
{ERR_FUNC(EC_F_EC_POINT_DBL), "EC_POINT_dbl"},
{ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M), "EC_POINT_get_affine_coordinates_GF2m"},
{ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP), "EC_POINT_get_affine_coordinates_GFp"},
{ERR_FUNC(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP), "EC_POINT_get_Jprojective_coordinates_GFp"},
{ERR_FUNC(EC_F_EC_POINT_INVERT), "EC_POINT_invert"},
{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"},
{ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M), "EC_POINT_set_affine_coordinates_GF2m"},
{ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP), "EC_POINT_set_affine_coordinates_GFp"},
{ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M), "EC_POINT_set_compressed_coordinates_GF2m"},
{ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP), "EC_POINT_set_compressed_coordinates_GFp"},
{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_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_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"},
{0,NULL}
};
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_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_ECPARAMETERS_PRINT), "ECParameters_print"},
{ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"},
{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT), "ECPKParameters_print"},
{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT_FP), "ECPKParameters_print_fp"},
{ERR_FUNC(EC_F_ECP_NISTZ256_GET_AFFINE), "ecp_nistz256_get_affine"},
{ERR_FUNC(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE),
"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_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),
"ec_GF2m_simple_group_set_curve"},
{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_OCT2POINT), "ec_GF2m_simple_oct2point"},
{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT2OCT), "ec_GF2m_simple_point2oct"},
{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES),
"ec_GF2m_simple_point_get_affine_coordinates"},
{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES),
"ec_GF2m_simple_point_set_affine_coordinates"},
{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES),
"ec_GF2m_simple_set_compressed_coordinates"},
{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_DECODE), "ec_GFp_mont_field_decode"},
{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_ENCODE), "ec_GFp_mont_field_encode"},
{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_MUL), "ec_GFp_mont_field_mul"},
{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE),
"ec_GFp_mont_field_set_to_one"},
{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"},
{ERR_FUNC(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES),
"ec_GFp_nistp224_point_get_affine_coordinates"},
{ERR_FUNC(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE),
"ec_GFp_nistp256_group_set_curve"},
{ERR_FUNC(EC_F_EC_GFP_NISTP256_POINTS_MUL), "ec_GFp_nistp256_points_mul"},
{ERR_FUNC(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES),
"ec_GFp_nistp256_point_get_affine_coordinates"},
{ERR_FUNC(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE),
"ec_GFp_nistp521_group_set_curve"},
{ERR_FUNC(EC_F_EC_GFP_NISTP521_POINTS_MUL), "ec_GFp_nistp521_points_mul"},
{ERR_FUNC(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES),
"ec_GFp_nistp521_point_get_affine_coordinates"},
{ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_MUL), "ec_GFp_nist_field_mul"},
{ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR), "ec_GFp_nist_field_sqr"},
{ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE),
"ec_GFp_nist_group_set_curve"},
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT),
"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"},
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE),
"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_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_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_PRINT), "EC_KEY_print"},
{ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"},
{ERR_FUNC(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES),
"EC_KEY_set_public_key_affine_coordinates"},
{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"},
{ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"},
{ERR_FUNC(EC_F_EC_POINT_DBL), "EC_POINT_dbl"},
{ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M),
"EC_POINT_get_affine_coordinates_GF2m"},
{ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP),
"EC_POINT_get_affine_coordinates_GFp"},
{ERR_FUNC(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP),
"EC_POINT_get_Jprojective_coordinates_GFp"},
{ERR_FUNC(EC_F_EC_POINT_INVERT), "EC_POINT_invert"},
{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"},
{ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M),
"EC_POINT_set_affine_coordinates_GF2m"},
{ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP),
"EC_POINT_set_affine_coordinates_GFp"},
{ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M),
"EC_POINT_set_compressed_coordinates_GF2m"},
{ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP),
"EC_POINT_set_compressed_coordinates_GFp"},
{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_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_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"},
{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_BUFFER_TOO_SMALL) ,"buffer too small"},
{ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE),"d2i ecpkparameters failure"},
{ERR_REASON(EC_R_DECODE_ERROR) ,"decode error"},
{ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO) ,"discriminant is zero"},
{ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),"ec group new by name failure"},
{ERR_REASON(EC_R_FIELD_TOO_LARGE) ,"field too large"},
{ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE),"group2pkparameters failure"},
{ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE),"i2d ecpkparameters failure"},
{ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS) ,"incompatible objects"},
{ERR_REASON(EC_R_INVALID_ARGUMENT) ,"invalid argument"},
{ERR_REASON(EC_R_INVALID_COMPRESSED_POINT),"invalid compressed point"},
{ERR_REASON(EC_R_INVALID_COMPRESSION_BIT),"invalid compression bit"},
{ERR_REASON(EC_R_INVALID_CURVE) ,"invalid curve"},
{ERR_REASON(EC_R_INVALID_DIGEST_TYPE) ,"invalid digest type"},
{ERR_REASON(EC_R_INVALID_ENCODING) ,"invalid encoding"},
{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_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"},
{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_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_PASSED_NULL_PARAMETER) ,"passed null parameter"},
{ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE),"pkparameters2group 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_SLOT_FULL) ,"slot full"},
{ERR_REASON(EC_R_UNDEFINED_GENERATOR) ,"undefined generator"},
{ERR_REASON(EC_R_UNDEFINED_ORDER) ,"undefined order"},
{ERR_REASON(EC_R_UNKNOWN_GROUP) ,"unknown group"},
{ERR_REASON(EC_R_UNKNOWN_ORDER) ,"unknown order"},
{ERR_REASON(EC_R_UNSUPPORTED_FIELD) ,"unsupported field"},
{ERR_REASON(EC_R_WRONG_ORDER) ,"wrong order"},
{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_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_D2I_ECPKPARAMETERS_FAILURE),
"d2i ecpkparameters failure"},
{ERR_REASON(EC_R_DECODE_ERROR), "decode error"},
{ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO), "discriminant is zero"},
{ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),
"ec group new by name failure"},
{ERR_REASON(EC_R_FIELD_TOO_LARGE), "field too large"},
{ERR_REASON(EC_R_GF2M_NOT_SUPPORTED), "gf2m not supported"},
{ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE),
"group2pkparameters failure"},
{ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE),
"i2d ecpkparameters failure"},
{ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS), "incompatible objects"},
{ERR_REASON(EC_R_INVALID_ARGUMENT), "invalid argument"},
{ERR_REASON(EC_R_INVALID_COMPRESSED_POINT), "invalid compressed point"},
{ERR_REASON(EC_R_INVALID_COMPRESSION_BIT), "invalid compression bit"},
{ERR_REASON(EC_R_INVALID_CURVE), "invalid curve"},
{ERR_REASON(EC_R_INVALID_DIGEST), "invalid digest"},
{ERR_REASON(EC_R_INVALID_DIGEST_TYPE), "invalid digest type"},
{ERR_REASON(EC_R_INVALID_ENCODING), "invalid encoding"},
{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_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"},
{ERR_REASON(EC_R_KDF_PARAMETER_ERROR), "kdf parameter error"},
{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_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_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_AT_INFINITY), "point at infinity"},
{ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE), "point is not on curve"},
{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"},
{ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"},
{ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"},
{ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"},
{ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"},
{ERR_REASON(EC_R_WRONG_CURVE_PARAMETERS), "wrong curve parameters"},
{ERR_REASON(EC_R_WRONG_ORDER), "wrong order"},
{0, NULL}
};
#endif
void ERR_load_EC_strings(void)
{
{
#ifndef OPENSSL_NO_ERR
if (ERR_func_error_string(EC_str_functs[0].error) == NULL)
{
ERR_load_strings(0,EC_str_functs);
ERR_load_strings(0,EC_str_reasons);
}
if (ERR_func_error_string(EC_str_functs[0].error) == NULL) {
ERR_load_strings(0, EC_str_functs);
ERR_load_strings(0, EC_str_reasons);
}
#endif
}
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -3,14 +3,14 @@
* Originally written by Bodo Moeller for the OpenSSL project.
*/
/* ====================================================================
* Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
* 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.
* 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
@@ -58,18 +58,17 @@
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* Portions of the attached software ("Contribution") are developed by
* Portions of the attached software ("Contribution") are developed by
* SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
*
* The Contribution is licensed pursuant to the OpenSSL open source
* license provided above.
*
* The elliptic curve binary polynomial software is originally written by
* The elliptic curve binary polynomial software is originally written by
* Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
*
*/
#include <stdlib.h>
#include <openssl/obj_mac.h>
@@ -78,224 +77,258 @@
#if defined(__SUNPRO_C)
# if __SUNPRO_C >= 0x520
# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
# endif
#endif
/* Structure details are not part of the exported interface,
* so all this may change in future versions. */
/* Use default functions for poin2oct, oct2point and compressed coordinates */
#define EC_FLAGS_DEFAULT_OCT 0x1
/*
* Structure details are not part of the exported interface, so all this may
* change in future versions.
*/
struct ec_method_st {
/* used by EC_METHOD_get_field_type: */
int field_type; /* a NID */
/* used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free, EC_GROUP_copy: */
int (*group_init)(EC_GROUP *);
void (*group_finish)(EC_GROUP *);
void (*group_clear_finish)(EC_GROUP *);
int (*group_copy)(EC_GROUP *, const EC_GROUP *);
/* used by EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, */
/* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */
int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
int (*group_get_curve)(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
/* used by EC_GROUP_get_degree: */
int (*group_get_degree)(const EC_GROUP *);
/* used by EC_GROUP_check: */
int (*group_check_discriminant)(const EC_GROUP *, BN_CTX *);
/* used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, EC_POINT_copy: */
int (*point_init)(EC_POINT *);
void (*point_finish)(EC_POINT *);
void (*point_clear_finish)(EC_POINT *);
int (*point_copy)(EC_POINT *, const EC_POINT *);
/* used by EC_POINT_set_to_infinity,
* EC_POINT_set_Jprojective_coordinates_GFp,
* EC_POINT_get_Jprojective_coordinates_GFp,
* EC_POINT_set_affine_coordinates_GFp, ..._GF2m,
* EC_POINT_get_affine_coordinates_GFp, ..._GF2m,
* EC_POINT_set_compressed_coordinates_GFp, ..._GF2m:
*/
int (*point_set_to_infinity)(const EC_GROUP *, EC_POINT *);
int (*point_set_Jprojective_coordinates_GFp)(const EC_GROUP *, EC_POINT *,
const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
int (*point_get_Jprojective_coordinates_GFp)(const EC_GROUP *, const EC_POINT *,
BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
int (*point_set_affine_coordinates)(const EC_GROUP *, EC_POINT *,
const BIGNUM *x, const BIGNUM *y, BN_CTX *);
int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
BIGNUM *x, BIGNUM *y, BN_CTX *);
int (*point_set_compressed_coordinates)(const EC_GROUP *, EC_POINT *,
const BIGNUM *x, int y_bit, BN_CTX *);
/* used by EC_POINT_point2oct, EC_POINT_oct2point: */
size_t (*point2oct)(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
unsigned char *buf, size_t len, BN_CTX *);
int (*oct2point)(const EC_GROUP *, EC_POINT *,
const unsigned char *buf, size_t len, BN_CTX *);
/* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */
int (*add)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
int (*dbl)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
int (*invert)(const EC_GROUP *, EC_POINT *, BN_CTX *);
/* used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp: */
int (*is_at_infinity)(const EC_GROUP *, const EC_POINT *);
int (*is_on_curve)(const EC_GROUP *, const EC_POINT *, BN_CTX *);
int (*point_cmp)(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
/* used by EC_POINT_make_affine, EC_POINTs_make_affine: */
int (*make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *);
int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
/* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult, EC_POINT_have_precompute_mult
* (default implementations are used if the 'mul' pointer is 0): */
int (*mul)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
int (*precompute_mult)(EC_GROUP *group, BN_CTX *);
int (*have_precompute_mult)(const EC_GROUP *group);
/* internal functions */
/* 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and 'dbl' so that
* the same implementations of point operations can be used with different
* optimized implementations of expensive field operations: */
int (*field_mul)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
int (*field_sqr)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
int (*field_div)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
int (*field_encode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. to Montgomery */
int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. from Montgomery */
int (*field_set_to_one)(const EC_GROUP *, BIGNUM *r, BN_CTX *);
} /* EC_METHOD */;
/* Various method flags */
int flags;
/* used by EC_METHOD_get_field_type: */
int field_type; /* a NID */
/*
* used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free,
* EC_GROUP_copy:
*/
int (*group_init) (EC_GROUP *);
void (*group_finish) (EC_GROUP *);
void (*group_clear_finish) (EC_GROUP *);
int (*group_copy) (EC_GROUP *, const EC_GROUP *);
/* used by EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, */
/* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */
int (*group_set_curve) (EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
int (*group_get_curve) (const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b,
BN_CTX *);
/* used by EC_GROUP_get_degree: */
int (*group_get_degree) (const EC_GROUP *);
/* used by EC_GROUP_check: */
int (*group_check_discriminant) (const EC_GROUP *, BN_CTX *);
/*
* used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free,
* EC_POINT_copy:
*/
int (*point_init) (EC_POINT *);
void (*point_finish) (EC_POINT *);
void (*point_clear_finish) (EC_POINT *);
int (*point_copy) (EC_POINT *, const EC_POINT *);
/*-
* used by EC_POINT_set_to_infinity,
* EC_POINT_set_Jprojective_coordinates_GFp,
* EC_POINT_get_Jprojective_coordinates_GFp,
* EC_POINT_set_affine_coordinates_GFp, ..._GF2m,
* EC_POINT_get_affine_coordinates_GFp, ..._GF2m,
* EC_POINT_set_compressed_coordinates_GFp, ..._GF2m:
*/
int (*point_set_to_infinity) (const EC_GROUP *, EC_POINT *);
int (*point_set_Jprojective_coordinates_GFp) (const EC_GROUP *,
EC_POINT *, const BIGNUM *x,
const BIGNUM *y,
const BIGNUM *z, BN_CTX *);
int (*point_get_Jprojective_coordinates_GFp) (const EC_GROUP *,
const EC_POINT *, BIGNUM *x,
BIGNUM *y, BIGNUM *z,
BN_CTX *);
int (*point_set_affine_coordinates) (const EC_GROUP *, EC_POINT *,
const BIGNUM *x, const BIGNUM *y,
BN_CTX *);
int (*point_get_affine_coordinates) (const EC_GROUP *, const EC_POINT *,
BIGNUM *x, BIGNUM *y, BN_CTX *);
int (*point_set_compressed_coordinates) (const EC_GROUP *, EC_POINT *,
const BIGNUM *x, int y_bit,
BN_CTX *);
/* used by EC_POINT_point2oct, EC_POINT_oct2point: */
size_t (*point2oct) (const EC_GROUP *, const EC_POINT *,
point_conversion_form_t form, unsigned char *buf,
size_t len, BN_CTX *);
int (*oct2point) (const EC_GROUP *, EC_POINT *, const unsigned char *buf,
size_t len, BN_CTX *);
/* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */
int (*add) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
const EC_POINT *b, BN_CTX *);
int (*dbl) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
int (*invert) (const EC_GROUP *, EC_POINT *, BN_CTX *);
/*
* used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp:
*/
int (*is_at_infinity) (const EC_GROUP *, const EC_POINT *);
int (*is_on_curve) (const EC_GROUP *, const EC_POINT *, BN_CTX *);
int (*point_cmp) (const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
BN_CTX *);
/* used by EC_POINT_make_affine, EC_POINTs_make_affine: */
int (*make_affine) (const EC_GROUP *, EC_POINT *, BN_CTX *);
int (*points_make_affine) (const EC_GROUP *, size_t num, EC_POINT *[],
BN_CTX *);
/*
* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult,
* EC_POINT_have_precompute_mult (default implementations are used if the
* 'mul' pointer is 0):
*/
int (*mul) (const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
BN_CTX *);
int (*precompute_mult) (EC_GROUP *group, BN_CTX *);
int (*have_precompute_mult) (const EC_GROUP *group);
/* internal functions */
/*
* 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and
* 'dbl' so that the same implementations of point operations can be used
* with different optimized implementations of expensive field
* operations:
*/
int (*field_mul) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
int (*field_sqr) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
int (*field_div) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
/* e.g. to Montgomery */
int (*field_encode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
BN_CTX *);
/* e.g. from Montgomery */
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 */ ;
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 */
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 */
struct ec_group_st {
const EC_METHOD *meth;
EC_POINT *generator; /* optional */
BIGNUM order, cofactor;
int curve_name;/* optional NID for named curve */
int asn1_flag; /* flag to control the asn1 encoding */
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 */
BIGNUM field; /* Field specification.
* For curves over GF(p), this is the modulus;
* for curves over GF(2^m), this is the
* irreducible polynomial defining the field.
*/
int poly[6]; /* 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 = poly[0] > poly[1] > ... > poly[k] = 0.
* The array is terminated with poly[k+1]=-1.
* All elliptic curve irreducibles have at most 5
* non-zero terms.
*/
BIGNUM a, b; /* Curve coefficients.
* (Here the assumption is that BIGNUMs can be used
* or abused for all kinds of fields, not just GF(p).)
* For characteristic > 3, the curve is defined
* by a Weierstrass equation of the form
* y^2 = 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.
*/
int a_is_minus3; /* enable optimized point arithmetics for special case */
void *field_data1; /* method-specific (e.g., Montgomery structure) */
void *field_data2; /* method-specific */
int (*field_mod_func)(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); /* method-specific */
} /* EC_GROUP */;
const EC_METHOD *meth;
EC_POINT *generator; /* optional */
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
*/
/*
* Field specification. For curves over GF(p), this is the modulus; for
* curves over GF(2^m), this is the irreducible polynomial defining the
* 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 =
* poly[0] > poly[1] > ... > poly[k] = 0. The array is terminated with
* poly[k+1]=-1. All elliptic curve irreducibles have at most 5 non-zero
* terms.
*/
int poly[6];
/*
* Curve coefficients. (Here the assumption is that BIGNUMs can be used
* or abused for all kinds of fields, not just GF(p).) For characteristic
* > 3, the curve is defined by a Weierstrass equation of the form y^2 =
* 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;
/* enable optimized point arithmetics for special case */
int a_is_minus3;
/* method-specific (e.g., Montgomery structure) */
void *field_data1;
/* method-specific */
void *field_data2;
/* method-specific */
int (*field_mod_func) (BIGNUM *, const BIGNUM *, const BIGNUM *,
BN_CTX *);
BN_MONT_CTX *mont_data; /* data for ECDSA inverse */
} /* EC_GROUP */ ;
struct ec_key_st {
int version;
int version;
EC_GROUP *group;
EC_POINT *pub_key;
BIGNUM *priv_key;
unsigned int enc_flag;
point_conversion_form_t conv_form;
int references;
int flags;
EC_EXTRA_DATA *method_data;
} /* EC_KEY */ ;
EC_GROUP *group;
EC_POINT *pub_key;
BIGNUM *priv_key;
unsigned int enc_flag;
point_conversion_form_t conv_form;
int references;
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.
/*
* 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 *(*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 **);
struct ec_point_st {
const EC_METHOD *meth;
const EC_METHOD *meth;
/*
* 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 */
int Z_is_one; /* enable optimized point arithmetics for
* special case */
} /* EC_POINT */ ;
/* 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 */
int Z_is_one; /* enable optimized point arithmetics for special case */
} /* EC_POINT */;
/* method functions in ec_mult.c
* (ec_lib.c uses these as defaults if group->method->mul is 0) */
/*
* method functions in ec_mult.c (ec_lib.c uses these as defaults if
* group->method->mul is 0)
*/
int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
BN_CTX *);
int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
int ec_wNAF_have_precompute_mult(const EC_GROUP *group);
/* method functions in ecp_smpl.c */
int ec_GFp_simple_group_init(EC_GROUP *);
void ec_GFp_simple_group_finish(EC_GROUP *);
void ec_GFp_simple_group_clear_finish(EC_GROUP *);
int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *);
int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p,
const BIGNUM *a, const BIGNUM *b, BN_CTX *);
int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
BIGNUM *b, BN_CTX *);
int ec_GFp_simple_group_get_degree(const EC_GROUP *);
int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
int ec_GFp_simple_point_init(EC_POINT *);
@@ -303,59 +336,81 @@ void ec_GFp_simple_point_finish(EC_POINT *);
void ec_GFp_simple_point_clear_finish(EC_POINT *);
int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *);
int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *,
const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *,
EC_POINT *, const BIGNUM *x,
const BIGNUM *y,
const BIGNUM *z, BN_CTX *);
int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *,
const EC_POINT *, BIGNUM *x,
BIGNUM *y, BIGNUM *z,
BN_CTX *);
int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
const BIGNUM *x, const BIGNUM *y, BN_CTX *);
int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *, const EC_POINT *,
BIGNUM *x, BIGNUM *y, BN_CTX *);
const BIGNUM *x,
const BIGNUM *y, BN_CTX *);
int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *,
const EC_POINT *, BIGNUM *x,
BIGNUM *y, BN_CTX *);
int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
const BIGNUM *x, int y_bit, BN_CTX *);
size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
unsigned char *buf, size_t len, BN_CTX *);
const BIGNUM *x, int y_bit,
BN_CTX *);
size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *,
point_conversion_form_t form,
unsigned char *buf, size_t len, BN_CTX *);
int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *,
const unsigned char *buf, size_t len, BN_CTX *);
int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
const unsigned char *buf, size_t len, BN_CTX *);
int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
const EC_POINT *b, BN_CTX *);
int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
BN_CTX *);
int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
BN_CTX *);
int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num,
EC_POINT *[], BN_CTX *);
int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
BN_CTX *);
/* method functions in ecp_mont.c */
int ec_GFp_mont_group_init(EC_GROUP *);
int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
void ec_GFp_mont_group_finish(EC_GROUP *);
void ec_GFp_mont_group_clear_finish(EC_GROUP *);
int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *);
int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
BN_CTX *);
int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
BN_CTX *);
int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
BN_CTX *);
int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *);
/* method functions in ecp_nist.c */
int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src);
int ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
int ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
BN_CTX *);
/* method functions in ec2_smpl.c */
int ec_GF2m_simple_group_init(EC_GROUP *);
void ec_GF2m_simple_group_finish(EC_GROUP *);
void ec_GF2m_simple_group_clear_finish(EC_GROUP *);
int ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *);
int ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
int ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
int ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p,
const BIGNUM *a, const BIGNUM *b,
BN_CTX *);
int ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
BIGNUM *b, BN_CTX *);
int ec_GF2m_simple_group_get_degree(const EC_GROUP *);
int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
int ec_GF2m_simple_point_init(EC_POINT *);
@@ -364,30 +419,150 @@ void ec_GF2m_simple_point_clear_finish(EC_POINT *);
int ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *);
int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
const BIGNUM *x, const BIGNUM *y, BN_CTX *);
int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *, const EC_POINT *,
BIGNUM *x, BIGNUM *y, BN_CTX *);
const BIGNUM *x,
const BIGNUM *y, BN_CTX *);
int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *,
const EC_POINT *, BIGNUM *x,
BIGNUM *y, BN_CTX *);
int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
const BIGNUM *x, int y_bit, BN_CTX *);
size_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
unsigned char *buf, size_t len, BN_CTX *);
const BIGNUM *x, int y_bit,
BN_CTX *);
size_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *,
point_conversion_form_t form,
unsigned char *buf, size_t len, BN_CTX *);
int ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *,
const unsigned char *buf, size_t len, BN_CTX *);
int ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
int ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
const unsigned char *buf, size_t len, BN_CTX *);
int ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
const EC_POINT *b, BN_CTX *);
int ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
BN_CTX *);
int ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
int ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
int ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
int ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
int ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
BN_CTX *);
int ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
int ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
int ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
int ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num,
EC_POINT *[], BN_CTX *);
int ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
BN_CTX *);
int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
/* method functions in ec2_mult.c */
int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r,
const BIGNUM *scalar, size_t num,
const EC_POINT *points[], const BIGNUM *scalars[],
BN_CTX *);
int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
/* method functions in ecp_nistp224.c */
int ec_GFp_nistp224_group_init(EC_GROUP *group);
int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
const BIGNUM *a, const BIGNUM *n,
BN_CTX *);
int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
const EC_POINT *point,
BIGNUM *x, BIGNUM *y,
BN_CTX *ctx);
int ec_GFp_nistp224_mul(const EC_GROUP *group, EC_POINT *r,
const BIGNUM *scalar, size_t num,
const EC_POINT *points[], const BIGNUM *scalars[],
BN_CTX *);
int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
const BIGNUM *scalar, size_t num,
const EC_POINT *points[],
const BIGNUM *scalars[], BN_CTX *ctx);
int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group);
/* method functions in ecp_nistp256.c */
int ec_GFp_nistp256_group_init(EC_GROUP *group);
int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
const BIGNUM *a, const BIGNUM *n,
BN_CTX *);
int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
const EC_POINT *point,
BIGNUM *x, BIGNUM *y,
BN_CTX *ctx);
int ec_GFp_nistp256_mul(const EC_GROUP *group, EC_POINT *r,
const BIGNUM *scalar, size_t num,
const EC_POINT *points[], const BIGNUM *scalars[],
BN_CTX *);
int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
const BIGNUM *scalar, size_t num,
const EC_POINT *points[],
const BIGNUM *scalars[], BN_CTX *ctx);
int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group);
/* method functions in ecp_nistp521.c */
int ec_GFp_nistp521_group_init(EC_GROUP *group);
int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
const BIGNUM *a, const BIGNUM *n,
BN_CTX *);
int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
const EC_POINT *point,
BIGNUM *x, BIGNUM *y,
BN_CTX *ctx);
int ec_GFp_nistp521_mul(const EC_GROUP *group, EC_POINT *r,
const BIGNUM *scalar, size_t num,
const EC_POINT *points[], const BIGNUM *scalars[],
BN_CTX *);
int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
const BIGNUM *scalar, size_t num,
const EC_POINT *points[],
const BIGNUM *scalars[], BN_CTX *ctx);
int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group);
/* utility functions in ecp_nistputil.c */
void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
size_t felem_size,
void *tmp_felems,
void (*felem_one) (void *out),
int (*felem_is_zero) (const void
*in),
void (*felem_assign) (void *out,
const void
*in),
void (*felem_square) (void *out,
const void
*in),
void (*felem_mul) (void *out,
const void
*in1,
const void
*in2),
void (*felem_inv) (void *out,
const void
*in),
void (*felem_contract) (void
*out,
const
void
*in));
void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
unsigned char *digit, unsigned char in);
#endif
int ec_precompute_mont_data(EC_GROUP *);
#ifdef ECP_NISTZ256_ASM
/** Returns GFp methods using montgomery multiplication, with x86-64 optimized
* P256. See http://eprint.iacr.org/2013/816.
* \return EC_METHOD object
*/
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

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

192
crypto/ec/ec_oct.c Normal file
View File

@@ -0,0 +1,192 @@
/* 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
* Binary polynomial ECC support in OpenSSL originally developed by
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
*/
#include <string.h>
#include <openssl/err.h>
#include <openssl/opensslv.h>
#include "ec_lcl.h"
int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
EC_POINT *point, const BIGNUM *x,
int y_bit, BN_CTX *ctx)
{
if (group->meth->point_set_compressed_coordinates == 0
&& !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP,
ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP,
EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
if (group->meth->field_type == NID_X9_62_prime_field)
return ec_GFp_simple_set_compressed_coordinates(group, point, x,
y_bit, ctx);
else
#ifdef OPENSSL_NO_EC2M
{
ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP,
EC_R_GF2M_NOT_SUPPORTED);
return 0;
}
#else
return ec_GF2m_simple_set_compressed_coordinates(group, point, x,
y_bit, ctx);
#endif
}
return group->meth->point_set_compressed_coordinates(group, point, x,
y_bit, ctx);
}
#ifndef OPENSSL_NO_EC2M
int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group,
EC_POINT *point, const BIGNUM *x,
int y_bit, BN_CTX *ctx)
{
if (group->meth->point_set_compressed_coordinates == 0
&& !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M,
ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M,
EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
if (group->meth->field_type == NID_X9_62_prime_field)
return ec_GFp_simple_set_compressed_coordinates(group, point, x,
y_bit, ctx);
else
return ec_GF2m_simple_set_compressed_coordinates(group, point, x,
y_bit, ctx);
}
return group->meth->point_set_compressed_coordinates(group, point, x,
y_bit, ctx);
}
#endif
size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point,
point_conversion_form_t form, unsigned char *buf,
size_t len, BN_CTX *ctx)
{
if (group->meth->point2oct == 0
&& !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
if (group->meth->field_type == NID_X9_62_prime_field)
return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx);
else
#ifdef OPENSSL_NO_EC2M
{
ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_GF2M_NOT_SUPPORTED);
return 0;
}
#else
return ec_GF2m_simple_point2oct(group, point,
form, buf, len, ctx);
#endif
}
return group->meth->point2oct(group, point, form, buf, len, ctx);
}
int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
const unsigned char *buf, size_t len, BN_CTX *ctx)
{
if (group->meth->oct2point == 0
&& !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
if (group->meth->field_type == NID_X9_62_prime_field)
return ec_GFp_simple_oct2point(group, point, buf, len, ctx);
else
#ifdef OPENSSL_NO_EC2M
{
ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_GF2M_NOT_SUPPORTED);
return 0;
}
#else
return ec_GF2m_simple_oct2point(group, point, buf, len, ctx);
#endif
}
return group->meth->oct2point(group, point, buf, len, ctx);
}

View File

@@ -1,5 +1,6 @@
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2006.
/*
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
* 2006.
*/
/* ====================================================================
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
@@ -9,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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
@@ -60,281 +61,470 @@
#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"
/* EC pkey context structure */
typedef struct
{
/* Key and paramgen group */
EC_GROUP *gen_group;
/* message digest */
const EVP_MD *md;
} EC_PKEY_CTX;
typedef struct {
/* Key and paramgen group */
EC_GROUP *gen_group;
/* message digest */
const EVP_MD *md;
/* Duplicate key if custom cofactor needed */
EC_KEY *co_key;
/* Cofactor mode */
signed char cofactor_mode;
/* KDF (if any) to use for ECDH */
char kdf_type;
/* Message digest to use for key derivation */
const EVP_MD *kdf_md;
/* User key material */
unsigned char *kdf_ukm;
size_t kdf_ukmlen;
/* KDF output length */
size_t kdf_outlen;
} EC_PKEY_CTX;
static int pkey_ec_init(EVP_PKEY_CTX *ctx)
{
EC_PKEY_CTX *dctx;
dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX));
if (!dctx)
return 0;
dctx->gen_group = NULL;
dctx->md = NULL;
{
EC_PKEY_CTX *dctx;
dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX));
if (!dctx)
return 0;
dctx->gen_group = NULL;
dctx->md = NULL;
ctx->data = dctx;
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;
return 1;
}
ctx->data = dctx;
return 1;
}
static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
{
EC_PKEY_CTX *dctx, *sctx;
if (!pkey_ec_init(dst))
return 0;
sctx = src->data;
dctx = dst->data;
if (sctx->gen_group)
{
dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
if (!dctx->gen_group)
return 0;
}
dctx->md = sctx->md;
return 1;
}
{
EC_PKEY_CTX *dctx, *sctx;
if (!pkey_ec_init(dst))
return 0;
sctx = src->data;
dctx = dst->data;
if (sctx->gen_group) {
dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
if (!dctx->gen_group)
return 0;
}
dctx->md = sctx->md;
if (sctx->co_key) {
dctx->co_key = EC_KEY_dup(sctx->co_key);
if (!dctx->co_key)
return 0;
}
dctx->kdf_type = sctx->kdf_type;
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);
if (!dctx->kdf_ukm)
return 0;
} else
dctx->kdf_ukm = NULL;
dctx->kdf_ukmlen = sctx->kdf_ukmlen;
return 1;
}
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);
OPENSSL_free(dctx);
}
}
{
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);
OPENSSL_free(dctx);
}
}
static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
const unsigned char *tbs, size_t tbslen)
{
int ret, type;
unsigned int sltmp;
EC_PKEY_CTX *dctx = ctx->data;
EC_KEY *ec = ctx->pkey->pkey.ec;
const unsigned char *tbs, size_t tbslen)
{
int ret, type;
unsigned int sltmp;
EC_PKEY_CTX *dctx = ctx->data;
EC_KEY *ec = ctx->pkey->pkey.ec;
if (!sig)
{
*siglen = ECDSA_size(ec);
return 1;
}
else if(*siglen < (size_t)ECDSA_size(ec))
{
ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL);
return 0;
}
if (!sig) {
*siglen = ECDSA_size(ec);
return 1;
} else if (*siglen < (size_t)ECDSA_size(ec)) {
ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL);
return 0;
}
if (dctx->md)
type = EVP_MD_type(dctx->md);
else
type = NID_sha1;
if (dctx->md)
type = EVP_MD_type(dctx->md);
else
type = NID_sha1;
ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
if (ret <= 0)
return ret;
*siglen = (size_t)sltmp;
return 1;
}
if (ret <= 0)
return ret;
*siglen = (size_t)sltmp;
return 1;
}
static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
const unsigned char *sig, size_t siglen,
const unsigned char *tbs, size_t tbslen)
{
int ret, type;
EC_PKEY_CTX *dctx = ctx->data;
EC_KEY *ec = ctx->pkey->pkey.ec;
const unsigned char *sig, size_t siglen,
const unsigned char *tbs, size_t tbslen)
{
int ret, type;
EC_PKEY_CTX *dctx = ctx->data;
EC_KEY *ec = ctx->pkey->pkey.ec;
if (dctx->md)
type = EVP_MD_type(dctx->md);
else
type = NID_sha1;
if (dctx->md)
type = EVP_MD_type(dctx->md);
else
type = NID_sha1;
ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
return ret;
}
return ret;
}
static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
{
int ret;
size_t outlen;
const EC_POINT *pubkey = NULL;
if (!ctx->pkey || !ctx->peerkey)
{
ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET);
return 0;
}
#ifndef OPENSSL_NO_ECDH
static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
size_t *keylen)
{
int ret;
size_t outlen;
const EC_POINT *pubkey = NULL;
EC_KEY *eckey;
EC_PKEY_CTX *dctx = ctx->data;
if (!ctx->pkey || !ctx->peerkey) {
ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET);
return 0;
}
if (!key)
{
const EC_GROUP *group;
group = EC_KEY_get0_group(ctx->pkey->pkey.ec);
*keylen = (EC_GROUP_get_degree(group) + 7)/8;
return 1;
}
eckey = dctx->co_key ? dctx->co_key : ctx->pkey->pkey.ec;
pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
if (!key) {
const EC_GROUP *group;
group = EC_KEY_get0_group(eckey);
*keylen = (EC_GROUP_get_degree(group) + 7) / 8;
return 1;
}
pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
/* NB: unlike PKS#3 DH, if *outlen is less than maximum size this is
* not an error, the result is truncated.
*/
/*
* NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is not
* an error, the result is truncated.
*/
outlen = *keylen;
ret = ECDH_compute_key(key, outlen, pubkey, ctx->pkey->pkey.ec, 0);
if (ret < 0)
return ret;
*keylen = ret;
return 1;
}
outlen = *keylen;
ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0);
if (ret <= 0)
return 0;
*keylen = ret;
return 1;
}
static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx,
unsigned char *key, size_t *keylen)
{
EC_PKEY_CTX *dctx = ctx->data;
unsigned char *ktmp = NULL;
size_t ktmplen;
int rv = 0;
if (dctx->kdf_type == EVP_PKEY_ECDH_KDF_NONE)
return pkey_ec_derive(ctx, key, keylen);
if (!key) {
*keylen = dctx->kdf_outlen;
return 1;
}
if (*keylen != dctx->kdf_outlen)
return 0;
if (!pkey_ec_derive(ctx, NULL, &ktmplen))
return 0;
ktmp = OPENSSL_malloc(ktmplen);
if (!ktmp)
return 0;
if (!pkey_ec_derive(ctx, ktmp, &ktmplen))
goto err;
/* Do KDF stuff */
if (!ECDH_KDF_X9_62(key, *keylen, ktmp, ktmplen,
dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
goto err;
rv = 1;
err:
if (ktmp) {
OPENSSL_cleanse(ktmp, ktmplen);
OPENSSL_free(ktmp);
}
return rv;
}
#endif
static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
EC_PKEY_CTX *dctx = ctx->data;
EC_GROUP *group;
switch (type)
{
case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
group = EC_GROUP_new_by_curve_name(p1);
if (group == NULL)
{
ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
return 0;
}
if (dctx->gen_group)
EC_GROUP_free(dctx->gen_group);
dctx->gen_group = group;
return 1;
{
EC_PKEY_CTX *dctx = ctx->data;
EC_GROUP *group;
switch (type) {
case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
group = EC_GROUP_new_by_curve_name(p1);
if (group == NULL) {
ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
return 0;
}
if (dctx->gen_group)
EC_GROUP_free(dctx->gen_group);
dctx->gen_group = group;
return 1;
case EVP_PKEY_CTRL_MD:
if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha512)
{
ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
return 0;
}
dctx->md = p2;
return 1;
case EVP_PKEY_CTRL_EC_PARAM_ENC:
if (!dctx->gen_group) {
ECerr(EC_F_PKEY_EC_CTRL, EC_R_NO_PARAMETERS_SET);
return 0;
}
EC_GROUP_set_asn1_flag(dctx->gen_group, p1);
return 1;
case EVP_PKEY_CTRL_PEER_KEY:
/* Default behaviour is OK */
case EVP_PKEY_CTRL_DIGESTINIT:
case EVP_PKEY_CTRL_PKCS7_SIGN:
case EVP_PKEY_CTRL_CMS_SIGN:
return 1;
#ifndef OPENSSL_NO_ECDH
case EVP_PKEY_CTRL_EC_ECDH_COFACTOR:
if (p1 == -2) {
if (dctx->cofactor_mode != -1)
return dctx->cofactor_mode;
else {
EC_KEY *ec_key = ctx->pkey->pkey.ec;
return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 :
0;
}
} else if (p1 < -1 || p1 > 1)
return -2;
dctx->cofactor_mode = p1;
if (p1 != -1) {
EC_KEY *ec_key = ctx->pkey->pkey.ec;
if (!ec_key->group)
return -2;
/* If cofactor is 1 cofactor mode does nothing */
if (BN_is_one(&ec_key->group->cofactor))
return 1;
if (!dctx->co_key) {
dctx->co_key = EC_KEY_dup(ec_key);
if (!dctx->co_key)
return 0;
}
if (p1)
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) {
EC_KEY_free(dctx->co_key);
dctx->co_key = NULL;
}
return 1;
#endif
default:
return -2;
case EVP_PKEY_CTRL_EC_KDF_TYPE:
if (p1 == -2)
return dctx->kdf_type;
if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_62)
return -2;
dctx->kdf_type = p1;
return 1;
case EVP_PKEY_CTRL_EC_KDF_MD:
dctx->kdf_md = p2;
return 1;
case EVP_PKEY_CTRL_GET_EC_KDF_MD:
*(const EVP_MD **)p2 = dctx->kdf_md;
return 1;
case EVP_PKEY_CTRL_EC_KDF_OUTLEN:
if (p1 <= 0)
return -2;
dctx->kdf_outlen = (size_t)p1;
return 1;
case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN:
*(int *)p2 = dctx->kdf_outlen;
return 1;
case EVP_PKEY_CTRL_EC_KDF_UKM:
if (dctx->kdf_ukm)
OPENSSL_free(dctx->kdf_ukm);
dctx->kdf_ukm = p2;
if (p2)
dctx->kdf_ukmlen = p1;
else
dctx->kdf_ukmlen = 0;
return 1;
case EVP_PKEY_CTRL_GET_EC_KDF_UKM:
*(unsigned char **)p2 = dctx->kdf_ukm;
return dctx->kdf_ukmlen;
case EVP_PKEY_CTRL_MD:
if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
return 0;
}
dctx->md = p2;
return 1;
case EVP_PKEY_CTRL_GET_MD:
*(const EVP_MD **)p2 = dctx->md;
return 1;
case EVP_PKEY_CTRL_PEER_KEY:
/* Default behaviour is OK */
case EVP_PKEY_CTRL_DIGESTINIT:
case EVP_PKEY_CTRL_PKCS7_SIGN:
case EVP_PKEY_CTRL_CMS_SIGN:
return 1;
default:
return -2;
}
}
}
}
static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
const char *type, const char *value)
{
if (!strcmp(type, "ec_paramgen_curve"))
{
int nid;
nid = OBJ_sn2nid(value);
if (nid == NID_undef)
nid = OBJ_ln2nid(value);
if (nid == NID_undef)
{
ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE);
return 0;
}
return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
}
return -2;
}
const char *type, const char *value)
{
if (!strcmp(type, "ec_paramgen_curve")) {
int nid;
nid = EC_curve_nist2nid(value);
if (nid == NID_undef)
nid = OBJ_sn2nid(value);
if (nid == NID_undef)
nid = OBJ_ln2nid(value);
if (nid == NID_undef) {
ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE);
return 0;
}
return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
} else if (!strcmp(type, "ec_param_enc")) {
int param_enc;
if (!strcmp(value, "explicit"))
param_enc = 0;
else if (!strcmp(value, "named_curve"))
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")) {
const EVP_MD *md;
if (!(md = EVP_get_digestbyname(value))) {
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")) {
int co_mode;
co_mode = atoi(value);
return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, co_mode);
}
return -2;
}
static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
{
EC_KEY *ec = NULL;
EC_PKEY_CTX *dctx = ctx->data;
int ret = 0;
if (dctx->gen_group == NULL)
{
ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET);
return 0;
}
ec = EC_KEY_new();
if (!ec)
return 0;
ret = EC_KEY_set_group(ec, dctx->gen_group);
if (ret)
EVP_PKEY_assign_EC_KEY(pkey, ec);
else
EC_KEY_free(ec);
return ret;
}
{
EC_KEY *ec = NULL;
EC_PKEY_CTX *dctx = ctx->data;
int ret = 0;
if (dctx->gen_group == NULL) {
ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET);
return 0;
}
ec = EC_KEY_new();
if (!ec)
return 0;
ret = EC_KEY_set_group(ec, dctx->gen_group);
if (ret)
EVP_PKEY_assign_EC_KEY(pkey, ec);
else
EC_KEY_free(ec);
return ret;
}
static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
{
EC_KEY *ec = NULL;
if (ctx->pkey == NULL)
{
ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
return 0;
}
ec = EC_KEY_new();
if (!ec)
return 0;
EVP_PKEY_assign_EC_KEY(pkey, ec);
/* Note: if error return, pkey is freed by parent routine */
if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
return 0;
return EC_KEY_generate_key(pkey->pkey.ec);
}
{
EC_KEY *ec = NULL;
EC_PKEY_CTX *dctx = ctx->data;
if (ctx->pkey == NULL && dctx->gen_group == NULL) {
ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
return 0;
}
ec = EC_KEY_new();
if (!ec)
return 0;
EVP_PKEY_assign_EC_KEY(pkey, ec);
if (ctx->pkey) {
/* Note: if error return, pkey is freed by parent routine */
if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
return 0;
} else {
if (!EC_KEY_set_group(ec, dctx->gen_group))
return 0;
}
return EC_KEY_generate_key(pkey->pkey.ec);
}
const EVP_PKEY_METHOD ec_pkey_meth =
{
EVP_PKEY_EC,
0,
pkey_ec_init,
pkey_ec_copy,
pkey_ec_cleanup,
const EVP_PKEY_METHOD ec_pkey_meth = {
EVP_PKEY_EC,
0,
pkey_ec_init,
pkey_ec_copy,
pkey_ec_cleanup,
0,
pkey_ec_paramgen,
0,
pkey_ec_paramgen,
0,
pkey_ec_keygen,
0,
pkey_ec_keygen,
0,
pkey_ec_sign,
0,
pkey_ec_sign,
0,
pkey_ec_verify,
0,
pkey_ec_verify,
0,0,
0, 0,
0,0,0,0,
0, 0, 0, 0,
0,0,
0, 0,
0,0,
0, 0,
0,
pkey_ec_derive,
0,
#ifndef OPENSSL_NO_ECDH
pkey_ec_kdf_derive,
#else
0,
#endif
pkey_ec_ctrl,
pkey_ec_ctrl_str
};
pkey_ec_ctrl,
pkey_ec_ctrl_str
};

Binary file not shown.

View File

@@ -7,7 +7,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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
@@ -56,140 +56,124 @@
#include <openssl/crypto.h>
#include "ec_lcl.h"
BIGNUM *EC_POINT_point2bn(const EC_GROUP *group,
const EC_POINT *point,
BIGNUM *EC_POINT_point2bn(const EC_GROUP *group,
const EC_POINT *point,
point_conversion_form_t form,
BIGNUM *ret,
BN_CTX *ctx)
{
size_t buf_len=0;
unsigned char *buf;
BIGNUM *ret, BN_CTX *ctx)
{
size_t buf_len = 0;
unsigned char *buf;
buf_len = EC_POINT_point2oct(group, point, form,
NULL, 0, ctx);
if (buf_len == 0)
return NULL;
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 ((buf = OPENSSL_malloc(buf_len)) == NULL)
return NULL;
if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx))
{
OPENSSL_free(buf);
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);
ret = BN_bin2bn(buf, buf_len, ret);
OPENSSL_free(buf);
OPENSSL_free(buf);
return ret;
return ret;
}
EC_POINT *EC_POINT_bn2point(const EC_GROUP *group,
const BIGNUM *bn,
EC_POINT *point,
BN_CTX *ctx)
{
size_t buf_len=0;
unsigned char *buf;
EC_POINT *ret;
const BIGNUM *bn, EC_POINT *point, BN_CTX *ctx)
{
size_t buf_len = 0;
unsigned char *buf;
EC_POINT *ret;
if ((buf_len = BN_num_bytes(bn)) == 0) return NULL;
buf = OPENSSL_malloc(buf_len);
if (buf == NULL)
return NULL;
if ((buf_len = BN_num_bytes(bn)) == 0)
return NULL;
buf = OPENSSL_malloc(buf_len);
if (buf == NULL)
return NULL;
if (!BN_bn2bin(bn, buf))
{
OPENSSL_free(buf);
return NULL;
}
if (!BN_bn2bin(bn, buf)) {
OPENSSL_free(buf);
return NULL;
}
if (point == NULL)
{
if ((ret = EC_POINT_new(group)) == NULL)
{
OPENSSL_free(buf);
return NULL;
}
}
else
ret = point;
if (point == NULL) {
if ((ret = EC_POINT_new(group)) == NULL) {
OPENSSL_free(buf);
return NULL;
}
} else
ret = point;
if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx))
{
if (point == NULL)
EC_POINT_clear_free(ret);
OPENSSL_free(buf);
return NULL;
}
if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) {
if (point == NULL)
EC_POINT_clear_free(ret);
OPENSSL_free(buf);
return NULL;
}
OPENSSL_free(buf);
return ret;
}
OPENSSL_free(buf);
return ret;
}
static const char *HEX_DIGITS = "0123456789ABCDEF";
/* the return value must be freed (using OPENSSL_free()) */
char *EC_POINT_point2hex(const EC_GROUP *group,
const EC_POINT *point,
point_conversion_form_t form,
BN_CTX *ctx)
{
char *ret, *p;
size_t buf_len=0,i;
unsigned char *buf, *pbuf;
point_conversion_form_t form, BN_CTX *ctx)
{
char *ret, *p;
size_t buf_len = 0, i;
unsigned char *buf, *pbuf;
buf_len = EC_POINT_point2oct(group, point, form,
NULL, 0, ctx);
if (buf_len == 0)
return NULL;
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 ((buf = OPENSSL_malloc(buf_len)) == NULL)
return NULL;
if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx))
{
OPENSSL_free(buf);
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);
if (ret == NULL)
{
OPENSSL_free(buf);
return NULL;
}
p = ret;
pbuf = buf;
for (i=buf_len; i > 0; i--)
{
int v = (int) *(pbuf++);
*(p++)=HEX_DIGITS[v>>4];
*(p++)=HEX_DIGITS[v&0x0F];
}
*p='\0';
ret = (char *)OPENSSL_malloc(buf_len * 2 + 2);
if (ret == NULL) {
OPENSSL_free(buf);
return NULL;
}
p = ret;
pbuf = buf;
for (i = buf_len; i > 0; i--) {
int v = (int)*(pbuf++);
*(p++) = HEX_DIGITS[v >> 4];
*(p++) = HEX_DIGITS[v & 0x0F];
}
*p = '\0';
OPENSSL_free(buf);
OPENSSL_free(buf);
return ret;
}
return ret;
}
EC_POINT *EC_POINT_hex2point(const EC_GROUP *group,
const char *buf,
EC_POINT *point,
BN_CTX *ctx)
{
EC_POINT *ret=NULL;
BIGNUM *tmp_bn=NULL;
const char *buf, EC_POINT *point, BN_CTX *ctx)
{
EC_POINT *ret = NULL;
BIGNUM *tmp_bn = NULL;
if (!BN_hex2bn(&tmp_bn, buf))
return NULL;
if (!BN_hex2bn(&tmp_bn, buf))
return NULL;
ret = EC_POINT_bn2point(group, tmp_bn, point, ctx);
ret = EC_POINT_bn2point(group, tmp_bn, point, ctx);
BN_clear_free(tmp_bn);
BN_clear_free(tmp_bn);
return ret;
}
return ret;
}

Binary file not shown.

View File

@@ -10,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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
@@ -57,7 +57,7 @@
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
* Portions originally developed by SUN MICROSYSTEMS, INC., and
* Portions originally developed by SUN MICROSYSTEMS, INC., and
* contributed to the OpenSSL project.
*/
@@ -69,323 +69,309 @@
#ifndef OPENSSL_NO_FP_API
int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
{
BIO *b;
int ret;
{
BIO *b;
int ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
{
ECerr(EC_F_ECPKPARAMETERS_PRINT_FP,ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b, fp, BIO_NOCLOSE);
ret = ECPKParameters_print(b, x, off);
BIO_free(b);
return(ret);
}
if ((b = BIO_new(BIO_s_file())) == NULL) {
ECerr(EC_F_ECPKPARAMETERS_PRINT_FP, ERR_R_BUF_LIB);
return (0);
}
BIO_set_fp(b, fp, BIO_NOCLOSE);
ret = ECPKParameters_print(b, x, off);
BIO_free(b);
return (ret);
}
int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
{
BIO *b;
int ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
{
ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
return(0);
}
BIO_set_fp(b, fp, BIO_NOCLOSE);
ret = EC_KEY_print(b, x, off);
BIO_free(b);
return(ret);
}
{
BIO *b;
int ret;
if ((b = BIO_new(BIO_s_file())) == NULL) {
ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
return (0);
}
BIO_set_fp(b, fp, BIO_NOCLOSE);
ret = EC_KEY_print(b, x, off);
BIO_free(b);
return (ret);
}
int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
{
BIO *b;
int ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
{
ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
return(0);
}
BIO_set_fp(b, fp, BIO_NOCLOSE);
ret = ECParameters_print(b, x);
BIO_free(b);
return(ret);
}
{
BIO *b;
int ret;
if ((b = BIO_new(BIO_s_file())) == NULL) {
ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
return (0);
}
BIO_set_fp(b, fp, BIO_NOCLOSE);
ret = ECParameters_print(b, x);
BIO_free(b);
return (ret);
}
#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;
}
{
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;
}
{
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);
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;
const unsigned char *seed;
size_t seed_len=0;
static const char *gen_compressed = "Generator (compressed):";
static const char *gen_uncompressed = "Generator (uncompressed):";
static const char *gen_hybrid = "Generator (hybrid):";
if (!x)
{
reason = ERR_R_PASSED_NULL_PARAMETER;
goto err;
}
{
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;
const unsigned char *seed;
size_t seed_len = 0;
ctx = BN_CTX_new();
if (ctx == NULL)
{
reason = ERR_R_MALLOC_FAILURE;
goto err;
}
static const char *gen_compressed = "Generator (compressed):";
static const char *gen_uncompressed = "Generator (uncompressed):";
static const char *gen_hybrid = "Generator (hybrid):";
if (EC_GROUP_get_asn1_flag(x))
{
/* the curve parameter are given by an asn1 OID */
int nid;
if (!x) {
reason = ERR_R_PASSED_NULL_PARAMETER;
goto err;
}
if (!BIO_indent(bp, off, 128))
goto err;
ctx = BN_CTX_new();
if (ctx == NULL) {
reason = ERR_R_MALLOC_FAILURE;
goto err;
}
nid = EC_GROUP_get_curve_name(x);
if (nid == 0)
goto err;
if (EC_GROUP_get_asn1_flag(x)) {
/* the curve parameter are given by an asn1 OID */
int nid;
const char *nname;
if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
goto err;
if (BIO_printf(bp, "\n") <= 0)
goto err;
}
else
{
/* explicit parameters */
int is_char_two = 0;
point_conversion_form_t form;
int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
if (!BIO_indent(bp, off, 128))
goto err;
if (tmp_nid == NID_X9_62_characteristic_two_field)
is_char_two = 1;
nid = EC_GROUP_get_curve_name(x);
if (nid == 0)
goto err;
if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
(b = BN_new()) == NULL || (order = BN_new()) == NULL ||
(cofactor = BN_new()) == NULL)
{
reason = ERR_R_MALLOC_FAILURE;
goto err;
}
if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
goto err;
if (BIO_printf(bp, "\n") <= 0)
goto err;
nname = EC_curve_nid2nist(nid);
if (nname) {
if (!BIO_indent(bp, off, 128))
goto err;
if (BIO_printf(bp, "NIST CURVE: %s\n", nname) <= 0)
goto err;
}
} else {
/* explicit parameters */
int is_char_two = 0;
point_conversion_form_t form;
int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
if (is_char_two)
{
if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx))
{
reason = ERR_R_EC_LIB;
goto err;
}
}
else /* prime field */
{
if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx))
{
reason = ERR_R_EC_LIB;
goto err;
}
}
if (tmp_nid == NID_X9_62_characteristic_two_field)
is_char_two = 1;
if ((point = EC_GROUP_get0_generator(x)) == NULL)
{
reason = ERR_R_EC_LIB;
goto err;
}
if (!EC_GROUP_get_order(x, order, NULL) ||
!EC_GROUP_get_cofactor(x, cofactor, NULL))
{
reason = ERR_R_EC_LIB;
goto err;
}
form = EC_GROUP_get_point_conversion_form(x);
if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
(b = BN_new()) == NULL || (order = BN_new()) == NULL ||
(cofactor = BN_new()) == NULL) {
reason = ERR_R_MALLOC_FAILURE;
goto err;
}
#ifndef OPENSSL_NO_EC2M
if (is_char_two) {
if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) {
reason = ERR_R_EC_LIB;
goto err;
}
} else /* prime field */
#endif
{
if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) {
reason = ERR_R_EC_LIB;
goto err;
}
}
if ((gen = EC_POINT_point2bn(x, point,
form, NULL, ctx)) == NULL)
{
reason = ERR_R_EC_LIB;
goto err;
}
if ((point = EC_GROUP_get0_generator(x)) == NULL) {
reason = ERR_R_EC_LIB;
goto err;
}
if (!EC_GROUP_get_order(x, order, NULL) ||
!EC_GROUP_get_cofactor(x, cofactor, NULL)) {
reason = ERR_R_EC_LIB;
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;
form = EC_GROUP_get_point_conversion_form(x);
if ((seed = EC_GROUP_get0_seed(x)) != NULL)
seed_len = EC_GROUP_get_seed_len(x);
if ((gen = EC_POINT_point2bn(x, point, form, NULL, ctx)) == NULL) {
reason = ERR_R_EC_LIB;
goto err;
}
buf_len += 10;
if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
{
reason = ERR_R_MALLOC_FAILURE;
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 (!BIO_indent(bp, off, 128))
goto err;
if ((seed = EC_GROUP_get0_seed(x)) != NULL)
seed_len = EC_GROUP_get_seed_len(x);
/* print the 'short name' of the field type */
if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
<= 0)
goto err;
buf_len += 10;
if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
reason = ERR_R_MALLOC_FAILURE;
goto err;
}
if (is_char_two)
{
/* print the 'short name' of the base type OID */
int basis_type = EC_GROUP_get_basis_type(x);
if (basis_type == 0)
goto err;
if (!BIO_indent(bp, off, 128))
goto err;
if (!BIO_indent(bp, off, 128))
goto err;
/* print the 'short name' of the field type */
if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
<= 0)
goto err;
if (BIO_printf(bp, "Basis Type: %s\n",
OBJ_nid2sn(basis_type)) <= 0)
goto err;
if (is_char_two) {
/* print the 'short name' of the base type OID */
int basis_type = EC_GROUP_get_basis_type(x);
if (basis_type == 0)
goto err;
/* print the polynomial */
if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer,
off))
goto err;
}
else
{
if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer,off))
goto err;
}
if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off))
goto err;
if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off))
goto err;
if (form == POINT_CONVERSION_COMPRESSED)
{
if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
buffer, off))
goto err;
}
else if (form == POINT_CONVERSION_UNCOMPRESSED)
{
if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
buffer, off))
goto err;
}
else /* form == POINT_CONVERSION_HYBRID */
{
if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
buffer, off))
goto err;
}
if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order,
buffer, off)) goto err;
if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor,
buffer, off)) goto err;
if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
goto err;
}
ret=1;
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);
return(ret);
}
if (!BIO_indent(bp, off, 128))
goto err;
if (BIO_printf(bp, "Basis Type: %s\n",
OBJ_nid2sn(basis_type)) <= 0)
goto err;
/* print the polynomial */
if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer,
off))
goto err;
} else {
if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer, off))
goto err;
}
if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off))
goto err;
if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off))
goto err;
if (form == POINT_CONVERSION_COMPRESSED) {
if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
buffer, off))
goto err;
} else if (form == POINT_CONVERSION_UNCOMPRESSED) {
if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
buffer, off))
goto err;
} else { /* form == POINT_CONVERSION_HYBRID */
if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
buffer, off))
goto err;
}
if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order,
buffer, off))
goto err;
if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor,
buffer, off))
goto err;
if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
goto err;
}
ret = 1;
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);
return (ret);
}
static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
size_t len, int off)
{
size_t i;
char str[128];
size_t len, int off)
{
size_t i;
char str[128];
if (buf == NULL)
return 1;
if (off)
{
if (off > 128)
off=128;
memset(str,' ',off);
if (BIO_write(fp, str, off) <= 0)
return 0;
}
if (buf == NULL)
return 1;
if (off > 0) {
if (off > 128)
off = 128;
memset(str, ' ', off);
if (BIO_write(fp, str, off) <= 0)
return 0;
} else {
off = 0;
}
if (BIO_printf(fp,"%s", name) <= 0)
return 0;
if (BIO_printf(fp, "%s", name) <= 0)
return 0;
for (i=0; i<len; i++)
{
if ((i%15) == 0)
{
str[0]='\n';
memset(&(str[1]),' ',off+4);
if (BIO_write(fp, str, off+1+4) <= 0)
return 0;
}
if (BIO_printf(fp,"%02x%s",buf[i],((i+1) == len)?"":":") <= 0)
return 0;
}
if (BIO_write(fp,"\n",1) <= 0)
return 0;
for (i = 0; i < len; i++) {
if ((i % 15) == 0) {
str[0] = '\n';
memset(&(str[1]), ' ', off + 4);
if (BIO_write(fp, str, off + 1 + 4) <= 0)
return 0;
}
if (BIO_printf(fp, "%02x%s", buf[i], ((i + 1) == len) ? "" : ":") <=
0)
return 0;
}
if (BIO_write(fp, "\n", 1) <= 0)
return 0;
return 1;
}
return 1;
}

Binary file not shown.

View File

@@ -10,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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
@@ -63,253 +63,246 @@
#include <openssl/err.h>
#ifdef OPENSSL_FIPS
# include <openssl/fips.h>
#endif
#include "ec_lcl.h"
const EC_METHOD *EC_GFp_mont_method(void)
{
static const EC_METHOD ret = {
NID_X9_62_prime_field,
ec_GFp_mont_group_init,
ec_GFp_mont_group_finish,
ec_GFp_mont_group_clear_finish,
ec_GFp_mont_group_copy,
ec_GFp_mont_group_set_curve,
ec_GFp_simple_group_get_curve,
ec_GFp_simple_group_get_degree,
ec_GFp_simple_group_check_discriminant,
ec_GFp_simple_point_init,
ec_GFp_simple_point_finish,
ec_GFp_simple_point_clear_finish,
ec_GFp_simple_point_copy,
ec_GFp_simple_point_set_to_infinity,
ec_GFp_simple_set_Jprojective_coordinates_GFp,
ec_GFp_simple_get_Jprojective_coordinates_GFp,
ec_GFp_simple_point_set_affine_coordinates,
ec_GFp_simple_point_get_affine_coordinates,
ec_GFp_simple_set_compressed_coordinates,
ec_GFp_simple_point2oct,
ec_GFp_simple_oct2point,
ec_GFp_simple_add,
ec_GFp_simple_dbl,
ec_GFp_simple_invert,
ec_GFp_simple_is_at_infinity,
ec_GFp_simple_is_on_curve,
ec_GFp_simple_cmp,
ec_GFp_simple_make_affine,
ec_GFp_simple_points_make_affine,
0 /* mul */,
0 /* precompute_mult */,
0 /* have_precompute_mult */,
ec_GFp_mont_field_mul,
ec_GFp_mont_field_sqr,
0 /* field_div */,
ec_GFp_mont_field_encode,
ec_GFp_mont_field_decode,
ec_GFp_mont_field_set_to_one };
{
static const EC_METHOD ret = {
EC_FLAGS_DEFAULT_OCT,
NID_X9_62_prime_field,
ec_GFp_mont_group_init,
ec_GFp_mont_group_finish,
ec_GFp_mont_group_clear_finish,
ec_GFp_mont_group_copy,
ec_GFp_mont_group_set_curve,
ec_GFp_simple_group_get_curve,
ec_GFp_simple_group_get_degree,
ec_GFp_simple_group_check_discriminant,
ec_GFp_simple_point_init,
ec_GFp_simple_point_finish,
ec_GFp_simple_point_clear_finish,
ec_GFp_simple_point_copy,
ec_GFp_simple_point_set_to_infinity,
ec_GFp_simple_set_Jprojective_coordinates_GFp,
ec_GFp_simple_get_Jprojective_coordinates_GFp,
ec_GFp_simple_point_set_affine_coordinates,
ec_GFp_simple_point_get_affine_coordinates,
0, 0, 0,
ec_GFp_simple_add,
ec_GFp_simple_dbl,
ec_GFp_simple_invert,
ec_GFp_simple_is_at_infinity,
ec_GFp_simple_is_on_curve,
ec_GFp_simple_cmp,
ec_GFp_simple_make_affine,
ec_GFp_simple_points_make_affine,
0 /* mul */ ,
0 /* precompute_mult */ ,
0 /* have_precompute_mult */ ,
ec_GFp_mont_field_mul,
ec_GFp_mont_field_sqr,
0 /* field_div */ ,
ec_GFp_mont_field_encode,
ec_GFp_mont_field_decode,
ec_GFp_mont_field_set_to_one
};
return &ret;
}
#ifdef OPENSSL_FIPS
if (FIPS_mode())
return fips_ec_gfp_mont_method();
#endif
return &ret;
}
int ec_GFp_mont_group_init(EC_GROUP *group)
{
int ok;
ok = ec_GFp_simple_group_init(group);
group->field_data1 = NULL;
group->field_data2 = NULL;
return ok;
}
{
int ok;
ok = ec_GFp_simple_group_init(group);
group->field_data1 = NULL;
group->field_data2 = NULL;
return ok;
}
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;
}
ec_GFp_simple_group_finish(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;
}
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;
}
ec_GFp_simple_group_clear_finish(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;
}
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;
}
{
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;
}
if (!ec_GFp_simple_group_copy(dest, src)) return 0;
if (!ec_GFp_simple_group_copy(dest, src))
return 0;
if (src->field_data1 != NULL)
{
dest->field_data1 = BN_MONT_CTX_new();
if (dest->field_data1 == NULL) return 0;
if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1)) goto err;
}
if (src->field_data2 != NULL)
{
dest->field_data2 = BN_dup(src->field_data2);
if (dest->field_data2 == NULL) goto err;
}
if (src->field_data1 != NULL) {
dest->field_data1 = BN_MONT_CTX_new();
if (dest->field_data1 == NULL)
return 0;
if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1))
goto err;
}
if (src->field_data2 != NULL) {
dest->field_data2 = BN_dup(src->field_data2);
if (dest->field_data2 == NULL)
goto err;
}
return 1;
return 1;
err:
if (dest->field_data1 != NULL)
{
BN_MONT_CTX_free(dest->field_data1);
dest->field_data1 = NULL;
}
return 0;
}
if (dest->field_data1 != NULL) {
BN_MONT_CTX_free(dest->field_data1);
dest->field_data1 = NULL;
}
return 0;
}
int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
BN_CTX *new_ctx = NULL;
BN_MONT_CTX *mont = NULL;
BIGNUM *one = NULL;
int ret = 0;
int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
BN_CTX *new_ctx = NULL;
BN_MONT_CTX *mont = NULL;
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;
}
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;
}
if (ctx == NULL)
{
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
mont = BN_MONT_CTX_new();
if (mont == NULL) goto err;
if (!BN_MONT_CTX_set(mont, p, ctx))
{
ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB);
goto err;
}
one = BN_new();
if (one == NULL) goto err;
if (!BN_to_montgomery(one, BN_value_one(), mont, ctx)) goto err;
mont = BN_MONT_CTX_new();
if (mont == NULL)
goto err;
if (!BN_MONT_CTX_set(mont, p, ctx)) {
ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB);
goto err;
}
one = BN_new();
if (one == NULL)
goto err;
if (!BN_to_montgomery(one, BN_value_one(), mont, ctx))
goto err;
group->field_data1 = mont;
mont = NULL;
group->field_data2 = one;
one = NULL;
group->field_data1 = mont;
mont = NULL;
group->field_data2 = one;
one = NULL;
ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
if (!ret)
{
BN_MONT_CTX_free(group->field_data1);
group->field_data1 = NULL;
BN_free(group->field_data2);
group->field_data2 = NULL;
}
if (!ret) {
BN_MONT_CTX_free(group->field_data1);
group->field_data1 = NULL;
BN_free(group->field_data2);
group->field_data2 = NULL;
}
err:
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
if (mont != NULL)
BN_MONT_CTX_free(mont);
return ret;
}
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
if (mont != NULL)
BN_MONT_CTX_free(mont);
return ret;
}
int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
const BIGNUM *b, BN_CTX *ctx)
{
if (group->field_data1 == NULL) {
ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED);
return 0;
}
int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
if (group->field_data1 == NULL)
{
ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED);
return 0;
}
return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx);
}
return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx);
}
int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
BN_CTX *ctx)
{
if (group->field_data1 == NULL) {
ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED);
return 0;
}
return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx);
}
int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
{
if (group->field_data1 == NULL)
{
ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED);
return 0;
}
int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r,
const BIGNUM *a, BN_CTX *ctx)
{
if (group->field_data1 == NULL) {
ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED);
return 0;
}
return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx);
}
return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx);
}
int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r,
const BIGNUM *a, BN_CTX *ctx)
{
if (group->field_data1 == NULL) {
ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED);
return 0;
}
int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
{
if (group->field_data1 == NULL)
{
ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED);
return 0;
}
return BN_from_montgomery(r, a, group->field_data1, ctx);
}
return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx);
}
int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r,
BN_CTX *ctx)
{
if (group->field_data2 == NULL) {
ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED);
return 0;
}
int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
{
if (group->field_data1 == NULL)
{
ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED);
return 0;
}
return BN_from_montgomery(r, a, group->field_data1, ctx);
}
int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, BN_CTX *ctx)
{
if (group->field_data2 == NULL)
{
ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED);
return 0;
}
if (!BN_copy(r, group->field_data2)) return 0;
return 1;
}
if (!BN_copy(r, group->field_data2))
return 0;
return 1;
}

Binary file not shown.

View File

@@ -10,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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
@@ -67,144 +67,154 @@
#include <openssl/obj_mac.h>
#include "ec_lcl.h"
const EC_METHOD *EC_GFp_nist_method(void)
{
static const EC_METHOD ret = {
NID_X9_62_prime_field,
ec_GFp_simple_group_init,
ec_GFp_simple_group_finish,
ec_GFp_simple_group_clear_finish,
ec_GFp_nist_group_copy,
ec_GFp_nist_group_set_curve,
ec_GFp_simple_group_get_curve,
ec_GFp_simple_group_get_degree,
ec_GFp_simple_group_check_discriminant,
ec_GFp_simple_point_init,
ec_GFp_simple_point_finish,
ec_GFp_simple_point_clear_finish,
ec_GFp_simple_point_copy,
ec_GFp_simple_point_set_to_infinity,
ec_GFp_simple_set_Jprojective_coordinates_GFp,
ec_GFp_simple_get_Jprojective_coordinates_GFp,
ec_GFp_simple_point_set_affine_coordinates,
ec_GFp_simple_point_get_affine_coordinates,
ec_GFp_simple_set_compressed_coordinates,
ec_GFp_simple_point2oct,
ec_GFp_simple_oct2point,
ec_GFp_simple_add,
ec_GFp_simple_dbl,
ec_GFp_simple_invert,
ec_GFp_simple_is_at_infinity,
ec_GFp_simple_is_on_curve,
ec_GFp_simple_cmp,
ec_GFp_simple_make_affine,
ec_GFp_simple_points_make_affine,
0 /* mul */,
0 /* precompute_mult */,
0 /* have_precompute_mult */,
ec_GFp_nist_field_mul,
ec_GFp_nist_field_sqr,
0 /* field_div */,
0 /* field_encode */,
0 /* field_decode */,
0 /* field_set_to_one */ };
#ifdef OPENSSL_FIPS
# include <openssl/fips.h>
#endif
return &ret;
}
const EC_METHOD *EC_GFp_nist_method(void)
{
static const EC_METHOD ret = {
EC_FLAGS_DEFAULT_OCT,
NID_X9_62_prime_field,
ec_GFp_simple_group_init,
ec_GFp_simple_group_finish,
ec_GFp_simple_group_clear_finish,
ec_GFp_nist_group_copy,
ec_GFp_nist_group_set_curve,
ec_GFp_simple_group_get_curve,
ec_GFp_simple_group_get_degree,
ec_GFp_simple_group_check_discriminant,
ec_GFp_simple_point_init,
ec_GFp_simple_point_finish,
ec_GFp_simple_point_clear_finish,
ec_GFp_simple_point_copy,
ec_GFp_simple_point_set_to_infinity,
ec_GFp_simple_set_Jprojective_coordinates_GFp,
ec_GFp_simple_get_Jprojective_coordinates_GFp,
ec_GFp_simple_point_set_affine_coordinates,
ec_GFp_simple_point_get_affine_coordinates,
0, 0, 0,
ec_GFp_simple_add,
ec_GFp_simple_dbl,
ec_GFp_simple_invert,
ec_GFp_simple_is_at_infinity,
ec_GFp_simple_is_on_curve,
ec_GFp_simple_cmp,
ec_GFp_simple_make_affine,
ec_GFp_simple_points_make_affine,
0 /* mul */ ,
0 /* precompute_mult */ ,
0 /* have_precompute_mult */ ,
ec_GFp_nist_field_mul,
ec_GFp_nist_field_sqr,
0 /* field_div */ ,
0 /* field_encode */ ,
0 /* field_decode */ ,
0 /* field_set_to_one */
};
#ifdef OPENSSL_FIPS
if (FIPS_mode())
return fips_ec_gfp_nist_method();
#endif
return &ret;
}
int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)
{
dest->field_mod_func = src->field_mod_func;
{
dest->field_mod_func = src->field_mod_func;
return ec_GFp_simple_group_copy(dest, src);
}
return ec_GFp_simple_group_copy(dest, src);
}
int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
int ret = 0;
BN_CTX *new_ctx = NULL;
BIGNUM *tmp_bn;
if (ctx == NULL)
if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
int ret = 0;
BN_CTX *new_ctx = NULL;
BIGNUM *tmp_bn;
BN_CTX_start(ctx);
if ((tmp_bn = BN_CTX_get(ctx)) == NULL) goto err;
if (ctx == NULL)
if ((ctx = new_ctx = BN_CTX_new()) == NULL)
return 0;
if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
group->field_mod_func = BN_nist_mod_192;
else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
group->field_mod_func = BN_nist_mod_224;
else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0)
group->field_mod_func = BN_nist_mod_256;
else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0)
group->field_mod_func = BN_nist_mod_384;
else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
group->field_mod_func = BN_nist_mod_521;
else
{
ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME);
goto err;
}
BN_CTX_start(ctx);
if ((tmp_bn = BN_CTX_get(ctx)) == NULL)
goto err;
ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
group->field_mod_func = BN_nist_mod_192;
else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
group->field_mod_func = BN_nist_mod_224;
else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0)
group->field_mod_func = BN_nist_mod_256;
else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0)
group->field_mod_func = BN_nist_mod_384;
else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
group->field_mod_func = BN_nist_mod_521;
else {
ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME);
goto err;
}
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);
return ret;
}
BN_CTX_end(ctx);
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
return ret;
}
int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
const BIGNUM *b, BN_CTX *ctx)
{
int ret=0;
BN_CTX *ctx_new=NULL;
const BIGNUM *b, BN_CTX *ctx)
{
int ret = 0;
BN_CTX *ctx_new = NULL;
if (!group || !r || !a || !b)
{
ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER);
goto err;
}
if (!ctx)
if ((ctx_new = ctx = BN_CTX_new()) == NULL) goto err;
if (!group || !r || !a || !b) {
ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER);
goto err;
}
if (!ctx)
if ((ctx_new = ctx = BN_CTX_new()) == NULL)
goto err;
if (!BN_mul(r, a, b, ctx)) goto err;
if (!group->field_mod_func(r, r, &group->field, ctx))
goto err;
ret=1;
err:
if (ctx_new)
BN_CTX_free(ctx_new);
return ret;
}
if (!BN_mul(r, a, b, ctx))
goto err;
if (!group->field_mod_func(r, r, &group->field, ctx))
goto err;
ret = 1;
err:
if (ctx_new)
BN_CTX_free(ctx_new);
return ret;
}
int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
BN_CTX *ctx)
{
int ret=0;
BN_CTX *ctx_new=NULL;
BN_CTX *ctx)
{
int ret = 0;
BN_CTX *ctx_new = NULL;
if (!group || !r || !a)
{
ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER);
goto err;
}
if (!ctx)
if ((ctx_new = ctx = BN_CTX_new()) == NULL) goto err;
if (!group || !r || !a) {
ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER);
goto err;
}
if (!ctx)
if ((ctx_new = ctx = BN_CTX_new()) == NULL)
goto err;
if (!BN_sqr(r, a, ctx)) goto err;
if (!group->field_mod_func(r, r, &group->field, ctx))
goto err;
if (!BN_sqr(r, a, ctx))
goto err;
if (!group->field_mod_func(r, r, &group->field, ctx))
goto err;
ret=1;
err:
if (ctx_new)
BN_CTX_free(ctx_new);
return ret;
}
ret = 1;
err:
if (ctx_new)
BN_CTX_free(ctx_new);
return ret;
}

Binary file not shown.

1769
crypto/ec/ecp_nistp224.c Normal file

File diff suppressed because it is too large Load Diff

2369
crypto/ec/ecp_nistp256.c Normal file

File diff suppressed because it is too large Load Diff

2148
crypto/ec/ecp_nistp521.c Normal file

File diff suppressed because it is too large Load Diff

218
crypto/ec/ecp_nistputil.c Normal file
View File

@@ -0,0 +1,218 @@
/* crypto/ec/ecp_nistputil.c */
/*
* Written by Bodo Moeller for the OpenSSL project.
*/
/* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
*
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
/*
* Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c.
*/
# include <stddef.h>
# include "ec_lcl.h"
/*
* Convert an array of points into affine coordinates. (If the point at
* infinity is found (Z = 0), it remains unchanged.) This function is
* essentially an equivalent to EC_POINTs_make_affine(), but works with the
* internal representation of points as used by ecp_nistp###.c rather than
* with (BIGNUM-based) EC_POINT data structures. point_array is the
* input/output buffer ('num' points in projective form, i.e. three
* coordinates each), based on an internal representation of field elements
* of size 'felem_size'. tmp_felems needs to point to a temporary array of
* 'num'+1 field elements for storage of intermediate values.
*/
void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
size_t felem_size,
void *tmp_felems,
void (*felem_one) (void *out),
int (*felem_is_zero) (const void
*in),
void (*felem_assign) (void *out,
const void
*in),
void (*felem_square) (void *out,
const void
*in),
void (*felem_mul) (void *out,
const void
*in1,
const void
*in2),
void (*felem_inv) (void *out,
const void
*in),
void (*felem_contract) (void
*out,
const
void
*in))
{
int i = 0;
# define tmp_felem(I) (&((char *)tmp_felems)[(I) * felem_size])
# define X(I) (&((char *)point_array)[3*(I) * felem_size])
# define Y(I) (&((char *)point_array)[(3*(I) + 1) * felem_size])
# define Z(I) (&((char *)point_array)[(3*(I) + 2) * felem_size])
if (!felem_is_zero(Z(0)))
felem_assign(tmp_felem(0), Z(0));
else
felem_one(tmp_felem(0));
for (i = 1; i < (int)num; i++) {
if (!felem_is_zero(Z(i)))
felem_mul(tmp_felem(i), tmp_felem(i - 1), Z(i));
else
felem_assign(tmp_felem(i), tmp_felem(i - 1));
}
/*
* Now each tmp_felem(i) is the product of Z(0) .. Z(i), skipping any
* zero-valued factors: if Z(i) = 0, we essentially pretend that Z(i) = 1
*/
felem_inv(tmp_felem(num - 1), tmp_felem(num - 1));
for (i = num - 1; i >= 0; i--) {
if (i > 0)
/*
* tmp_felem(i-1) is the product of Z(0) .. Z(i-1), tmp_felem(i)
* is the inverse of the product of Z(0) .. Z(i)
*/
/* 1/Z(i) */
felem_mul(tmp_felem(num), tmp_felem(i - 1), tmp_felem(i));
else
felem_assign(tmp_felem(num), tmp_felem(0)); /* 1/Z(0) */
if (!felem_is_zero(Z(i))) {
if (i > 0)
/*
* For next iteration, replace tmp_felem(i-1) by its inverse
*/
felem_mul(tmp_felem(i - 1), tmp_felem(i), Z(i));
/*
* Convert point (X, Y, Z) into affine form (X/(Z^2), Y/(Z^3), 1)
*/
felem_square(Z(i), tmp_felem(num)); /* 1/(Z^2) */
felem_mul(X(i), X(i), Z(i)); /* X/(Z^2) */
felem_mul(Z(i), Z(i), tmp_felem(num)); /* 1/(Z^3) */
felem_mul(Y(i), Y(i), Z(i)); /* Y/(Z^3) */
felem_contract(X(i), X(i));
felem_contract(Y(i), Y(i));
felem_one(Z(i));
} else {
if (i > 0)
/*
* For next iteration, replace tmp_felem(i-1) by its inverse
*/
felem_assign(tmp_felem(i - 1), tmp_felem(i));
}
}
}
/*-
* This function looks at 5+1 scalar bits (5 current, 1 adjacent less
* significant bit), and recodes them into a signed digit for use in fast point
* multiplication: the use of signed rather than unsigned digits means that
* fewer points need to be precomputed, given that point inversion is easy
* (a precomputed point dP makes -dP available as well).
*
* BACKGROUND:
*
* Signed digits for multiplication were introduced by Booth ("A signed binary
* multiplication technique", Quart. Journ. Mech. and Applied Math., vol. IV,
* pt. 2 (1951), pp. 236-240), in that case for multiplication of integers.
* Booth's original encoding did not generally improve the density of nonzero
* digits over the binary representation, and was merely meant to simplify the
* handling of signed factors given in two's complement; but it has since been
* shown to be the basis of various signed-digit representations that do have
* further advantages, including the wNAF, using the following general approach:
*
* (1) Given a binary representation
*
* b_k ... b_2 b_1 b_0,
*
* of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1
* by using bit-wise subtraction as follows:
*
* b_k b_(k-1) ... b_2 b_1 b_0
* - b_k ... b_3 b_2 b_1 b_0
* -------------------------------------
* s_k b_(k-1) ... s_3 s_2 s_1 s_0
*
* A left-shift followed by subtraction of the original value yields a new
* representation of the same value, using signed bits s_i = b_(i+1) - b_i.
* This representation from Booth's paper has since appeared in the
* literature under a variety of different names including "reversed binary
* form", "alternating greedy expansion", "mutual opposite form", and
* "sign-alternating {+-1}-representation".
*
* An interesting property is that among the nonzero bits, values 1 and -1
* strictly alternate.
*
* (2) Various window schemes can be applied to the Booth representation of
* integers: for example, right-to-left sliding windows yield the wNAF
* (a signed-digit encoding independently discovered by various researchers
* in the 1990s), and left-to-right sliding windows yield a left-to-right
* equivalent of the wNAF (independently discovered by various researchers
* around 2004).
*
* To prevent leaking information through side channels in point multiplication,
* we need to recode the given integer into a regular pattern: sliding windows
* as in wNAFs won't do, we need their fixed-window equivalent -- which is a few
* decades older: we'll be using the so-called "modified Booth encoding" due to
* MacSorley ("High-speed arithmetic in binary computers", Proc. IRE, vol. 49
* (1961), pp. 67-91), in a radix-2^5 setting. That is, we always combine five
* signed bits into a signed digit:
*
* s_(4j + 4) s_(4j + 3) s_(4j + 2) s_(4j + 1) s_(4j)
*
* The sign-alternating property implies that the resulting digit values are
* integers from -16 to 16.
*
* Of course, we don't actually need to compute the signed digits s_i as an
* intermediate step (that's just a nice way to see how this scheme relates
* to the wNAF): a direct computation obtains the recoded digit from the
* six bits b_(4j + 4) ... b_(4j - 1).
*
* This function takes those five bits as an integer (0 .. 63), writing the
* recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute
* value, in the range 0 .. 8). Note that this integer essentially provides the
* input bits "shifted to the left" by one position: for example, the input to
* compute the least significant recoded digit, given that there's no bit b_-1,
* has to be b_4 b_3 b_2 b_1 b_0 0.
*
*/
void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
unsigned char *digit, unsigned char in)
{
unsigned char s, d;
s = ~((in >> 5) - 1); /* sets all bits to MSB(in), 'in' seen as
* 6-bit value */
d = (1 << 6) - in - 1;
d = (d & s) | (in & ~s);
d = (d >> 1) + (d & 1);
*sign = s & 1;
*digit = d;
}
#else
static void *dummy = &dummy;
#endif

1521
crypto/ec/ecp_nistz256.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

428
crypto/ec/ecp_oct.c Normal file
View File

@@ -0,0 +1,428 @@
/* 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
* Portions of this software developed by SUN MICROSYSTEMS, INC.,
* and contributed to the OpenSSL project.
*/
#include <openssl/err.h>
#include <openssl/symhacks.h>
#include "ec_lcl.h"
int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
EC_POINT *point,
const BIGNUM *x_, int y_bit,
BN_CTX *ctx)
{
BN_CTX *new_ctx = NULL;
BIGNUM *tmp1, *tmp2, *x, *y;
int ret = 0;
/* clear error queue */
ERR_clear_error();
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
y_bit = (y_bit != 0);
BN_CTX_start(ctx);
tmp1 = BN_CTX_get(ctx);
tmp2 = BN_CTX_get(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
if (y == NULL)
goto err;
/*-
* Recover y. We have a Weierstrass equation
* y^2 = x^3 + a*x + b,
* so y is one of the square roots of x^3 + a*x + b.
*/
/* tmp1 := x^3 */
if (!BN_nnmod(x, x_, &group->field, ctx))
goto err;
if (group->meth->field_decode == 0) {
/* field_{sqr,mul} work on standard representation */
if (!group->meth->field_sqr(group, tmp2, x_, ctx))
goto err;
if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx))
goto err;
} else {
if (!BN_mod_sqr(tmp2, x_, &group->field, ctx))
goto err;
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))
goto err;
if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field))
goto err;
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))
goto err;
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))
goto err;
}
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))
goto err;
if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field))
goto err;
} else {
if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field))
goto err;
}
if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) {
unsigned long err = ERR_peek_last_error();
if (ERR_GET_LIB(err) == ERR_LIB_BN
&& ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
ERR_clear_error();
ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
EC_R_INVALID_COMPRESSED_POINT);
} else
ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
ERR_R_BN_LIB);
goto err;
}
if (y_bit != BN_is_odd(y)) {
if (BN_is_zero(y)) {
int kron;
kron = BN_kronecker(x, &group->field, ctx);
if (kron == -2)
goto err;
if (kron == 1)
ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
EC_R_INVALID_COMPRESSION_BIT);
else
/*
* BN_mod_sqrt() should have cought this error (not a square)
*/
ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
EC_R_INVALID_COMPRESSED_POINT);
goto err;
}
if (!BN_usub(y, &group->field, y))
goto err;
}
if (y_bit != BN_is_odd(y)) {
ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
ERR_R_INTERNAL_ERROR);
goto err;
}
if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
goto err;
ret = 1;
err:
BN_CTX_end(ctx);
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
return ret;
}
size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
point_conversion_form_t form,
unsigned char *buf, size_t len, BN_CTX *ctx)
{
size_t ret;
BN_CTX *new_ctx = NULL;
int used_ctx = 0;
BIGNUM *x, *y;
size_t field_len, i, skip;
if ((form != POINT_CONVERSION_COMPRESSED)
&& (form != POINT_CONVERSION_UNCOMPRESSED)
&& (form != POINT_CONVERSION_HYBRID)) {
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
goto err;
}
if (EC_POINT_is_at_infinity(group, point)) {
/* encodes to a single 0 octet */
if (buf != NULL) {
if (len < 1) {
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
return 0;
}
buf[0] = 0;
}
return 1;
}
/* ret := required output buffer length */
field_len = BN_num_bytes(&group->field);
ret =
(form ==
POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
/* if 'buf' is NULL, just return required length */
if (buf != NULL) {
if (len < ret) {
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
goto err;
}
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
BN_CTX_start(ctx);
used_ctx = 1;
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
if (y == NULL)
goto err;
if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx))
goto err;
if ((form == POINT_CONVERSION_COMPRESSED
|| form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
buf[0] = form + 1;
else
buf[0] = form;
i = 1;
skip = field_len - BN_num_bytes(x);
if (skip > field_len) {
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
goto err;
}
while (skip > 0) {
buf[i++] = 0;
skip--;
}
skip = BN_bn2bin(x, buf + i);
i += skip;
if (i != 1 + field_len) {
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
goto err;
}
if (form == POINT_CONVERSION_UNCOMPRESSED
|| form == POINT_CONVERSION_HYBRID) {
skip = field_len - BN_num_bytes(y);
if (skip > field_len) {
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
goto err;
}
while (skip > 0) {
buf[i++] = 0;
skip--;
}
skip = BN_bn2bin(y, buf + i);
i += skip;
}
if (i != ret) {
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
goto err;
}
}
if (used_ctx)
BN_CTX_end(ctx);
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
return ret;
err:
if (used_ctx)
BN_CTX_end(ctx);
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
return 0;
}
int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
const unsigned char *buf, size_t len, BN_CTX *ctx)
{
point_conversion_form_t form;
int y_bit;
BN_CTX *new_ctx = NULL;
BIGNUM *x, *y;
size_t field_len, enc_len;
int ret = 0;
if (len == 0) {
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
return 0;
}
form = buf[0];
y_bit = form & 1;
form = form & ~1U;
if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
&& (form != POINT_CONVERSION_UNCOMPRESSED)
&& (form != POINT_CONVERSION_HYBRID)) {
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
return 0;
}
if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
return 0;
}
if (form == 0) {
if (len != 1) {
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
return 0;
}
return EC_POINT_set_to_infinity(group, point);
}
field_len = BN_num_bytes(&group->field);
enc_len =
(form ==
POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
if (len != enc_len) {
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
return 0;
}
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
BN_CTX_start(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
if (y == NULL)
goto err;
if (!BN_bin2bn(buf + 1, field_len, x))
goto err;
if (BN_ucmp(x, &group->field) >= 0) {
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
goto err;
}
if (form == POINT_CONVERSION_COMPRESSED) {
if (!EC_POINT_set_compressed_coordinates_GFp
(group, point, x, y_bit, ctx))
goto err;
} else {
if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
goto err;
if (BN_ucmp(y, &group->field) >= 0) {
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
goto err;
}
if (form == POINT_CONVERSION_HYBRID) {
if (y_bit != BN_is_odd(y)) {
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
goto err;
}
}
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);
return ret;
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File