diff options
author | Bodo Möller <bodo@openssl.org> | 2006-09-28 13:45:34 +0000 |
---|---|---|
committer | Bodo Möller <bodo@openssl.org> | 2006-09-28 13:45:34 +0000 |
commit | 5e3225cc44ebdce3a88d04a627e975b3e76a6f9a (patch) | |
tree | 40fc0efbaf2e75215453e71a5b6b8b326d3bee0f /crypto/ec/ec_asn1.c | |
parent | 61118caa86ecf8acba2c6d17caabeed9022acf9d (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.c | 46 |
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) |