diff --git a/CHANGES b/CHANGES index c58c811f4002dd7dcec9c10c0e4a4c92001444e0..a695a4dc635d5bc4810bca8617f7674fb287d5a9 100644 --- a/CHANGES +++ b/CHANGES @@ -2,7 +2,7 @@ OpenSSL CHANGES _______________ - Changes between 0.9.8 and 0.9.9 [xx XXX xxxx] + Changes between 0.9.8a and 0.9.9 [xx XXX xxxx] *) Support for PKCS#1 RSAPublicKey format on rsa utility command line. [Steve Henson] @@ -27,6 +27,12 @@ Changes between 0.9.8 and 0.9.8a [XX xxx XXXX] + *) Avoid small subgroup attacks in Diffie-Hellman. + [Nick Mathewson and Ben Laurie] + + *) Add functions for well-known primes. + [Nick Mathewson] + *) Extended Windows CE support. [Satoshi Nakamura and Andy Polyakov] diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h index e0e474f2c866da51368cec4c30c0b36c74be7d48..680f92891e6f7cbcd276b72ccd2a4421d007bc63 100644 --- a/crypto/asn1/asn1.h +++ b/crypto/asn1/asn1.h @@ -1040,6 +1040,7 @@ void ERR_load_ASN1_strings(void); #define ASN1_F_ASN1_MBSTRING_NCOPY 122 #define ASN1_F_ASN1_OBJECT_NEW 123 #define ASN1_F_ASN1_PACK_STRING 124 +#define ASN1_F_ASN1_PCTX_NEW 205 #define ASN1_F_ASN1_PKCS5_PBE_SET 125 #define ASN1_F_ASN1_SEQ_PACK 126 #define ASN1_F_ASN1_SEQ_UNPACK 127 diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c index b9df21c5fea98c59dbe5dbfa776a603734a5dd46..bef2519e65a6371062baa77804f684f23c166924 100644 --- a/crypto/asn1/asn1_err.c +++ b/crypto/asn1/asn1_err.c @@ -111,6 +111,7 @@ static ERR_STRING_DATA ASN1_str_functs[]= {ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"}, {ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW), "ASN1_OBJECT_new"}, {ERR_FUNC(ASN1_F_ASN1_PACK_STRING), "ASN1_pack_string"}, +{ERR_FUNC(ASN1_F_ASN1_PCTX_NEW), "ASN1_PCTX_NEW"}, {ERR_FUNC(ASN1_F_ASN1_PKCS5_PBE_SET), "ASN1_PKCS5_PBE_SET"}, {ERR_FUNC(ASN1_F_ASN1_SEQ_PACK), "ASN1_seq_pack"}, {ERR_FUNC(ASN1_F_ASN1_SEQ_UNPACK), "ASN1_seq_unpack"}, diff --git a/crypto/bn/Makefile b/crypto/bn/Makefile index 4afb6a393c962d9a7053649e63b09e013e92ec88..ab9c494913146b5271e1d586adcd65d7183b44f6 100644 --- a/crypto/bn/Makefile +++ b/crypto/bn/Makefile @@ -28,13 +28,13 @@ LIBSRC= bn_add.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c bn_mod.c \ bn_print.c bn_rand.c bn_shift.c bn_word.c bn_blind.c \ bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_err.c bn_sqr.c bn_asm.c \ bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c bn_nist.c \ - bn_depr.c + bn_depr.c bn_const.c LIBOBJ= bn_add.o bn_div.o bn_exp.o bn_lib.o bn_ctx.o bn_mul.o bn_mod.o \ bn_print.o bn_rand.o bn_shift.o bn_word.o bn_blind.o \ bn_kron.o bn_sqrt.o bn_gcd.o bn_prime.o bn_err.o bn_sqr.o $(BN_ASM) \ bn_recp.o bn_mont.o bn_mpi.o bn_exp2.o bn_gf2m.o bn_nist.o \ - bn_depr.o + bn_depr.o bn_const.o SRC= $(LIBSRC) diff --git a/crypto/bn/bn.h b/crypto/bn/bn.h index 670584ad74a7cbe683c0df7d8045dad624ae0722..b990ff2b5d50034ab0eeb3825a6ac60cdc75392c 100644 --- a/crypto/bn/bn.h +++ b/crypto/bn/bn.h @@ -732,6 +732,18 @@ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d); BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num); BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num); +/* Primes from RFC 2409 */ +int get_rfc2409_prime_768(BIGNUM **bn); +int get_rfc2409_prime_1024(BIGNUM **bn); + +/* Primes from RFC 3526 */ +int get_rfc3526_prime_1536(BIGNUM **bn); +int get_rfc3526_prime_2048(BIGNUM **bn); +int get_rfc3526_prime_3072(BIGNUM **bn); +int get_rfc3526_prime_4096(BIGNUM **bn); +int get_rfc3526_prime_6144(BIGNUM **bn); +int get_rfc3526_prime_8192(BIGNUM **bn); + int BN_bntest_rand(BIGNUM *rnd, int bits, int top,int bottom); /* BEGIN ERROR CODES */ diff --git a/crypto/dh/dh.h b/crypto/dh/dh.h index d1559fd4f878cf9e7b8a1eae15f1bdf3ab486c96..7871882e35a40865e43e64f034735fca0c794b6e 100644 --- a/crypto/dh/dh.h +++ b/crypto/dh/dh.h @@ -145,6 +145,10 @@ struct dh_st #define DH_UNABLE_TO_CHECK_GENERATOR 0x04 #define DH_NOT_SUITABLE_GENERATOR 0x08 +/* DH_check_pub_key error codes */ +#define DH_CHECK_PUBKEY_TOO_SMALL 0x01 +#define DH_CHECK_PUBKEY_TOO_LARGE 0x02 + /* primes p where (p-1)/2 is prime too are called "safe"; we define this for backward compatibility: */ #define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME @@ -183,6 +187,7 @@ DH * DH_generate_parameters(int prime_len,int generator, int DH_generate_parameters_ex(DH *dh, int prime_len,int generator, BN_GENCB *cb); int DH_check(const DH *dh,int *codes); +int DH_check_pub_key(const DH *dh,const BIGNUM *pub_key, int *codes); int DH_generate_key(DH *dh); int DH_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh); DH * d2i_DHparams(DH **a,const unsigned char **pp, long length); @@ -216,6 +221,7 @@ void ERR_load_DH_strings(void); /* Reason codes. */ #define DH_R_BAD_GENERATOR 101 #define DH_R_NO_PRIVATE_VALUE 100 +#define DH_R_INVALID_PUBKEY 102 #ifdef __cplusplus } diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c index bfc9c3ad7685eaee12ccc66c88ce8fe3aef1c3eb..10217c83dc13aa4adeb3865de502510ec75cee45 100644 --- a/crypto/dh/dh_check.c +++ b/crypto/dh/dh_check.c @@ -118,3 +118,25 @@ err: if (q != NULL) BN_free(q); return(ok); } + +int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) + { + int ok=0; + BIGNUM *q=NULL; + + *ret=0; + q=BN_new(); + if (q == NULL) goto err; + BN_set_word(q,1); + if (BN_cmp(pub_key,q)<=0) + *ret|=DH_CHECK_PUBKEY_TOO_SMALL; + BN_copy(q,dh->p); + BN_sub_word(q,1); + if (BN_cmp(pub_key,q)>=0) + *ret|=DH_CHECK_PUBKEY_TOO_LARGE; + + ok = 1; +err: + if (q != NULL) BN_free(q); + return(ok); + } diff --git a/crypto/dh/dh_err.c b/crypto/dh/dh_err.c index edce2c7036fb6ae69bbc4cd07cc65debfbcfb463..ea67fb71a0d2ef64b142f54981ae74fba677dcc4 100644 --- a/crypto/dh/dh_err.c +++ b/crypto/dh/dh_err.c @@ -84,6 +84,7 @@ static ERR_STRING_DATA DH_str_reasons[]= { {ERR_REASON(DH_R_BAD_GENERATOR) ,"bad generator"}, {ERR_REASON(DH_R_NO_PRIVATE_VALUE) ,"no private value"}, +{ERR_REASON(DH_R_INVALID_PUBKEY) ,"invalid public key"}, {0,NULL} }; diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c index 39eefe387eab82b63a3e0a3c42097d4012771f44..cc17c8851b691daf2798cad861f56b03adb9cbb1 100644 --- a/crypto/dh/dh_key.c +++ b/crypto/dh/dh_key.c @@ -177,6 +177,7 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) BN_MONT_CTX *mont=NULL; BIGNUM *tmp; int ret= -1; + int check_result; ctx = BN_CTX_new(); if (ctx == NULL) goto err; @@ -202,6 +203,12 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) goto err; } + if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) + { + DHerr(DH_F_COMPUTE_KEY,DH_R_INVALID_PUBKEY); + goto err; + } + if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key,dh->p,ctx,mont)) { DHerr(DH_F_COMPUTE_KEY,ERR_R_BN_LIB);