Changes between 1.0.1 and 1.1.0 [xx XXX xxxx]
+ *) New build option no-ec2m to disable characteristic 2 code.
+ [Steve Henson]
+
*) New build option "fipscanisteronly". This only builds fipscanister.o
and (currently) associated fips utilities. Uses the file Makefile.fips
instead of Makefile.org as the prototype.
#include "cryptlib.h"
#include "bn_lcl.h"
+#ifndef OPENSSL_NO_EC2M
+
/* Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should fail. */
#define MAX_ITERATIONS 50
return 1;
}
+#endif
message(out,"BN_mod_sqrt");
if (!test_sqrt(out,ctx)) goto err;
(void)BIO_flush(out);
-
+#ifndef OPENSSL_NO_EC2M
message(out,"BN_GF2m_add");
if (!test_gf2m_add(out)) goto err;
(void)BIO_flush(out);
message(out,"BN_GF2m_mod_solve_quad");
if (!test_gf2m_mod_solve_quad(out,ctx)) goto err;
(void)BIO_flush(out);
-
+#endif
BN_CTX_free(ctx);
BIO_free(out);
BN_free(one);
return(1);
}
-
+#ifndef OPENSSL_NO_EC2M
int test_gf2m_add(BIO *bp)
{
BIGNUM a,b,c;
BN_free(e);
return ret;
}
-
+#endif
static int genprime_cb(int p, int n, BN_GENCB *arg)
{
char c='*';
#endif
#endif
-
+#ifndef OPENSSL_NO_EC2M
/********************************************************************/
/* EC_METHOD for curves over GF(2^m) */
/********************************************************************/
*/
const EC_METHOD *EC_GF2m_simple_method(void);
+#endif
+
/********************************************************************/
/* EC_GROUP functions */
*/
int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
+#ifndef OPENSSL_NO_EC2M
/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
* \param group EC_GROUP object
* \param p BIGNUM with the polynomial defining the underlying field
* \return 1 on success and 0 if an error occured
*/
int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
-
+#endif
/** Returns the number of bits needed to represent a field element
* \param group EC_GROUP object
* \return number of bits needed to represent a field element
* \return newly created EC_GROUP object with the specified parameters
*/
EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
-
+#ifndef OPENSSL_NO_EC2M
/** Creates a new EC_GROUP object with the specified parameters defined
* over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b)
* \param p BIGNUM with the polynomial defining the underlying field
* \return newly created EC_GROUP object with the specified parameters
*/
EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
-
+#endif
/** Creates a EC_GROUP object with a curve specified by a NID
* \param nid NID of the OID of the curve name
* \return newly created EC_GROUP object with specified curve or NULL
*/
int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
const BIGNUM *x, int y_bit, BN_CTX *ctx);
-
+#ifndef OPENSSL_NO_EC2M
/** Sets the affine coordinates of a EC_POINT over GF2m
* \param group underlying EC_GROUP object
* \param p EC_POINT object
*/
int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
const BIGNUM *x, int y_bit, BN_CTX *ctx);
-
+#endif
/** Encodes a EC_POINT object to a octet string
* \param group underlying EC_GROUP object
* \param p EC_POINT object
#define EC_R_DISCRIMINANT_IS_ZERO 118
#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119
#define EC_R_FIELD_TOO_LARGE 143
+#define EC_R_GF2M_NOT_SUPPORTED 147
#define EC_R_GROUP2PKPARAMETERS_FAILURE 120
#define EC_R_I2D_ECPKPARAMETERS_FAILURE 121
#define EC_R_INCOMPATIBLE_OBJECTS 101
#include "ec_lcl.h"
+#ifndef OPENSSL_NO_EC2M
+
/* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective
* coordinates.
{
return ec_wNAF_have_precompute_mult(group);
}
+
+#endif
#include "ec_lcl.h"
+#ifndef OPENSSL_NO_EC2M
+
const EC_METHOD *EC_GF2m_simple_method(void)
{
{
return BN_GF2m_mod_div(r, a, b, &group->field, ctx);
}
+
+#endif
/* everything else is currently not supported */
return 0;
}
-
+#ifndef OPENSSL_NO_EC2M
int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
{
if (group == NULL)
return 1;
}
-
int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
unsigned int *k2, unsigned int *k3)
{
return 1;
}
-
+#endif
/* some structures needed for the asn1 encoding */
}
}
else /* nid == NID_X9_62_characteristic_two_field */
+#ifdef OPENSSL_NO_EC2M
+ {
+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED);
+ goto err;
+ }
+#else
{
int field_type;
X9_62_CHARACTERISTIC_TWO *char_two;
}
}
}
+#endif
ok = 1;
goto err;
}
}
+#ifndef OPENSSL_NO_EC2M
else /* nid == NID_X9_62_characteristic_two_field */
{
if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL))
goto err;
}
}
-
+#endif
len_1 = (size_t)BN_num_bytes(tmp_1);
len_2 = (size_t)BN_num_bytes(tmp_2);
/* get the field parameters */
tmp = OBJ_obj2nid(params->fieldID->fieldType);
-
if (tmp == NID_X9_62_characteristic_two_field)
+#ifdef OPENSSL_NO_EC2M
+ {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_GF2M_NOT_SUPPORTED);
+ goto err;
+ }
+#else
{
X9_62_CHARACTERISTIC_TWO *char_two;
/* create the EC_GROUP structure */
ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
}
+#endif
else if (tmp == NID_X9_62_prime_field)
{
/* we have a curve over a prime field */
if ((group = ec_asn1_pkparameters2group(params)) == NULL)
{
ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
+ ECPKPARAMETERS_free(params);
return NULL;
}
0x13,0xDD,0x29,0x45,0x5C,0x5C,0x2A,0x3D }
};
+#ifndef OPENSSL_NO_EC2M
+
/* characteristic two curves */
static const struct { EC_CURVE_DATA h; unsigned char data[20+15*6]; }
_EC_SECG_CHAR2_113R1 = {
0xBA,0xFC,0xA7,0x5E }
};
+#endif
+
typedef struct _ec_list_element_st {
int nid;
const EC_CURVE_DATA *data;
{ NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0, "X9.62 curve over a 239 bit prime field" },
{ NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0, "X9.62 curve over a 239 bit prime field" },
{ NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, 0, "X9.62/SECG curve over a 256 bit prime field" },
+#ifndef OPENSSL_NO_EC2M
/* characteristic two field curves */
/* NIST/SECG curves */
{ NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0, "SECG curve over a 113 bit binary field" },
{ NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, 0, "NIST/SECG/WTLS curve over a 163 bit binary field" },
{ NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, 0, "SECG curve over a 113 bit binary field" },
{ NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0, "X9.62 curve over a 163 bit binary field" },
+#endif
{ NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0, "SECG/WTLS curve over a 112 bit prime field" },
{ NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0, "SECG/WTLS curve over a 160 bit prime field" },
{ NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, 0, "WTLS curve over a 112 bit prime field" },
{ NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0, "WTLS curve over a 160 bit prime field" },
+#ifndef OPENSSL_NO_EC2M
{ NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field" },
{ NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field" },
+#endif
{ NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0, "WTLS curvs over a 224 bit prime field" },
+#ifndef OPENSSL_NO_EC2M
/* IPSec curves */
{ NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0, "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n"
"\tNot suitable for ECDSA.\n\tQuestionable extension field!" },
{ NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0, "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n"
"\tNot suitable for ECDSA.\n\tQuestionable extension field!" },
+#endif
};
#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element))
goto err;
}
}
+#ifndef OPENSSL_NO_EC2M
else /* field_type == NID_X9_62_characteristic_two_field */
{
if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL)
goto err;
}
}
+#endif
if ((P = EC_POINT_new(group)) == NULL)
{
ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
goto err;
}
- if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx))
+ if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx))
{
ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
goto err;
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;
return ret;
}
+#endif
{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"},
tx = BN_CTX_get(ctx);
ty = BN_CTX_get(ctx);
-
+#ifndef OPENSSL_NO_EC2M
if (is_char_two)
{
if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point,
goto err;
}
else
+#endif
{
if (!EC_POINT_set_affine_coordinates_GFp(key->group, point,
x, y, ctx))
return group->meth->group_get_curve(group, p, a, b, ctx);
}
-
+#ifndef OPENSSL_NO_EC2M
int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
if (group->meth->group_set_curve == 0)
}
return group->meth->group_get_curve(group, p, a, b, ctx);
}
-
+#endif
int EC_GROUP_get_degree(const EC_GROUP *group)
{
return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
}
-
+#ifndef OPENSSL_NO_EC2M
int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
{
}
return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
}
-
+#endif
int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
}
-
+#ifndef OPENSSL_NO_EC2M
int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *point,
BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
{
}
return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
}
-
+#endif
int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
const BIGNUM *x, int y_bit, BN_CTX *ctx)
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)
{
}
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)
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))
}
}
else /* prime field */
+#endif
{
if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx))
{
if (!(_variable = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; \
if (!EC_GROUP_copy(_variable, group)) ABORT; \
+#ifndef OPENSSL_NO_EC2M
static void char2_field_tests(void)
- {
+ {
BN_CTX *ctx = NULL;
BIGNUM *p, *a, *b;
EC_GROUP *group;
if (C2_B571) EC_GROUP_free(C2_B571);
}
+#endif
static void internal_curve_test(void)
{
prime_field_tests();
puts("");
+#ifndef OPENSSL_NO_EC2M
char2_field_tests();
+#endif
#ifdef EC_NISTP224_64_GCC_128
nistp224_test();
#endif
if (!EC_POINT_get_affine_coordinates_GFp(group,
EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err;
}
+#ifndef OPENSSL_NO_EC2M
else
{
if (!EC_POINT_get_affine_coordinates_GF2m(group,
EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err;
}
+#endif
#ifdef NOISY
BIO_puts(out," pri 1=");
BN_print(out,a->priv_key);
if (!EC_POINT_get_affine_coordinates_GFp(group,
EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err;
}
+#ifndef OPENSSL_NO_EC2M
else
{
if (!EC_POINT_get_affine_coordinates_GF2m(group,
EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err;
}
+#endif
#ifdef NOISY
BIO_puts(out," pri 2=");
if (!test_ecdh_curve(NID_X9_62_prime256v1, "NIST Prime-Curve P-256", ctx, out)) goto err;
if (!test_ecdh_curve(NID_secp384r1, "NIST Prime-Curve P-384", ctx, out)) goto err;
if (!test_ecdh_curve(NID_secp521r1, "NIST Prime-Curve P-521", ctx, out)) goto err;
+#ifndef OPENSSL_NO_EC2M
/* NIST BINARY CURVES TESTS */
if (!test_ecdh_curve(NID_sect163k1, "NIST Binary-Curve K-163", ctx, out)) goto err;
if (!test_ecdh_curve(NID_sect163r2, "NIST Binary-Curve B-163", ctx, out)) goto err;
if (!test_ecdh_curve(NID_sect409r1, "NIST Binary-Curve B-409", ctx, out)) goto err;
if (!test_ecdh_curve(NID_sect571k1, "NIST Binary-Curve K-571", ctx, out)) goto err;
if (!test_ecdh_curve(NID_sect571r1, "NIST Binary-Curve B-571", ctx, out)) goto err;
+#endif
ret = 0;
goto err;
}
}
+#ifndef OPENSSL_NO_EC2M
else
{
if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx))
goto err;
}
}
+#endif
buflen = (EC_GROUP_get_degree(group) + 7)/8;
len = BN_num_bytes(x);
"3238135532097973577080787768312505059318910517550078427819"
"78505179448783"))
goto x962_err;
+#ifndef OPENSSL_NO_EC2M
if (!x9_62_test_internal(out, NID_X9_62_c2tnb191v1,
"87194383164871543355722284926904419997237591535066528048",
"308992691965804947361541664549085895292153777025772063598"))
"1970303740007316867383349976549972270528498040721988191026"
"49413465737174"))
goto x962_err;
-
+#endif
ret = 1;
x962_err:
if (!restore_rand())
goto err;
}
}
+#ifndef OPENSSL_NO_EC2M
else /* NID_X9_62_characteristic_two_field */
{
if (!EC_POINT_get_affine_coordinates_GF2m(group,
goto err;
}
}
+#endif
if (!BN_nnmod(r, X, order, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
goto err;
}
}
+#ifndef OPENSSL_NO_EC2M
else /* NID_X9_62_characteristic_two_field */
{
if (!EC_POINT_get_affine_coordinates_GF2m(group,
goto err;
}
}
-
+#endif
if (!BN_nnmod(u1, X, order, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
}
}
else
+#ifdef OPENSSL_NO_EC2M
+ nid = NID_X9_62_prime256v1;
+#else
nid = NID_sect163r2;
+#endif
ecdh = EC_KEY_new_by_curve_name(nid);
if (ecdh == NULL)