summaryrefslogtreecommitdiffstats
path: root/crypto/ec/ec_asn1.c
diff options
context:
space:
mode:
authorBodo Möller <bodo@openssl.org>2006-09-28 13:45:34 +0000
committerBodo Möller <bodo@openssl.org>2006-09-28 13:45:34 +0000
commit5e3225cc44ebdce3a88d04a627e975b3e76a6f9a (patch)
tree40fc0efbaf2e75215453e71a5b6b8b326d3bee0f /crypto/ec/ec_asn1.c
parent61118caa86ecf8acba2c6d17caabeed9022acf9d (diff)
Introduce limits to prevent malicious keys being able to
cause a denial of service. (CVE-2006-2940) [Steve Henson, Bodo Moeller]
Diffstat (limited to 'crypto/ec/ec_asn1.c')
-rw-r--r--crypto/ec/ec_asn1.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c
index dec913b8ad..66ef129293 100644
--- a/crypto/ec/ec_asn1.c
+++ b/crypto/ec/ec_asn1.c
@@ -741,6 +741,7 @@ static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
EC_GROUP *ret = NULL;
BIGNUM *p = NULL, *a = NULL, *b = NULL;
EC_POINT *point=NULL;
+ long field_bits;
if (!params->fieldID || !params->fieldID->fieldType ||
!params->fieldID->p.ptr)
@@ -779,6 +780,13 @@ static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
char_two = params->fieldID->p.char_two;
+ field_bits = char_two->m;
+ if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS)
+ {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
+ goto err;
+ }
+
if ((p = BN_new()) == NULL)
{
ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
@@ -799,6 +807,13 @@ static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
}
tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
+
+ if (!(char_two->m > tmp_long && tmp_long > 0))
+ {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_TRINOMIAL_BASIS);
+ goto err;
+ }
+
/* create the polynomial */
if (!BN_set_bit(p, (int)char_two->m))
goto err;
@@ -817,6 +832,13 @@ static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
goto err;
}
+
+ if (!(char_two->m > penta->k3 && penta->k3 > penta->k2 && penta->k2 > penta->k1 && penta->k1 > 0))
+ {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_PENTANOMIAL_BASIS);
+ goto err;
+ }
+
/* create the polynomial */
if (!BN_set_bit(p, (int)char_two->m)) goto err;
if (!BN_set_bit(p, (int)penta->k1)) goto err;
@@ -853,6 +875,20 @@ static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
goto err;
}
+
+ if (BN_is_negative(p) || BN_is_zero(p))
+ {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
+ goto err;
+ }
+
+ field_bits = BN_num_bits(p);
+ if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS)
+ {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
+ goto err;
+ }
+
/* create the EC_GROUP structure */
ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
}
@@ -910,6 +946,16 @@ static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
goto err;
}
+ if (BN_is_negative(a) || BN_is_zero(a))
+ {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
+ goto err;
+ }
+ if (BN_num_bits(a) > (int)field_bits + 1) /* Hasse bound */
+ {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
+ goto err;
+ }
/* extract the cofactor (optional) */
if (params->cofactor == NULL)