diff --git a/CHANGES b/CHANGES index a1fa57c8..aa00369e 100644 --- a/CHANGES +++ b/CHANGES @@ -25,6 +25,17 @@ list of built in objects, i.e. OIDs with names. [Richard Levitte] + Changes between 1.1.1 and 1.1.1a [xx XXX xxxx] + + *) Fixed the issue that RAND_add()/RAND_seed() silently discards random input + if its length exceeds 4096 bytes. The limit has been raised to a buffer size + of two gigabytes and the error handling improved. + + This issue was reported to OpenSSL by Dr. Falko Strenzke. It has been + categorized as a normal bug, not a security issue, because the DRBG reseeds + automatically and is fully functional even without additional randomness + provided by the application. + Changes between 1.1.0i and 1.1.1 [11 Sep 2018] *) Add a new ClientHello callback. Provides a callback interface that gives @@ -13121,4 +13132,3 @@ des-cbc 3624.96k 5258.21k 5530.91k 5624.30k 5628.26k *) A minor bug in ssl/s3_clnt.c where there would always be 4 0 bytes sent in the client random. [Edward Bishop ] - diff --git a/apps/apps.c b/apps/apps.c index 9be65605..653e3973 100644 --- a/apps/apps.c +++ b/apps/apps.c @@ -1831,6 +1831,12 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti) opt_getprog(), typestr); continue; } + if (*valstr == '\0') { + BIO_printf(bio_err, + "%s: No value provided for Subject Attribute %s, skipped\n", + opt_getprog(), typestr); + continue; + } if (!X509_NAME_add_entry_by_NID(n, nid, chtype, valstr, strlen((char *)valstr), -1, ismulti ? -1 : 0)) diff --git a/apps/speed.c b/apps/speed.c index 27b4d50a..833bb9bf 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -2947,7 +2947,7 @@ int speed_main(int argc, char **argv) if (rsa_count <= 1) { /* if longer than 10s, don't do any more */ - for (testnum++; testnum < EC_NUM; testnum++) + for (testnum++; testnum < ECDSA_NUM; testnum++) ecdsa_doit[testnum] = 0; } } diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 84e63930..489ccc09 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -1016,6 +1016,7 @@ RAND_F_RAND_POOL_ACQUIRE_ENTROPY:122:rand_pool_acquire_entropy RAND_F_RAND_POOL_ADD:103:rand_pool_add RAND_F_RAND_POOL_ADD_BEGIN:113:rand_pool_add_begin RAND_F_RAND_POOL_ADD_END:114:rand_pool_add_end +RAND_F_RAND_POOL_ATTACH:124:rand_pool_attach RAND_F_RAND_POOL_BYTES_NEEDED:115:rand_pool_bytes_needed RAND_F_RAND_POOL_NEW:116:rand_pool_new RAND_F_RAND_WRITE_FILE:112:RAND_write_file diff --git a/crypto/include/internal/rand_int.h b/crypto/include/internal/rand_int.h index d91ee4c9..3c966ab9 100644 --- a/crypto/include/internal/rand_int.h +++ b/crypto/include/internal/rand_int.h @@ -53,6 +53,8 @@ void rand_drbg_cleanup_additional_data(unsigned char *out, size_t outlen); * RAND_POOL functions */ RAND_POOL *rand_pool_new(int entropy_requested, size_t min_len, size_t max_len); +RAND_POOL *rand_pool_attach(const unsigned char *buffer, size_t len, + size_t entropy); void rand_pool_free(RAND_POOL *pool); const unsigned char *rand_pool_buffer(RAND_POOL *pool); diff --git a/crypto/poly1305/poly1305_ieee754.c b/crypto/poly1305/poly1305_ieee754.c index 995a02e5..7cfd9686 100644 --- a/crypto/poly1305/poly1305_ieee754.c +++ b/crypto/poly1305/poly1305_ieee754.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-20018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/rand/drbg_ctr.c b/crypto/rand/drbg_ctr.c index 97378be4..894c77d6 100644 --- a/crypto/rand/drbg_ctr.c +++ b/crypto/rand/drbg_ctr.c @@ -401,10 +401,10 @@ int drbg_ctr_init(RAND_DRBG *drbg) if ((drbg->flags & RAND_DRBG_FLAG_CTR_NO_DF) == 0) { /* df initialisation */ static const unsigned char df_key[32] = { - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }; if (ctr->ctx_df == NULL) @@ -416,9 +416,9 @@ int drbg_ctr_init(RAND_DRBG *drbg) return 0; drbg->min_entropylen = ctr->keylen; - drbg->max_entropylen = DRBG_MINMAX_FACTOR * drbg->min_entropylen; + drbg->max_entropylen = DRBG_MAX_LENGTH; drbg->min_noncelen = drbg->min_entropylen / 2; - drbg->max_noncelen = DRBG_MINMAX_FACTOR * drbg->min_noncelen; + drbg->max_noncelen = DRBG_MAX_LENGTH; drbg->max_perslen = DRBG_MAX_LENGTH; drbg->max_adinlen = DRBG_MAX_LENGTH; } else { diff --git a/crypto/rand/drbg_hash.c b/crypto/rand/drbg_hash.c index 9caf5b27..cae567be 100644 --- a/crypto/rand/drbg_hash.c +++ b/crypto/rand/drbg_hash.c @@ -332,10 +332,10 @@ int drbg_hash_init(RAND_DRBG *drbg) drbg->seedlen = HASH_PRNG_SMALL_SEEDLEN; drbg->min_entropylen = drbg->strength / 8; - drbg->max_entropylen = DRBG_MINMAX_FACTOR * drbg->min_entropylen; + drbg->max_entropylen = DRBG_MAX_LENGTH; drbg->min_noncelen = drbg->min_entropylen / 2; - drbg->max_noncelen = DRBG_MINMAX_FACTOR * drbg->min_noncelen; + drbg->max_noncelen = DRBG_MAX_LENGTH; drbg->max_perslen = DRBG_MAX_LENGTH; drbg->max_adinlen = DRBG_MAX_LENGTH; diff --git a/crypto/rand/drbg_hmac.c b/crypto/rand/drbg_hmac.c index 25c5b030..424c88cb 100644 --- a/crypto/rand/drbg_hmac.c +++ b/crypto/rand/drbg_hmac.c @@ -223,10 +223,10 @@ int drbg_hmac_init(RAND_DRBG *drbg) drbg->seedlen = hmac->blocklen; drbg->min_entropylen = drbg->strength / 8; - drbg->max_entropylen = DRBG_MINMAX_FACTOR * drbg->min_entropylen; + drbg->max_entropylen = DRBG_MAX_LENGTH; drbg->min_noncelen = drbg->min_entropylen / 2; - drbg->max_noncelen = DRBG_MINMAX_FACTOR * drbg->min_noncelen; + drbg->max_noncelen = DRBG_MAX_LENGTH; drbg->max_perslen = DRBG_MAX_LENGTH; drbg->max_adinlen = DRBG_MAX_LENGTH; diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c index 10a17a9a..36b20c93 100644 --- a/crypto/rand/drbg_lib.c +++ b/crypto/rand/drbg_lib.c @@ -286,7 +286,7 @@ static RAND_DRBG *rand_drbg_new(int secure, return drbg; -err: + err: if (drbg->secure) OPENSSL_secure_free(drbg); else @@ -378,7 +378,7 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg, entropylen = drbg->get_entropy(drbg, &entropy, min_entropy, min_entropylen, max_entropylen, 0); if (entropylen < min_entropylen - || entropylen > max_entropylen) { + || entropylen > max_entropylen) { RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_ERROR_RETRIEVING_ENTROPY); goto end; } @@ -408,10 +408,10 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg, drbg->reseed_prop_counter = drbg->parent->reseed_prop_counter; } -end: + end: if (entropy != NULL && drbg->cleanup_entropy != NULL) drbg->cleanup_entropy(drbg, entropy, entropylen); - if (nonce != NULL && drbg->cleanup_nonce!= NULL ) + if (nonce != NULL && drbg->cleanup_nonce != NULL) drbg->cleanup_nonce(drbg, nonce, noncelen); if (drbg->pool != NULL) { if (drbg->state == DRBG_READY) { @@ -504,7 +504,7 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg, drbg->max_entropylen, prediction_resistance); if (entropylen < drbg->min_entropylen - || entropylen > drbg->max_entropylen) { + || entropylen > drbg->max_entropylen) { RANDerr(RAND_F_RAND_DRBG_RESEED, RAND_R_ERROR_RETRIEVING_ENTROPY); goto end; } @@ -522,7 +522,7 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg, drbg->reseed_prop_counter = drbg->parent->reseed_prop_counter; } -end: + end: if (entropy != NULL && drbg->cleanup_entropy != NULL) drbg->cleanup_entropy(drbg, entropy, entropylen); if (drbg->state == DRBG_READY) @@ -556,8 +556,10 @@ int rand_drbg_restart(RAND_DRBG *drbg, if (drbg->pool != NULL) { RANDerr(RAND_F_RAND_DRBG_RESTART, ERR_R_INTERNAL_ERROR); + drbg->state = DRBG_ERROR; rand_pool_free(drbg->pool); drbg->pool = NULL; + return 0; } if (buffer != NULL) { @@ -565,24 +567,25 @@ int rand_drbg_restart(RAND_DRBG *drbg, if (drbg->max_entropylen < len) { RANDerr(RAND_F_RAND_DRBG_RESTART, RAND_R_ENTROPY_INPUT_TOO_LONG); + drbg->state = DRBG_ERROR; return 0; } if (entropy > 8 * len) { RANDerr(RAND_F_RAND_DRBG_RESTART, RAND_R_ENTROPY_OUT_OF_RANGE); + drbg->state = DRBG_ERROR; return 0; } /* will be picked up by the rand_drbg_get_entropy() callback */ - drbg->pool = rand_pool_new(entropy, len, len); + drbg->pool = rand_pool_attach(buffer, len, entropy); if (drbg->pool == NULL) return 0; - - rand_pool_add(drbg->pool, buffer, len, entropy); } else { if (drbg->max_adinlen < len) { RANDerr(RAND_F_RAND_DRBG_RESTART, RAND_R_ADDITIONAL_INPUT_TOO_LONG); + drbg->state = DRBG_ERROR; return 0; } adin = buffer; @@ -1040,14 +1043,16 @@ static int drbg_add(const void *buf, int num, double randomness) if (num < 0 || randomness < 0.0) return 0; - if (randomness > (double)drbg->max_entropylen) { + if (randomness > (double)RAND_DRBG_STRENGTH) { /* * The purpose of this check is to bound |randomness| by a * relatively small value in order to prevent an integer * overflow when multiplying by 8 in the rand_drbg_restart() - * call below. + * call below. Note that randomness is measured in bytes, + * not bits, so this value corresponds to eight times the + * security strength. */ - return 0; + randomness = (double)RAND_DRBG_STRENGTH; } rand_drbg_lock(drbg); diff --git a/crypto/rand/rand_err.c b/crypto/rand/rand_err.c index 31480a68..6a870455 100644 --- a/crypto/rand/rand_err.c +++ b/crypto/rand/rand_err.c @@ -44,6 +44,7 @@ static const ERR_STRING_DATA RAND_str_functs[] = { {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ADD_BEGIN, 0), "rand_pool_add_begin"}, {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ADD_END, 0), "rand_pool_add_end"}, + {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ATTACH, 0), "rand_pool_attach"}, {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_BYTES_NEEDED, 0), "rand_pool_bytes_needed"}, {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_NEW, 0), "rand_pool_new"}, diff --git a/crypto/rand/rand_lcl.h b/crypto/rand/rand_lcl.h index 7b1c74d4..13f8cc82 100644 --- a/crypto/rand/rand_lcl.h +++ b/crypto/rand/rand_lcl.h @@ -32,18 +32,42 @@ -/* Max size of additional input and personalization string. */ -# define DRBG_MAX_LENGTH 4096 +/* + * Maximum input size for the DRBG (entropy, nonce, personalization string) + * + * NIST SP800 90Ar1 allows a maximum of (1 << 35) bits i.e., (1 << 32) bytes. + * + * We lower it to 'only' INT32_MAX bytes, which is equivalent to 2 gigabytes. + */ +# define DRBG_MAX_LENGTH INT32_MAX + + /* - * The quotient between max_{entropy,nonce}len and min_{entropy,nonce}len + * Maximum allocation size for RANDOM_POOL buffers * - * The current factor is large enough that the RAND_POOL can store a - * random input which has a lousy entropy rate of 0.0625 bits per byte. - * This input will be sent through the derivation function which 'compresses' - * the low quality input into a high quality output. + * The max_len value for the buffer provided to the rand_drbg_get_entropy() + * callback is currently 2^31 bytes (2 gigabytes), if a derivation function + * is used. Since this is much too large to be allocated, the rand_pool_new() + * function chooses more modest values as default pool length, bounded + * by RAND_POOL_MIN_LENGTH and RAND_POOL_MAX_LENGTH + * + * The choice of the RAND_POOL_FACTOR is large enough such that the + * RAND_POOL can store a random input which has a lousy entropy rate of + * 8/256 (= 0.03125) bits per byte. This input will be sent through the + * derivation function which 'compresses' the low quality input into a + * high quality output. + * + * The factor 1.5 below is the pessimistic estimate for the extra amount + * of entropy required when no get_nonce() callback is defined. + */ +# define RAND_POOL_FACTOR 256 +# define RAND_POOL_MAX_LENGTH (RAND_POOL_FACTOR * \ + 3 * (RAND_DRBG_STRENGTH / 16)) +/* + * = (RAND_POOL_FACTOR * \ + * 1.5 * (RAND_DRBG_STRENGTH / 8)) */ -# define DRBG_MINMAX_FACTOR 128 /* DRBG status values */ @@ -142,10 +166,12 @@ struct rand_pool_st { unsigned char *buffer; /* points to the beginning of the random pool */ size_t len; /* current number of random bytes contained in the pool */ + int attached; /* true pool was attached to existing buffer */ + size_t min_len; /* minimum number of random bytes requested */ size_t max_len; /* maximum number of random bytes (allocated buffer size) */ size_t entropy; /* current entropy count in bits */ - size_t requested_entropy; /* requested entropy count in bits */ + size_t entropy_requested; /* requested entropy count in bits */ }; /* @@ -167,7 +193,7 @@ struct rand_drbg_st { unsigned short flags; /* various external flags */ /* - * The random pool is used by RAND_add()/drbg_add() to attach random + * The random_data is used by RAND_add()/drbg_add() to attach random * data to the global drbg, such that the rand_drbg_get_entropy() callback * can pull it during instantiation and reseeding. This is necessary to * reconcile the different philosophies of the RAND and the RAND_DRBG diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c index e9bc9522..f40c513c 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -146,17 +146,11 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg, return 0; } - pool = rand_pool_new(entropy, min_len, max_len); - if (pool == NULL) - return 0; - - if (drbg->pool) { - rand_pool_add(pool, - rand_pool_buffer(drbg->pool), - rand_pool_length(drbg->pool), - rand_pool_entropy(drbg->pool)); - rand_pool_free(drbg->pool); - drbg->pool = NULL; + if (drbg->pool != NULL) { + pool = drbg->pool; + pool->entropy_requested = entropy; + } else { + pool = rand_pool_new(entropy, min_len, max_len); } if (drbg->parent) { @@ -217,7 +211,10 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg, void rand_drbg_cleanup_entropy(RAND_DRBG *drbg, unsigned char *out, size_t outlen) { - OPENSSL_secure_clear_free(out, outlen); + if (drbg->pool == NULL) + OPENSSL_secure_clear_free(out, outlen); + else + drbg->pool = NULL; } @@ -405,7 +402,7 @@ int RAND_poll(void) /* fill random pool and seed the current legacy RNG */ pool = rand_pool_new(RAND_DRBG_STRENGTH, RAND_DRBG_STRENGTH / 8, - DRBG_MINMAX_FACTOR * (RAND_DRBG_STRENGTH / 8)); + RAND_POOL_MAX_LENGTH); if (pool == NULL) return 0; @@ -430,17 +427,18 @@ err: * Allocate memory and initialize a new random pool */ -RAND_POOL *rand_pool_new(int entropy, size_t min_len, size_t max_len) +RAND_POOL *rand_pool_new(int entropy_requested, size_t min_len, size_t max_len) { RAND_POOL *pool = OPENSSL_zalloc(sizeof(*pool)); if (pool == NULL) { RANDerr(RAND_F_RAND_POOL_NEW, ERR_R_MALLOC_FAILURE); - goto err; + return NULL; } pool->min_len = min_len; - pool->max_len = max_len; + pool->max_len = (max_len > RAND_POOL_MAX_LENGTH) ? + RAND_POOL_MAX_LENGTH : max_len; pool->buffer = OPENSSL_secure_zalloc(pool->max_len); if (pool->buffer == NULL) { @@ -448,7 +446,7 @@ RAND_POOL *rand_pool_new(int entropy, size_t min_len, size_t max_len) goto err; } - pool->requested_entropy = entropy; + pool->entropy_requested = entropy_requested; return pool; @@ -457,6 +455,38 @@ err: return NULL; } +/* + * Attach new random pool to the given buffer + * + * This function is intended to be used only for feeding random data + * provided by RAND_add() and RAND_seed() into the DRBG. + */ +RAND_POOL *rand_pool_attach(const unsigned char *buffer, size_t len, + size_t entropy) +{ + RAND_POOL *pool = OPENSSL_zalloc(sizeof(*pool)); + + if (pool == NULL) { + RANDerr(RAND_F_RAND_POOL_ATTACH, ERR_R_MALLOC_FAILURE); + return NULL; + } + + /* + * The const needs to be cast away, but attached buffers will not be + * modified (in contrary to allocated buffers which are zeroed and + * freed in the end). + */ + pool->buffer = (unsigned char *) buffer; + pool->len = len; + + pool->attached = 1; + + pool->min_len = pool->max_len = pool->len; + pool->entropy = entropy; + + return pool; +} + /* * Free |pool|, securely erasing its buffer. */ @@ -465,7 +495,14 @@ void rand_pool_free(RAND_POOL *pool) if (pool == NULL) return; - OPENSSL_secure_clear_free(pool->buffer, pool->max_len); + /* + * Although it would be advisable from a cryptographical viewpoint, + * we are not allowed to clear attached buffers, since they are passed + * to rand_pool_attach() as `const unsigned char*`. + * (see corresponding comment in rand_pool_attach()). + */ + if (!pool->attached) + OPENSSL_secure_clear_free(pool->buffer, pool->max_len); OPENSSL_free(pool); } @@ -524,7 +561,7 @@ unsigned char *rand_pool_detach(RAND_POOL *pool) */ size_t rand_pool_entropy_available(RAND_POOL *pool) { - if (pool->entropy < pool->requested_entropy) + if (pool->entropy < pool->entropy_requested) return 0; if (pool->len < pool->min_len) @@ -540,8 +577,8 @@ size_t rand_pool_entropy_available(RAND_POOL *pool) size_t rand_pool_entropy_needed(RAND_POOL *pool) { - if (pool->entropy < pool->requested_entropy) - return pool->requested_entropy - pool->entropy; + if (pool->entropy < pool->entropy_requested) + return pool->entropy_requested - pool->entropy; return 0; } diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c index f7819611..cb3a6b24 100644 --- a/crypto/rand/rand_unix.c +++ b/crypto/rand/rand_unix.c @@ -77,6 +77,17 @@ static uint64_t get_timer_bits(void); # endif #endif /* defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__) */ +#if defined(OPENSSL_RAND_SEED_NONE) +/* none means none. this simplifies the following logic */ +# undef OPENSSL_RAND_SEED_OS +# undef OPENSSL_RAND_SEED_GETRANDOM +# undef OPENSSL_RAND_SEED_LIBRANDOM +# undef OPENSSL_RAND_SEED_DEVRANDOM +# undef OPENSSL_RAND_SEED_RDTSC +# undef OPENSSL_RAND_SEED_RDCPU +# undef OPENSSL_RAND_SEED_EGD +#endif + #if (defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI)) && \ !defined(OPENSSL_RAND_SEED_NONE) # error "UEFI and VXWorks only support seeding NONE" @@ -86,8 +97,6 @@ static uint64_t get_timer_bits(void); || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_VXWORKS) \ || defined(OPENSSL_SYS_UEFI)) -static ssize_t syscall_random(void *buf, size_t buflen); - # if defined(OPENSSL_SYS_VOS) # ifndef OPENSSL_RAND_SEED_OS @@ -244,6 +253,7 @@ static ssize_t sysctl_random(char *buf, size_t buflen) } # endif +# if defined(OPENSSL_RAND_SEED_GETRANDOM) /* * syscall_random(): Try to get random data using a system call * returns the number of bytes returned in buf, or < 0 on error. @@ -254,7 +264,7 @@ static ssize_t syscall_random(void *buf, size_t buflen) * Note: 'buflen' equals the size of the buffer which is used by the * get_entropy() callback of the RAND_DRBG. It is roughly bounded by * - * 2 * DRBG_MINMAX_FACTOR * (RAND_DRBG_STRENGTH / 8) = 2^13 + * 2 * RAND_POOL_FACTOR * (RAND_DRBG_STRENGTH / 8) = 2^14 * * which is way below the OSSL_SSIZE_MAX limit. Therefore sign conversion * between size_t and ssize_t is safe even without a range check. @@ -302,8 +312,9 @@ static ssize_t syscall_random(void *buf, size_t buflen) return -1; # endif } +# endif /* defined(OPENSSL_RAND_SEED_GETRANDOM) */ -#if !defined(OPENSSL_RAND_SEED_NONE) && defined(OPENSSL_RAND_SEED_DEVRANDOM) +# if defined(OPENSSL_RAND_SEED_DEVRANDOM) static const char *random_device_paths[] = { DEVRANDOM }; static struct random_device { int fd; @@ -410,9 +421,7 @@ void rand_pool_keep_random_devices_open(int keep) keep_random_devices_open = keep; } -# else /* defined(OPENSSL_RAND_SEED_NONE) - * || !defined(OPENSSL_RAND_SEED_DEVRANDOM) - */ +# else /* !defined(OPENSSL_RAND_SEED_DEVRANDOM) */ int rand_pool_init(void) { @@ -427,9 +436,7 @@ void rand_pool_keep_random_devices_open(int keep) { } -# endif /* !defined(OPENSSL_RAND_SEED_NONE) - * && defined(OPENSSL_RAND_SEED_DEVRANDOM) - */ +# endif /* defined(OPENSSL_RAND_SEED_DEVRANDOM) */ /* * Try the various seeding methods in turn, exit when successful. @@ -450,14 +457,14 @@ void rand_pool_keep_random_devices_open(int keep) */ size_t rand_pool_acquire_entropy(RAND_POOL *pool) { -# ifdef OPENSSL_RAND_SEED_NONE +# if defined(OPENSSL_RAND_SEED_NONE) return rand_pool_entropy_available(pool); # else size_t bytes_needed; size_t entropy_available = 0; unsigned char *buffer; -# ifdef OPENSSL_RAND_SEED_GETRANDOM +# if defined(OPENSSL_RAND_SEED_GETRANDOM) { ssize_t bytes; /* Maximum allowed number of consecutive unsuccessful attempts */ @@ -487,7 +494,7 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool) } # endif -# ifdef OPENSSL_RAND_SEED_DEVRANDOM +# if defined(OPENSSL_RAND_SEED_DEVRANDOM) bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); { size_t i; @@ -524,19 +531,19 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool) } # endif -# ifdef OPENSSL_RAND_SEED_RDTSC +# if defined(OPENSSL_RAND_SEED_RDTSC) entropy_available = rand_acquire_entropy_from_tsc(pool); if (entropy_available > 0) return entropy_available; # endif -# ifdef OPENSSL_RAND_SEED_RDCPU +# if defined(OPENSSL_RAND_SEED_RDCPU) entropy_available = rand_acquire_entropy_from_cpu(pool); if (entropy_available > 0) return entropy_available; # endif -# ifdef OPENSSL_RAND_SEED_EGD +# if defined(OPENSSL_RAND_SEED_EGD) bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); if (bytes_needed > 0) { static const char *paths[] = { DEVRANDOM_EGD, NULL }; diff --git a/crypto/rand/rand_win.c b/crypto/rand/rand_win.c index 34c2a8b9..d2039eb2 100644 --- a/crypto/rand/rand_win.c +++ b/crypto/rand/rand_win.c @@ -67,7 +67,7 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool) if (buffer != NULL) { size_t bytes = 0; if (BCryptGenRandom(NULL, buffer, bytes_needed, - BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS) + BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS) bytes = bytes_needed; rand_pool_add_end(pool, bytes, 8 * bytes); @@ -82,7 +82,7 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool) size_t bytes = 0; /* poll the CryptoAPI PRNG */ if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT) != 0) { + CRYPT_VERIFYCONTEXT | CRYPT_SILENT) != 0) { if (CryptGenRandom(hProvider, bytes_needed, buffer) != 0) bytes = bytes_needed; diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c index 72d1b5e0..49c34b7c 100644 --- a/crypto/rsa/rsa_lib.c +++ b/crypto/rsa/rsa_lib.c @@ -125,8 +125,8 @@ void RSA_free(RSA *r) CRYPTO_THREAD_lock_free(r->lock); - BN_clear_free(r->n); - BN_clear_free(r->e); + BN_free(r->n); + BN_free(r->e); BN_clear_free(r->d); BN_clear_free(r->p); BN_clear_free(r->q); @@ -196,7 +196,7 @@ int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) r->e = e; } if (d != NULL) { - BN_free(r->d); + BN_clear_free(r->d); r->d = d; } @@ -213,11 +213,11 @@ int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) return 0; if (p != NULL) { - BN_free(r->p); + BN_clear_free(r->p); r->p = p; } if (q != NULL) { - BN_free(r->q); + BN_clear_free(r->q); r->q = q; } @@ -235,15 +235,15 @@ int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) return 0; if (dmp1 != NULL) { - BN_free(r->dmp1); + BN_clear_free(r->dmp1); r->dmp1 = dmp1; } if (dmq1 != NULL) { - BN_free(r->dmq1); + BN_clear_free(r->dmq1); r->dmq1 = dmq1; } if (iqmp != NULL) { - BN_free(r->iqmp); + BN_clear_free(r->iqmp); r->iqmp = iqmp; } diff --git a/crypto/rsa/rsa_ossl.c b/crypto/rsa/rsa_ossl.c index d581777e..2b1b006c 100644 --- a/crypto/rsa/rsa_ossl.c +++ b/crypto/rsa/rsa_ossl.c @@ -680,10 +680,11 @@ static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) */ || !bn_mod_sub_fixed_top(r1, r1, m1, rsa->p) - /* r0 = r0 * iqmp mod p */ + /* r1 = r1 * iqmp mod p */ || !bn_to_mont_fixed_top(r1, r1, rsa->_method_mod_p, ctx) || !bn_mul_mont_fixed_top(r1, r1, rsa->iqmp, rsa->_method_mod_p, ctx) + /* r0 = r1 * q + m1 */ || !bn_mul_fixed_top(r0, r1, rsa->q, ctx) || !bn_mod_add_fixed_top(r0, r0, m1, rsa->n)) goto err; diff --git a/crypto/sha/asm/keccak1600-s390x.pl b/crypto/sha/asm/keccak1600-s390x.pl index 3bce19be..1184cf23 100755 --- a/crypto/sha/asm/keccak1600-s390x.pl +++ b/crypto/sha/asm/keccak1600-s390x.pl @@ -432,9 +432,9 @@ SHA3_absorb: lrvg %r0,0($inp) la $inp,8($inp) xg %r0,0(%r1) - la %r1,8(%r1) a${g}hi $len,-8 - stg %r0,-8(%r1) + stg %r0,0(%r1) + la %r1,8(%r1) brct $bsz,.Lblock_absorb stm${g} $inp,$len,$frame+3*$SIZE_T($sp) diff --git a/doc/man1/ca.pod b/doc/man1/ca.pod index 9b282e64..e998eabf 100644 --- a/doc/man1/ca.pod +++ b/doc/man1/ca.pod @@ -250,8 +250,10 @@ for all available algorithms. =item B<-subj arg> Supersedes subject name given in the request. -The arg must be formatted as I, -characters may be escaped by \ (backslash), no spaces are skipped. +The arg must be formatted as I. +Keyword characters may be escaped by \ (backslash), and whitespace is retained. +Empty values are permitted, but the corresponding type will not be included +in the resulting certificate. =item B<-utf8> diff --git a/doc/man1/req.pod b/doc/man1/req.pod index 113cd9b6..c76d63d6 100644 --- a/doc/man1/req.pod +++ b/doc/man1/req.pod @@ -221,8 +221,10 @@ see L. Sets subject name for new request or supersedes the subject name when processing a request. -The arg must be formatted as I, -characters may be escaped by \ (backslash), no spaces are skipped. +The arg must be formatted as I. +Keyword characters may be escaped by \ (backslash), and whitespace is retained. +Empty values are permitted, but the corresponding type will not be included +in the request. =item B<-multivalue-rdn> diff --git a/doc/man1/storeutl.pod b/doc/man1/storeutl.pod index 3f26ab50..083f0282 100644 --- a/doc/man1/storeutl.pod +++ b/doc/man1/storeutl.pod @@ -82,8 +82,11 @@ returned. =item B<-subject arg> Search for an object having the subject name B. -The arg must be formatted as I, -characters may be escaped by \ (backslash), no spaces are skipped. +The arg must be formatted as I. +Keyword characters may be escaped by \ (backslash), and whitespace is retained. +Empty values are permitted but are ignored for the search. That is, +a search with an empty value will have the same effect as not specifying +the type at all. =item B<-issuer arg> diff --git a/doc/man3/DES_random_key.pod b/doc/man3/DES_random_key.pod index f543bea1..6e0394d6 100644 --- a/doc/man3/DES_random_key.pod +++ b/doc/man3/DES_random_key.pod @@ -99,7 +99,7 @@ algorithm. There are two phases to the use of DES encryption. The first is the generation of a I from a key, the second is the -actual encryption. A DES key is of type I. This type is +actual encryption. A DES key is of type I. This type consists of 8 bytes with odd parity. The least significant bit in each byte is the parity bit. The key schedule is an expanded form of the key; it is used to speed the encryption process. @@ -170,42 +170,42 @@ of 24 bytes. This is much better than CBC DES. DES_ede3_cbc_encrypt() implements outer triple CBC DES encryption with three keys. This means that each DES operation inside the CBC mode is -an C. This mode is used by SSL. +C. This mode is used by SSL. The DES_ede2_cbc_encrypt() macro implements two-key Triple-DES by reusing I for the final encryption. C. This form of Triple-DES is used by the RSAREF library. -DES_pcbc_encrypt() encrypt/decrypts using the propagating cipher block +DES_pcbc_encrypt() encrypts/decrypts using the propagating cipher block chaining mode used by Kerberos v4. Its parameters are the same as DES_ncbc_encrypt(). -DES_cfb_encrypt() encrypt/decrypts using cipher feedback mode. This -method takes an array of characters as input and outputs and array of +DES_cfb_encrypt() encrypts/decrypts using cipher feedback mode. This +method takes an array of characters as input and outputs an array of characters. It does not require any padding to 8 character groups. Note: the I variable is changed and the new changed value needs to be passed to the next call to this function. Since this function runs a complete DES ECB encryption per I, this function is only -suggested for use when sending small numbers of characters. +suggested for use when sending a small number of characters. DES_cfb64_encrypt() -implements CFB mode of DES with 64bit feedback. Why is this +implements CFB mode of DES with 64-bit feedback. Why is this useful you ask? Because this routine will allow you to encrypt an -arbitrary number of bytes, no 8 byte padding. Each call to this +arbitrary number of bytes, without 8 byte padding. Each call to this routine will encrypt the input bytes to output and then update ivec and num. num contains 'how far' we are though ivec. If this does -not make much sense, read more about cfb mode of DES :-). +not make much sense, read more about CFB mode of DES. DES_ede3_cfb64_encrypt() and DES_ede2_cfb64_encrypt() is the same as DES_cfb64_encrypt() except that Triple-DES is used. DES_ofb_encrypt() encrypts using output feedback mode. This method -takes an array of characters as input and outputs and array of +takes an array of characters as input and outputs an array of characters. It does not require any padding to 8 character groups. Note: the I variable is changed and the new changed value needs to be passed to the next call to this function. Since this function runs -a complete DES ECB encryption per numbits, this function is only -suggested for use when sending small numbers of characters. +a complete DES ECB encryption per I, this function is only +suggested for use when sending a small number of characters. DES_ofb64_encrypt() is the same as DES_cfb64_encrypt() using Output Feed Back mode. @@ -232,10 +232,10 @@ The following are DES-based transformations: DES_fcrypt() is a fast version of the Unix crypt(3) function. This version takes only a small amount of space relative to other fast -crypt() implementations. This is different to the normal crypt in +crypt() implementations. This is different to the normal crypt() in that the third parameter is the buffer that the return value is written into. It needs to be at least 14 bytes long. This function -is thread safe, unlike the normal crypt. +is thread safe, unlike the normal crypt(). DES_crypt() is a faster replacement for the normal system crypt(). This function calls DES_fcrypt() with a static array passed as the diff --git a/doc/man3/EVP_DigestInit.pod b/doc/man3/EVP_DigestInit.pod index 0fedd17c..5ecbcc5e 100644 --- a/doc/man3/EVP_DigestInit.pod +++ b/doc/man3/EVP_DigestInit.pod @@ -310,16 +310,17 @@ This example digests the data "Test Message\n" and "Hello World\n", using the digest name passed on the command line. #include + #include #include - main(int argc, char *argv[]) + int main(int argc, char *argv[]) { EVP_MD_CTX *mdctx; const EVP_MD *md; char mess1[] = "Test Message\n"; char mess2[] = "Hello World\n"; unsigned char md_value[EVP_MAX_MD_SIZE]; - int md_len, i; + unsigned int md_len, i; if (argv[1] == NULL) { printf("Usage: mdtest digestname\n"); diff --git a/fuzz/helper.py b/fuzz/helper.py index f5f9d77d..889af308 100755 --- a/fuzz/helper.py +++ b/fuzz/helper.py @@ -45,7 +45,7 @@ def main(): cmd = ([os.path.abspath(os.path.join(THIS_DIR, FUZZER))] + sys.argv[2:] + ["-artifact_prefix=" + corpora[1] + "/"] + corpora) - print " ".join(cmd) + print(" ".join(cmd)) subprocess.call(cmd) if __name__ == "__main__": diff --git a/include/openssl/randerr.h b/include/openssl/randerr.h index 128f4dea..599a2a18 100644 --- a/include/openssl/randerr.h +++ b/include/openssl/randerr.h @@ -40,6 +40,7 @@ int ERR_load_RAND_strings(void); # define RAND_F_RAND_POOL_ADD 103 # define RAND_F_RAND_POOL_ADD_BEGIN 113 # define RAND_F_RAND_POOL_ADD_END 114 +# define RAND_F_RAND_POOL_ATTACH 124 # define RAND_F_RAND_POOL_BYTES_NEEDED 115 # define RAND_F_RAND_POOL_NEW 116 # define RAND_F_RAND_WRITE_FILE 112 diff --git a/include/openssl/rsa.h b/include/openssl/rsa.h index a38ba12f..cdce1264 100644 --- a/include/openssl/rsa.h +++ b/include/openssl/rsa.h @@ -160,7 +160,7 @@ extern "C" { # define EVP_PKEY_CTX_set_rsa_pss_keygen_md(ctx, md) \ EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, \ - EVP_PKEY_OP_TYPE_KEYGEN, EVP_PKEY_CTRL_MD, \ + EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_MD, \ 0, (void *)(md)) # define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1) diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c index 5f403817..fca84ef9 100644 --- a/ssl/s3_enc.c +++ b/ssl/s3_enc.c @@ -442,15 +442,16 @@ size_t ssl3_final_finish_mac(SSL *s, const char *sender, size_t len, if (!EVP_MD_CTX_copy_ex(ctx, s->s3->handshake_dgst)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINAL_FINISH_MAC, ERR_R_INTERNAL_ERROR); - return 0; + ret = 0; + goto err; } ret = EVP_MD_CTX_size(ctx); if (ret < 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINAL_FINISH_MAC, ERR_R_INTERNAL_ERROR); - EVP_MD_CTX_reset(ctx); - return 0; + ret = 0; + goto err; } if ((sender != NULL && EVP_DigestUpdate(ctx, sender, len) <= 0) @@ -463,6 +464,7 @@ size_t ssl3_final_finish_mac(SSL *s, const char *sender, size_t len, ret = 0; } + err: EVP_MD_CTX_free(ctx); return ret; diff --git a/test/drbgtest.c b/test/drbgtest.c index f2054a8a..bb51e012 100644 --- a/test/drbgtest.c +++ b/test/drbgtest.c @@ -911,7 +911,6 @@ static size_t get_pool_entropy(RAND_DRBG *drbg, */ static void cleanup_pool_entropy(RAND_DRBG *drbg, unsigned char *out, size_t outlen) { - OPENSSL_secure_clear_free(drbg->pool->buffer, drbg->pool->max_len); OPENSSL_free(drbg->pool); drbg->pool = NULL; } diff --git a/test/ecdsatest.c b/test/ecdsatest.c index c4bcb8ed..96939a5b 100644 --- a/test/ecdsatest.c +++ b/test/ecdsatest.c @@ -13,7 +13,7 @@ #include #include /* To see if OPENSSL_NO_EC is defined */ -# include "testutil.h" +#include "testutil.h" #ifndef OPENSSL_NO_EC @@ -25,6 +25,7 @@ # ifndef OPENSSL_NO_ENGINE # include # endif +# include # include # include @@ -103,7 +104,7 @@ static int x9_62_test_internal(int nid, const char *r_in, const char *s_in) { int ret = 0; const char message[] = "abc"; - unsigned char digest[20]; + unsigned char digest[SHA_DIGEST_LENGTH]; unsigned int dgst_len = 0; EVP_MD_CTX *md_ctx; EC_KEY *key = NULL; @@ -135,7 +136,8 @@ static int x9_62_test_internal(int nid, const char *r_in, const char *s_in) /* Use ECDSA_sign_setup to avoid use of ECDSA nonces */ if (!TEST_true(ECDSA_sign_setup(key, NULL, &kinv, &rp))) goto x962_int_err; - if (!TEST_ptr(signature = ECDSA_do_sign_ex(digest, 20, kinv, rp, key))) + if (!TEST_ptr(signature = + ECDSA_do_sign_ex(digest, SHA_DIGEST_LENGTH, kinv, rp, key))) goto x962_int_err; /* compare the created signature with the expected signature */ @@ -149,7 +151,8 @@ static int x9_62_test_internal(int nid, const char *r_in, const char *s_in) goto x962_int_err; /* verify the signature */ - if (!TEST_int_eq(ECDSA_do_verify(digest, 20, signature, key), 1)) + if (!TEST_int_eq(ECDSA_do_verify(digest, SHA_DIGEST_LENGTH, + signature, key), 1)) goto x962_int_err; ret = 1; @@ -211,7 +214,8 @@ static int test_builtin(void) EC_KEY *eckey = NULL, *wrong_eckey = NULL; EC_GROUP *group; ECDSA_SIG *ecdsa_sig = NULL, *modified_sig = NULL; - unsigned char digest[20], wrong_digest[20]; + unsigned char digest[SHA512_DIGEST_LENGTH]; + unsigned char wrong_digest[SHA512_DIGEST_LENGTH]; unsigned char *signature = NULL; const unsigned char *sig_ptr; unsigned char *sig_ptr2; @@ -223,8 +227,8 @@ static int test_builtin(void) int nid, ret = 0; /* fill digest values with some random data */ - if (!TEST_true(RAND_bytes(digest, 20)) - || !TEST_true(RAND_bytes(wrong_digest, 20))) + if (!TEST_true(RAND_bytes(digest, SHA512_DIGEST_LENGTH)) + || !TEST_true(RAND_bytes(wrong_digest, SHA512_DIGEST_LENGTH))) goto builtin_err; /* create and verify a ecdsa signature with every available curve */ @@ -239,7 +243,7 @@ static int test_builtin(void) unsigned char dirt, offset; nid = curves[n].nid; - if (nid == NID_ipsec4) + if (nid == NID_ipsec4 || nid == NID_ipsec3) continue; /* create new ecdsa key (== EC_KEY) */ if (!TEST_ptr(eckey = EC_KEY_new()) @@ -248,12 +252,7 @@ static int test_builtin(void) goto builtin_err; EC_GROUP_free(group); degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey)); - if (degree < 160) { - /* drop the curve */ - EC_KEY_free(eckey); - eckey = NULL; - continue; - } + TEST_info("testing %s", OBJ_nid2sn(nid)); /* create key */ @@ -275,28 +274,32 @@ static int test_builtin(void) /* create signature */ sig_len = ECDSA_size(eckey); if (!TEST_ptr(signature = OPENSSL_malloc(sig_len)) - || !TEST_true(ECDSA_sign(0, digest, 20, signature, &sig_len, - eckey))) + || !TEST_true(ECDSA_sign(0, digest, SHA512_DIGEST_LENGTH, + signature, &sig_len, eckey))) goto builtin_err; /* verify signature */ - if (!TEST_int_eq(ECDSA_verify(0, digest, 20, signature, sig_len, - eckey), 1)) + if (!TEST_int_eq(ECDSA_verify(0, digest, SHA512_DIGEST_LENGTH, + signature, sig_len, eckey), + 1)) goto builtin_err; /* verify signature with the wrong key */ - if (!TEST_int_ne(ECDSA_verify(0, digest, 20, signature, sig_len, - wrong_eckey), 1)) + if (!TEST_int_ne(ECDSA_verify(0, digest, SHA512_DIGEST_LENGTH, + signature, sig_len, wrong_eckey), + 1)) goto builtin_err; /* wrong digest */ - if (!TEST_int_ne(ECDSA_verify(0, wrong_digest, 20, signature, - sig_len, eckey), 1)) + if (!TEST_int_ne(ECDSA_verify(0, wrong_digest, SHA512_DIGEST_LENGTH, + signature, sig_len, eckey), + 1)) goto builtin_err; /* wrong length */ - if (!TEST_int_ne(ECDSA_verify(0, digest, 20, signature, - sig_len - 1, eckey), 1)) + if (!TEST_int_ne(ECDSA_verify(0, digest, SHA512_DIGEST_LENGTH, + signature, sig_len - 1, eckey), + 1)) goto builtin_err; /* @@ -342,14 +345,15 @@ static int test_builtin(void) } sig_ptr2 = signature; sig_len = i2d_ECDSA_SIG(modified_sig, &sig_ptr2); - if (!TEST_false(ECDSA_verify(0, digest, 20, signature, sig_len, eckey))) + if (!TEST_false(ECDSA_verify(0, digest, SHA512_DIGEST_LENGTH, + signature, sig_len, eckey))) goto builtin_err; /* Sanity check: undo the modification and verify signature. */ raw_buf[offset] ^= dirt; if (!TEST_ptr(unmodified_r = BN_bin2bn(raw_buf, bn_len, NULL)) || !TEST_ptr(unmodified_s = BN_bin2bn(raw_buf + bn_len, - bn_len, NULL)) + bn_len, NULL)) || !TEST_true(ECDSA_SIG_set0(modified_sig, unmodified_r, unmodified_s))) { BN_free(unmodified_r); @@ -359,7 +363,8 @@ static int test_builtin(void) sig_ptr2 = signature; sig_len = i2d_ECDSA_SIG(modified_sig, &sig_ptr2); - if (!TEST_true(ECDSA_verify(0, digest, 20, signature, sig_len, eckey))) + if (!TEST_true(ECDSA_verify(0, digest, SHA512_DIGEST_LENGTH, + signature, sig_len, eckey))) goto builtin_err; /* cleanup */ diff --git a/util/indent.pro b/util/indent.pro index 18026460..443bddb1 100644 --- a/util/indent.pro +++ b/util/indent.pro @@ -637,3 +637,7 @@ -T ossl_uintmax_t -T ossl_uintmax_t -T CT_POLICY_EVAL_CTX +-T RAND_DRBG +-T RAND_DRBG_CTR +-T RAND_POOL +-T RAND_METHOD diff --git a/util/mkdef.pl b/util/mkdef.pl index 635e3e90..b40fd265 100755 --- a/util/mkdef.pl +++ b/util/mkdef.pl @@ -108,6 +108,7 @@ my %OS_data = ( platforms => { UNIX => 1, EXPORT_VAR_AS_FUNCTION => 0 } }, linux => 'solaris', # alias + "bsd-gcc" => 'solaris', # alias aix => { writer => \&writer_aix, sort => sorter_unix(), platforms => { UNIX => 1,