diff options
author | Jung-uk Kim <jkim@FreeBSD.org> | 2018-11-20 18:59:41 +0000 |
---|---|---|
committer | Jung-uk Kim <jkim@FreeBSD.org> | 2018-11-20 18:59:41 +0000 |
commit | 8c3f9abd70b3f447a4795c1b00b386b044fb322d (patch) | |
tree | 884976f2693f42bade35b92edc3c1f7f8c53825b /crypto | |
parent | a43ce912fc025d11e1395506111f75fc194d7ba5 (diff) | |
download | src-test-8c3f9abd70b3f447a4795c1b00b386b044fb322d.tar.gz src-test-8c3f9abd70b3f447a4795c1b00b386b044fb322d.zip |
Import OpenSSL 1.1.1a.vendor/openssl/1.1.1a
Notes
Notes:
svn path=/vendor-crypto/openssl/dist/; revision=340690
svn path=/vendor-crypto/openssl/1.1.1a/; revision=340691; tag=vendor/openssl/1.1.1a
Diffstat (limited to 'crypto')
52 files changed, 734 insertions, 392 deletions
diff --git a/crypto/LPdir_unix.c b/crypto/LPdir_unix.c index 356089d7fd34a..b1022895c8554 100644 --- a/crypto/LPdir_unix.c +++ b/crypto/LPdir_unix.c @@ -51,7 +51,7 @@ #endif /* - * The POSIXly macro for the maximum number of characters in a file path is + * The POSIX macro for the maximum number of characters in a file path is * NAME_MAX. However, some operating systems use PATH_MAX instead. * Therefore, it seems natural to first check for PATH_MAX and use that, and * if it doesn't exist, use NAME_MAX. diff --git a/crypto/async/arch/async_posix.h b/crypto/async/arch/async_posix.h index b07c2cb01beb8..62449fe60e04f 100644 --- a/crypto/async/arch/async_posix.h +++ b/crypto/async/arch/async_posix.h @@ -17,7 +17,8 @@ # include <unistd.h> -# if _POSIX_VERSION >= 200112L +# if _POSIX_VERSION >= 200112L \ + && (_POSIX_VERSION < 200809L || defined(__GLIBC__)) # include <pthread.h> diff --git a/crypto/bio/b_sock2.c b/crypto/bio/b_sock2.c index 823732d64e1a3..5d82ab22dc304 100644 --- a/crypto/bio/b_sock2.c +++ b/crypto/bio/b_sock2.c @@ -133,7 +133,9 @@ int BIO_connect(int sock, const BIO_ADDR *addr, int options) */ int BIO_bind(int sock, const BIO_ADDR *addr, int options) { +# ifndef OPENSSL_SYS_WINDOWS int on = 1; +# endif if (sock == -1) { BIOerr(BIO_F_BIO_BIND, BIO_R_INVALID_SOCKET); diff --git a/crypto/bio/bio_lib.c b/crypto/bio/bio_lib.c index 95eef7d4bf5b8..ca375b911ae8b 100644 --- a/crypto/bio/bio_lib.c +++ b/crypto/bio/bio_lib.c @@ -52,7 +52,7 @@ static long bio_call_callback(BIO *b, int oper, const char *argp, size_t len, argi = (int)len; } - if (inret && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) { + if (inret > 0 && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) { if (*processed > INT_MAX) return -1; inret = *processed; @@ -60,7 +60,7 @@ static long bio_call_callback(BIO *b, int oper, const char *argp, size_t len, ret = b->callback(b, oper, argp, argi, argl, inret); - if (ret >= 0 && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) { + if (ret > 0 && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) { *processed = (size_t)ret; ret = 1; } diff --git a/crypto/bio/bss_log.c b/crypto/bio/bss_log.c index 4324f24126818..e9ab932ec2953 100644 --- a/crypto/bio/bss_log.c +++ b/crypto/bio/bss_log.c @@ -408,4 +408,9 @@ static void xcloselog(BIO *bp) # endif /* Unix */ +#else /* NO_SYSLOG */ +const BIO_METHOD *BIO_s_log(void) +{ + return NULL; +} #endif /* NO_SYSLOG */ diff --git a/crypto/bn/asm/x86_64-gcc.c b/crypto/bn/asm/x86_64-gcc.c index d38f337164773..31839ba060fa5 100644 --- a/crypto/bn/asm/x86_64-gcc.c +++ b/crypto/bn/asm/x86_64-gcc.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-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 @@ -64,12 +64,6 @@ * machine. */ -# if defined(_WIN64) || !defined(__LP64__) -# define BN_ULONG unsigned long long -# else -# define BN_ULONG unsigned long -# endif - # undef mul # undef mul_add diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c index 2c92d7eac9d51..c026ffcb339ce 100644 --- a/crypto/bn/bn_exp.c +++ b/crypto/bn/bn_exp.c @@ -1077,7 +1077,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, * is not only slower but also makes each bit vulnerable to * EM (and likely other) side-channel attacks like One&Done * (for details see "One&Done: A Single-Decryption EM-Based - * Attack on OpenSSL’s Constant-Time Blinded RSA" by M. Alam, + * Attack on OpenSSL's Constant-Time Blinded RSA" by M. Alam, * H. Khan, M. Dey, N. Sinha, R. Callan, A. Zajic, and * M. Prvulovic, in USENIX Security'18) */ diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c index 266a3dd3046b9..80f910c807793 100644 --- a/crypto/bn/bn_lib.c +++ b/crypto/bn/bn_lib.c @@ -767,26 +767,30 @@ void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) b->neg ^= t; /*- - * Idea behind BN_FLG_STATIC_DATA is actually to - * indicate that data may not be written to. - * Intention is actually to treat it as it's - * read-only data, and some (if not most) of it does - * reside in read-only segment. In other words - * observation of BN_FLG_STATIC_DATA in - * BN_consttime_swap should be treated as fatal - * condition. It would either cause SEGV or - * effectively cause data corruption. - * BN_FLG_MALLOCED refers to BN structure itself, - * and hence must be preserved. Remaining flags are - * BN_FLG_CONSTIME and BN_FLG_SECURE. Latter must be - * preserved, because it determines how x->d was - * allocated and hence how to free it. This leaves - * BN_FLG_CONSTTIME that one can do something about. - * To summarize it's sufficient to mask and swap - * BN_FLG_CONSTTIME alone. BN_FLG_STATIC_DATA should - * be treated as fatal. + * BN_FLG_STATIC_DATA: indicates that data may not be written to. Intention + * is actually to treat it as it's read-only data, and some (if not most) + * of it does reside in read-only segment. In other words observation of + * BN_FLG_STATIC_DATA in BN_consttime_swap should be treated as fatal + * condition. It would either cause SEGV or effectively cause data + * corruption. + * + * BN_FLG_MALLOCED: refers to BN structure itself, and hence must be + * preserved. + * + * BN_FLG_SECURE: must be preserved, because it determines how x->d was + * allocated and hence how to free it. + * + * BN_FLG_CONSTTIME: sufficient to mask and swap + * + * BN_FLG_FIXED_TOP: indicates that we haven't called bn_correct_top() on + * the data, so the d array may be padded with additional 0 values (i.e. + * top could be greater than the minimal value that it could be). We should + * be swapping it */ - t = ((a->flags ^ b->flags) & BN_FLG_CONSTTIME) & condition; + +#define BN_CONSTTIME_SWAP_FLAGS (BN_FLG_CONSTTIME | BN_FLG_FIXED_TOP) + + t = ((a->flags ^ b->flags) & BN_CONSTTIME_SWAP_FLAGS) & condition; a->flags ^= t; b->flags ^= t; diff --git a/crypto/build.info b/crypto/build.info index b515b7318efb1..2c619c62e8439 100644 --- a/crypto/build.info +++ b/crypto/build.info @@ -2,7 +2,7 @@ LIBS=../libcrypto SOURCE[../libcrypto]=\ cryptlib.c mem.c mem_dbg.c cversion.c ex_data.c cpt_err.c \ ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fopen.c ctype.c \ - threads_pthread.c threads_win.c threads_none.c \ + threads_pthread.c threads_win.c threads_none.c getenv.c \ o_init.c o_fips.c mem_sec.c init.c {- $target{cpuid_asm_src} -} \ {- $target{uplink_aux_src} -} EXTRA= ../ms/uplink-x86.pl ../ms/uplink.c ../ms/applink.c \ diff --git a/crypto/conf/conf_api.c b/crypto/conf/conf_api.c index 72fe2da1ad785..5e57d749ce5e7 100644 --- a/crypto/conf/conf_api.c +++ b/crypto/conf/conf_api.c @@ -10,6 +10,7 @@ /* Part of the code in here was originally in conf.c, which is now removed */ #include "e_os.h" +#include "internal/cryptlib.h" #include <stdlib.h> #include <string.h> #include <openssl/conf.h> @@ -82,7 +83,7 @@ char *_CONF_get_string(const CONF *conf, const char *section, if (v != NULL) return v->value; if (strcmp(section, "ENV") == 0) { - p = getenv(name); + p = ossl_safe_getenv(name); if (p != NULL) return p; } @@ -95,7 +96,7 @@ char *_CONF_get_string(const CONF *conf, const char *section, else return NULL; } else - return getenv(name); + return ossl_safe_getenv(name); } static unsigned long conf_value_hash(const CONF_VALUE *v) diff --git a/crypto/conf/conf_mod.c b/crypto/conf/conf_mod.c index df53609cc47e4..51f262e774dd6 100644 --- a/crypto/conf/conf_mod.c +++ b/crypto/conf/conf_mod.c @@ -480,11 +480,8 @@ char *CONF_get1_default_config_file(void) char *file, *sep = ""; int len; - if (!OPENSSL_issetugid()) { - file = getenv("OPENSSL_CONF"); - if (file) - return OPENSSL_strdup(file); - } + if ((file = ossl_safe_getenv("OPENSSL_CONF")) != NULL) + return OPENSSL_strdup(file); len = strlen(X509_get_default_cert_area()); #ifndef OPENSSL_SYS_VMS diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c index b1e535a695964..1cd77c96d2f7f 100644 --- a/crypto/cryptlib.c +++ b/crypto/cryptlib.c @@ -204,7 +204,7 @@ int OPENSSL_isservice(void) if (_OPENSSL_isservice.p == NULL) { HANDLE mod = GetModuleHandle(NULL); - FARPROC f; + FARPROC f = NULL; if (mod != NULL) f = GetProcAddress(mod, "_OPENSSL_isservice"); diff --git a/crypto/ct/ct_log.c b/crypto/ct/ct_log.c index be6681dca74e6..c1bca3e1415e5 100644 --- a/crypto/ct/ct_log.c +++ b/crypto/ct/ct_log.c @@ -137,7 +137,7 @@ static int ctlog_new_from_conf(CTLOG **ct_log, const CONF *conf, const char *sec int CTLOG_STORE_load_default_file(CTLOG_STORE *store) { - const char *fpath = getenv(CTLOG_FILE_EVP); + const char *fpath = ossl_safe_getenv(CTLOG_FILE_EVP); if (fpath == NULL) fpath = CTLOG_FILE; diff --git a/crypto/dsa/dsa_gen.c b/crypto/dsa/dsa_gen.c index 46f4f01ee0e49..383d853b6d373 100644 --- a/crypto/dsa/dsa_gen.c +++ b/crypto/dsa/dsa_gen.c @@ -327,6 +327,12 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, if (mctx == NULL) goto err; + /* make sure L > N, otherwise we'll get trapped in an infinite loop */ + if (L <= N) { + DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS); + goto err; + } + if (evpmd == NULL) { if (N == 160) evpmd = EVP_sha1(); diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c index ac1f65a51a751..7a0b0874c54e0 100644 --- a/crypto/dsa/dsa_ossl.c +++ b/crypto/dsa/dsa_ossl.c @@ -9,6 +9,7 @@ #include <stdio.h> #include "internal/cryptlib.h" +#include "internal/bn_int.h" #include <openssl/bn.h> #include <openssl/sha.h> #include "dsa_locl.h" @@ -23,6 +24,8 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa); static int dsa_init(DSA *dsa); static int dsa_finish(DSA *dsa); +static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q, + BN_CTX *ctx); static DSA_METHOD openssl_dsa_meth = { "OpenSSL DSA method", @@ -178,9 +181,9 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, { BN_CTX *ctx = NULL; BIGNUM *k, *kinv = NULL, *r = *rp; - BIGNUM *l, *m; + BIGNUM *l; int ret = 0; - int q_bits; + int q_bits, q_words; if (!dsa->p || !dsa->q || !dsa->g) { DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS); @@ -189,8 +192,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, k = BN_new(); l = BN_new(); - m = BN_new(); - if (k == NULL || l == NULL || m == NULL) + if (k == NULL || l == NULL) goto err; if (ctx_in == NULL) { @@ -201,9 +203,9 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, /* Preallocate space */ q_bits = BN_num_bits(dsa->q); - if (!BN_set_bit(k, q_bits) - || !BN_set_bit(l, q_bits) - || !BN_set_bit(m, q_bits)) + q_words = bn_get_top(dsa->q); + if (!bn_wexpand(k, q_words + 2) + || !bn_wexpand(l, q_words + 2)) goto err; /* Get random k */ @@ -221,6 +223,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, } while (BN_is_zero(k)); BN_set_flags(k, BN_FLG_CONSTTIME); + BN_set_flags(l, BN_FLG_CONSTTIME); if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p, @@ -238,14 +241,17 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, * small timing information leakage. We then choose the sum that is * one bit longer than the modulus. * - * TODO: revisit the BN_copy aiming for a memory access agnostic - * conditional copy. + * There are some concerns about the efficacy of doing this. More + * specificly refer to the discussion starting with: + * https://github.com/openssl/openssl/pull/7486#discussion_r228323705 + * The fix is to rework BN so these gymnastics aren't required. */ if (!BN_add(l, k, dsa->q) - || !BN_add(m, l, dsa->q) - || !BN_copy(k, BN_num_bits(l) > q_bits ? l : m)) + || !BN_add(k, l, dsa->q)) goto err; + BN_consttime_swap(BN_is_bit_set(l, q_bits), k, l, q_words + 2); + if ((dsa)->meth->bn_mod_exp != NULL) { if (!dsa->meth->bn_mod_exp(dsa, r, dsa->g, k, dsa->p, ctx, dsa->method_mont_p)) @@ -258,8 +264,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, if (!BN_mod(r, r, dsa->q, ctx)) goto err; - /* Compute part of 's = inv(k) (m + xr) mod q' */ - if ((kinv = BN_mod_inverse(NULL, k, dsa->q, ctx)) == NULL) + /* Compute part of 's = inv(k) (m + xr) mod q' */ + if ((kinv = dsa_mod_inverse_fermat(k, dsa->q, ctx)) == NULL) goto err; BN_clear_free(*kinvp); @@ -273,7 +279,6 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BN_CTX_free(ctx); BN_clear_free(k); BN_clear_free(l); - BN_clear_free(m); return ret; } @@ -393,3 +398,31 @@ static int dsa_finish(DSA *dsa) BN_MONT_CTX_free(dsa->method_mont_p); return 1; } + +/* + * Compute the inverse of k modulo q. + * Since q is prime, Fermat's Little Theorem applies, which reduces this to + * mod-exp operation. Both the exponent and modulus are public information + * so a mod-exp that doesn't leak the base is sufficient. A newly allocated + * BIGNUM is returned which the caller must free. + */ +static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q, + BN_CTX *ctx) +{ + BIGNUM *res = NULL; + BIGNUM *r, *e; + + if ((r = BN_new()) == NULL) + return NULL; + + BN_CTX_start(ctx); + if ((e = BN_CTX_get(ctx)) != NULL + && BN_set_word(r, 2) + && BN_sub(e, q, r) + && BN_mod_exp_mont(r, k, e, q, ctx, NULL)) + res = r; + else + BN_free(r); + BN_CTX_end(ctx); + return res; +} diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c index 21302685d8776..a3164b5b2ed97 100644 --- a/crypto/ec/ec_ameth.c +++ b/crypto/ec/ec_ameth.c @@ -699,7 +699,7 @@ static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid) if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0) return 0; - if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_62) <= 0) + if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_63) <= 0) return 0; kdf_md = EVP_get_digestbynid(kdfmd_nid); @@ -864,7 +864,7 @@ static int ecdh_cms_encrypt(CMS_RecipientInfo *ri) ecdh_nid = NID_dh_cofactor_kdf; if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) { - kdf_type = EVP_PKEY_ECDH_KDF_X9_62; + kdf_type = EVP_PKEY_ECDH_KDF_X9_63; if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0) goto err; } else diff --git a/crypto/ec/ec_mult.c b/crypto/ec/ec_mult.c index 7e1b3650e76a9..0e0a5e1394aff 100644 --- a/crypto/ec/ec_mult.c +++ b/crypto/ec/ec_mult.c @@ -206,8 +206,8 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, */ cardinality_bits = BN_num_bits(cardinality); group_top = bn_get_top(cardinality); - if ((bn_wexpand(k, group_top + 1) == NULL) - || (bn_wexpand(lambda, group_top + 1) == NULL)) { + if ((bn_wexpand(k, group_top + 2) == NULL) + || (bn_wexpand(lambda, group_top + 2) == NULL)) { ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB); goto err; } @@ -244,7 +244,7 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, * k := scalar + 2*cardinality */ kbit = BN_is_bit_set(lambda, cardinality_bits); - BN_consttime_swap(kbit, k, lambda, group_top + 1); + BN_consttime_swap(kbit, k, lambda, group_top + 2); group_top = bn_get_top(group->field); if ((bn_wexpand(s->X, group_top) == NULL) diff --git a/crypto/ec/ec_pmeth.c b/crypto/ec/ec_pmeth.c index 5bee031b9201e..f4ad0749ef458 100644 --- a/crypto/ec/ec_pmeth.c +++ b/crypto/ec/ec_pmeth.c @@ -209,7 +209,7 @@ static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx, if (!pkey_ec_derive(ctx, ktmp, &ktmplen)) goto err; /* Do KDF stuff */ - if (!ECDH_KDF_X9_62(key, *keylen, ktmp, ktmplen, + if (!ecdh_KDF_X9_63(key, *keylen, ktmp, ktmplen, dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md)) goto err; rv = 1; @@ -281,7 +281,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_EC_KDF_TYPE: if (p1 == -2) return dctx->kdf_type; - if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_62) + if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_63) return -2; dctx->kdf_type = p1; return 1; diff --git a/crypto/ec/ecdh_kdf.c b/crypto/ec/ecdh_kdf.c index d47486eb346da..d686f9d897df1 100644 --- a/crypto/ec/ecdh_kdf.c +++ b/crypto/ec/ecdh_kdf.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-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 @@ -10,12 +10,13 @@ #include <string.h> #include <openssl/ec.h> #include <openssl/evp.h> +#include "ec_lcl.h" -/* Key derivation function from X9.62/SECG */ +/* Key derivation function from X9.63/SECG */ /* Way more than we will ever need */ #define ECDH_KDF_MAX (1 << 30) -int ECDH_KDF_X9_62(unsigned char *out, size_t outlen, +int ecdh_KDF_X9_63(unsigned char *out, size_t outlen, const unsigned char *Z, size_t Zlen, const unsigned char *sinfo, size_t sinfolen, const EVP_MD *md) @@ -66,3 +67,15 @@ int ECDH_KDF_X9_62(unsigned char *out, size_t outlen, EVP_MD_CTX_free(mctx); return rv; } + +/*- + * The old name for ecdh_KDF_X9_63 + * Retained for ABI compatibility + */ +int ECDH_KDF_X9_62(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + const unsigned char *sinfo, size_t sinfolen, + const EVP_MD *md) +{ + return ecdh_KDF_X9_63(out, outlen, Z, Zlen, sinfo, sinfolen, md); +} diff --git a/crypto/engine/eng_devcrypto.c b/crypto/engine/eng_devcrypto.c index 9deaf5c6188ca..4a0ba09a38bec 100644 --- a/crypto/engine/eng_devcrypto.c +++ b/crypto/engine/eng_devcrypto.c @@ -28,6 +28,13 @@ # define CHECK_BSD_STYLE_MACROS #endif +/* + * ONE global file descriptor for all sessions. This allows operations + * such as digest session data copying (see digest_copy()), but is also + * saner... why re-open /dev/crypto for every session? + */ +static int cfd; + /****************************************************************************** * * Ciphers @@ -39,7 +46,6 @@ *****/ struct cipher_ctx { - int cfd; struct session_op sess; /* to pass from init to do_cipher */ @@ -69,7 +75,7 @@ static const struct cipher_data_st { { NID_aes_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC }, { NID_aes_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC }, #ifndef OPENSSL_NO_RC4 - { NID_rc4, 1, 16, 0, CRYPTO_ARC4 }, + { NID_rc4, 1, 16, 0, EVP_CIPH_STREAM_CIPHER, CRYPTO_ARC4 }, #endif #if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_CTR) { NID_aes_128_ctr, 16, 128 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR }, @@ -135,19 +141,13 @@ static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const struct cipher_data_st *cipher_d = get_cipher_data(EVP_CIPHER_CTX_nid(ctx)); - if ((cipher_ctx->cfd = open("/dev/crypto", O_RDWR, 0)) < 0) { - SYSerr(SYS_F_OPEN, errno); - return 0; - } - memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess)); cipher_ctx->sess.cipher = cipher_d->devcryptoid; cipher_ctx->sess.keylen = cipher_d->keylen; cipher_ctx->sess.key = (void *)key; cipher_ctx->op = enc ? COP_ENCRYPT : COP_DECRYPT; - if (ioctl(cipher_ctx->cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) { + if (ioctl(cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) { SYSerr(SYS_F_IOCTL, errno); - close(cipher_ctx->cfd); return 0; } @@ -186,7 +186,7 @@ static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, cryp.flags = COP_FLAG_WRITE_IV; #endif - if (ioctl(cipher_ctx->cfd, CIOCCRYPT, &cryp) < 0) { + if (ioctl(cfd, CIOCCRYPT, &cryp) < 0) { SYSerr(SYS_F_IOCTL, errno); return 0; } @@ -212,14 +212,10 @@ static int cipher_cleanup(EVP_CIPHER_CTX *ctx) struct cipher_ctx *cipher_ctx = (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); - if (ioctl(cipher_ctx->cfd, CIOCFSESSION, &cipher_ctx->sess) < 0) { + if (ioctl(cfd, CIOCFSESSION, &cipher_ctx->sess.ses) < 0) { SYSerr(SYS_F_IOCTL, errno); return 0; } - if (close(cipher_ctx->cfd) < 0) { - SYSerr(SYS_F_CLOSE, errno); - return 0; - } return 1; } @@ -233,14 +229,10 @@ static int known_cipher_nids[OSSL_NELEM(cipher_data)]; static int known_cipher_nids_amount = -1; /* -1 indicates not yet initialised */ static EVP_CIPHER *known_cipher_methods[OSSL_NELEM(cipher_data)] = { NULL, }; -static void prepare_cipher_methods() +static void prepare_cipher_methods(void) { size_t i; struct session_op sess; - int cfd; - - if ((cfd = open("/dev/crypto", O_RDWR, 0)) < 0) - return; memset(&sess, 0, sizeof(sess)); sess.key = (void *)"01234567890123456789012345678901234567890123456789"; @@ -255,7 +247,7 @@ static void prepare_cipher_methods() sess.cipher = cipher_data[i].devcryptoid; sess.keylen = cipher_data[i].keylen; if (ioctl(cfd, CIOCGSESSION, &sess) < 0 - || ioctl(cfd, CIOCFSESSION, &sess) < 0) + || ioctl(cfd, CIOCFSESSION, &sess.ses) < 0) continue; if ((known_cipher_methods[i] = @@ -281,8 +273,6 @@ static void prepare_cipher_methods() cipher_data[i].nid; } } - - close(cfd); } static const EVP_CIPHER *get_cipher_method(int nid) @@ -308,7 +298,7 @@ static void destroy_cipher_method(int nid) known_cipher_methods[i] = NULL; } -static void destroy_all_cipher_methods() +static void destroy_all_cipher_methods(void) { size_t i; @@ -329,11 +319,12 @@ static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher, /* * We only support digests if the cryptodev implementation supports multiple - * data updates. Otherwise, we would be forced to maintain a cache, which is - * perilous if there's a lot of data coming in (if someone wants to checksum - * an OpenSSL tarball, for example). + * data updates and session copying. Otherwise, we would be forced to maintain + * a cache, which is perilous if there's a lot of data coming in (if someone + * wants to checksum an OpenSSL tarball, for example). */ -#if defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL) +#if defined(CIOCCPHASH) && defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL) +#define IMPLEMENT_DIGEST /****************************************************************************** * @@ -346,7 +337,6 @@ static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher, *****/ struct digest_ctx { - int cfd; struct session_op sess; int init; }; @@ -413,19 +403,12 @@ static int digest_init(EVP_MD_CTX *ctx) const struct digest_data_st *digest_d = get_digest_data(EVP_MD_CTX_type(ctx)); - if (digest_ctx->init == 0 - && (digest_ctx->cfd = open("/dev/crypto", O_RDWR, 0)) < 0) { - SYSerr(SYS_F_OPEN, errno); - return 0; - } - digest_ctx->init = 1; memset(&digest_ctx->sess, 0, sizeof(digest_ctx->sess)); digest_ctx->sess.mac = digest_d->devcryptoid; - if (ioctl(digest_ctx->cfd, CIOCGSESSION, &digest_ctx->sess) < 0) { + if (ioctl(cfd, CIOCGSESSION, &digest_ctx->sess) < 0) { SYSerr(SYS_F_IOCTL, errno); - close(digest_ctx->cfd); return 0; } @@ -444,7 +427,7 @@ static int digest_op(struct digest_ctx *ctx, const void *src, size_t srclen, cryp.dst = NULL; cryp.mac = res; cryp.flags = flags; - return ioctl(ctx->cfd, CIOCCRYPT, &cryp); + return ioctl(cfd, CIOCCRYPT, &cryp); } static int digest_update(EVP_MD_CTX *ctx, const void *data, size_t count) @@ -472,7 +455,7 @@ static int digest_final(EVP_MD_CTX *ctx, unsigned char *md) SYSerr(SYS_F_IOCTL, errno); return 0; } - if (ioctl(digest_ctx->cfd, CIOCFSESSION, &digest_ctx->sess) < 0) { + if (ioctl(cfd, CIOCFSESSION, &digest_ctx->sess.ses) < 0) { SYSerr(SYS_F_IOCTL, errno); return 0; } @@ -480,16 +463,38 @@ static int digest_final(EVP_MD_CTX *ctx, unsigned char *md) return 1; } -static int digest_cleanup(EVP_MD_CTX *ctx) +static int digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) { - struct digest_ctx *digest_ctx = - (struct digest_ctx *)EVP_MD_CTX_md_data(ctx); + struct digest_ctx *digest_from = + (struct digest_ctx *)EVP_MD_CTX_md_data(from); + struct digest_ctx *digest_to = + (struct digest_ctx *)EVP_MD_CTX_md_data(to); + struct cphash_op cphash; + + if (digest_from == NULL) + return 1; - if (close(digest_ctx->cfd) < 0) { - SYSerr(SYS_F_CLOSE, errno); + if (digest_from->init != 1) { + SYSerr(SYS_F_IOCTL, EINVAL); return 0; } + if (!digest_init(to)) { + SYSerr(SYS_F_IOCTL, errno); + return 0; + } + + cphash.src_ses = digest_from->sess.ses; + cphash.dst_ses = digest_to->sess.ses; + if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) { + SYSerr(SYS_F_IOCTL, errno); + return 0; + } + return 1; +} + +static int digest_cleanup(EVP_MD_CTX *ctx) +{ return 1; } @@ -502,14 +507,10 @@ static int known_digest_nids[OSSL_NELEM(digest_data)]; static int known_digest_nids_amount = -1; /* -1 indicates not yet initialised */ static EVP_MD *known_digest_methods[OSSL_NELEM(digest_data)] = { NULL, }; -static void prepare_digest_methods() +static void prepare_digest_methods(void) { size_t i; struct session_op sess; - int cfd; - - if ((cfd = open("/dev/crypto", O_RDWR, 0)) < 0) - return; memset(&sess, 0, sizeof(sess)); @@ -522,7 +523,7 @@ static void prepare_digest_methods() */ sess.mac = digest_data[i].devcryptoid; if (ioctl(cfd, CIOCGSESSION, &sess) < 0 - || ioctl(cfd, CIOCFSESSION, &sess) < 0) + || ioctl(cfd, CIOCFSESSION, &sess.ses) < 0) continue; if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid, @@ -532,6 +533,7 @@ static void prepare_digest_methods() || !EVP_MD_meth_set_init(known_digest_methods[i], digest_init) || !EVP_MD_meth_set_update(known_digest_methods[i], digest_update) || !EVP_MD_meth_set_final(known_digest_methods[i], digest_final) + || !EVP_MD_meth_set_copy(known_digest_methods[i], digest_copy) || !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup) || !EVP_MD_meth_set_app_datasize(known_digest_methods[i], sizeof(struct digest_ctx))) { @@ -541,8 +543,6 @@ static void prepare_digest_methods() known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid; } } - - close(cfd); } static const EVP_MD *get_digest_method(int nid) @@ -568,7 +568,7 @@ static void destroy_digest_method(int nid) known_digest_methods[i] = NULL; } -static void destroy_all_digest_methods() +static void destroy_all_digest_methods(void) { size_t i; @@ -598,9 +598,12 @@ static int devcrypto_digests(ENGINE *e, const EVP_MD **digest, static int devcrypto_unload(ENGINE *e) { destroy_all_cipher_methods(); -#if defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL) +#ifdef IMPLEMENT_DIGEST destroy_all_digest_methods(); #endif + + close(cfd); + return 1; } /* @@ -611,23 +614,30 @@ void engine_load_devcrypto_int() { ENGINE *e = NULL; - if (access("/dev/crypto", R_OK | W_OK) < 0) { - fprintf(stderr, - "/dev/crypto not present, not enabling devcrypto engine\n"); + if ((cfd = open("/dev/crypto", O_RDWR, 0)) < 0) { + fprintf(stderr, "Could not open /dev/crypto: %s\n", strerror(errno)); return; } prepare_cipher_methods(); -#if defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL) +#ifdef IMPLEMENT_DIGEST prepare_digest_methods(); #endif - if ((e = ENGINE_new()) == NULL) + if ((e = ENGINE_new()) == NULL + || !ENGINE_set_destroy_function(e, devcrypto_unload)) { + ENGINE_free(e); + /* + * We know that devcrypto_unload() won't be called when one of the + * above two calls have failed, so we close cfd explicitly here to + * avoid leaking resources. + */ + close(cfd); return; + } if (!ENGINE_set_id(e, "devcrypto") || !ENGINE_set_name(e, "/dev/crypto engine") - || !ENGINE_set_destroy_function(e, devcrypto_unload) /* * Asymmetric ciphers aren't well supported with /dev/crypto. Among the BSD @@ -664,7 +674,7 @@ void engine_load_devcrypto_int() # endif #endif || !ENGINE_set_ciphers(e, devcrypto_ciphers) -#if defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL) +#ifdef IMPLEMENT_DIGEST || !ENGINE_set_digests(e, devcrypto_digests) #endif ) { diff --git a/crypto/engine/eng_list.c b/crypto/engine/eng_list.c index 4bc7ea173cdce..45c339c54157a 100644 --- a/crypto/engine/eng_list.c +++ b/crypto/engine/eng_list.c @@ -317,8 +317,7 @@ ENGINE *ENGINE_by_id(const char *id) * Prevent infinite recursion if we're looking for the dynamic engine. */ if (strcmp(id, "dynamic")) { - if (OPENSSL_issetugid() - || (load_dir = getenv("OPENSSL_ENGINES")) == NULL) + if ((load_dir = ossl_safe_getenv("OPENSSL_ENGINES")) == NULL) load_dir = ENGINESDIR; iterator = ENGINE_by_id("dynamic"); if (!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) || diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 2c8572ba64ad4..5003d8735a4d2 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -1014,6 +1014,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/evp/e_aes.c b/crypto/evp/e_aes.c index 0add393276bcc..39eb4f379a99a 100644 --- a/crypto/evp/e_aes.c +++ b/crypto/evp/e_aes.c @@ -2241,7 +2241,7 @@ static int s390x_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (!cctx->aes.ccm.len_set) { /*- - * In case message length was not previously set explicitely via + * In case message length was not previously set explicitly via * Update(), set it now. */ ivec = EVP_CIPHER_CTX_iv_noconst(ctx); diff --git a/crypto/evp/e_rc2.c b/crypto/evp/e_rc2.c index 80afe316d7644..aa0d140186878 100644 --- a/crypto/evp/e_rc2.c +++ b/crypto/evp/e_rc2.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-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 @@ -92,7 +92,8 @@ static int rc2_meth_to_magic(EVP_CIPHER_CTX *e) { int i; - EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i); + if (EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i) <= 0) + return 0; if (i == 128) return RC2_128_MAGIC; else if (i == 64) @@ -136,8 +137,9 @@ static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) return -1; if (i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1)) return -1; - EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL); - if (EVP_CIPHER_CTX_set_key_length(c, key_bits / 8) <= 0) + if (EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, + NULL) <= 0 + || EVP_CIPHER_CTX_set_key_length(c, key_bits / 8) <= 0) return -1; } return i; diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index 633cb8863d6d4..7fbf895e07321 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -837,21 +837,21 @@ void EVP_PKEY_meth_get_ctrl(const EVP_PKEY_METHOD *pmeth, void EVP_PKEY_meth_get_check(const EVP_PKEY_METHOD *pmeth, int (**pcheck) (EVP_PKEY *pkey)) { - if (*pcheck) + if (pcheck != NULL) *pcheck = pmeth->check; } void EVP_PKEY_meth_get_public_check(const EVP_PKEY_METHOD *pmeth, int (**pcheck) (EVP_PKEY *pkey)) { - if (*pcheck) + if (pcheck != NULL) *pcheck = pmeth->public_check; } void EVP_PKEY_meth_get_param_check(const EVP_PKEY_METHOD *pmeth, int (**pcheck) (EVP_PKEY *pkey)) { - if (*pcheck) + if (pcheck != NULL) *pcheck = pmeth->param_check; } diff --git a/crypto/getenv.c b/crypto/getenv.c new file mode 100644 index 0000000000000..7e98b645b0d12 --- /dev/null +++ b/crypto/getenv.c @@ -0,0 +1,31 @@ +/* + * Copyright 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 + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include <stdlib.h> +#include "internal/cryptlib.h" + +char *ossl_safe_getenv(const char *name) +{ +#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) +# if __GLIBC_PREREQ(2, 17) +# define SECURE_GETENV + return secure_getenv(name); +# endif +#endif + +#ifndef SECURE_GETENV + if (OPENSSL_issetugid()) + return NULL; + return getenv(name); +#endif +} diff --git a/crypto/include/internal/ec_int.h b/crypto/include/internal/ec_int.h index bb4b5129d0019..182c39cc80566 100644 --- a/crypto/include/internal/ec_int.h +++ b/crypto/include/internal/ec_int.h @@ -41,5 +41,13 @@ __owur int ec_group_do_inverse_ord(const EC_GROUP *group, BIGNUM *res, const BIGNUM *x, BN_CTX *ctx); +/*- + * ECDH Key Derivation Function as defined in ANSI X9.63 + */ +int ecdh_KDF_X9_63(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + const unsigned char *sinfo, size_t sinfolen, + const EVP_MD *md); + # endif /* OPENSSL_NO_EC */ #endif diff --git a/crypto/include/internal/rand_int.h b/crypto/include/internal/rand_int.h index d91ee4c9342cb..888cab1b8f664 100644 --- a/crypto/include/internal/rand_int.h +++ b/crypto/include/internal/rand_int.h @@ -45,18 +45,21 @@ size_t rand_drbg_get_nonce(RAND_DRBG *drbg, void rand_drbg_cleanup_nonce(RAND_DRBG *drbg, unsigned char *out, size_t outlen); -size_t rand_drbg_get_additional_data(unsigned char **pout, size_t max_len); +size_t rand_drbg_get_additional_data(RAND_POOL *pool, unsigned char **pout); -void rand_drbg_cleanup_additional_data(unsigned char *out, size_t outlen); +void rand_drbg_cleanup_additional_data(RAND_POOL *pool, unsigned char *out); /* * 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); unsigned char *rand_pool_detach(RAND_POOL *pool); +void rand_pool_reattach(RAND_POOL *pool, unsigned char *buffer); size_t rand_pool_entropy(RAND_POOL *pool); size_t rand_pool_length(RAND_POOL *pool); diff --git a/crypto/kdf/hkdf.c b/crypto/kdf/hkdf.c index ec6090ad6a7b7..ae46fad609ac9 100644 --- a/crypto/kdf/hkdf.c +++ b/crypto/kdf/hkdf.c @@ -175,6 +175,18 @@ static int pkey_hkdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, return -2; } +static int pkey_hkdf_derive_init(EVP_PKEY_CTX *ctx) +{ + HKDF_PKEY_CTX *kctx = ctx->data; + + OPENSSL_clear_free(kctx->key, kctx->key_len); + OPENSSL_clear_free(kctx->salt, kctx->salt_len); + OPENSSL_cleanse(kctx->info, kctx->info_len); + memset(kctx, 0, sizeof(*kctx)); + + return 1; +} + static int pkey_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) { @@ -236,7 +248,7 @@ const EVP_PKEY_METHOD hkdf_pkey_meth = { 0, 0, - 0, + pkey_hkdf_derive_init, pkey_hkdf_derive, pkey_hkdf_ctrl, pkey_hkdf_ctrl_str diff --git a/crypto/mem_sec.c b/crypto/mem_sec.c index c4190bed33482..9e0f6702f4069 100644 --- a/crypto/mem_sec.c +++ b/crypto/mem_sec.c @@ -20,12 +20,8 @@ #include <string.h> -/* e_os.h includes unistd.h, which defines _POSIX_VERSION */ -#if !defined(OPENSSL_NO_SECURE_MEMORY) && defined(OPENSSL_SYS_UNIX) \ - && ( (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L) \ - || defined(__sun) || defined(__hpux) || defined(__sgi) \ - || defined(__osf__) ) -# define IMPLEMENTED +/* e_os.h defines OPENSSL_SECURE_MEMORY if secure memory can be implemented */ +#ifdef OPENSSL_SECURE_MEMORY # include <stdlib.h> # include <assert.h> # include <unistd.h> @@ -51,7 +47,7 @@ # define MAP_ANON MAP_ANONYMOUS #endif -#ifdef IMPLEMENTED +#ifdef OPENSSL_SECURE_MEMORY static size_t secure_mem_used; static int secure_mem_initialized; @@ -71,7 +67,7 @@ static int sh_allocated(const char *ptr); int CRYPTO_secure_malloc_init(size_t size, int minsize) { -#ifdef IMPLEMENTED +#ifdef OPENSSL_SECURE_MEMORY int ret = 0; if (!secure_mem_initialized) { @@ -89,12 +85,12 @@ int CRYPTO_secure_malloc_init(size_t size, int minsize) return ret; #else return 0; -#endif /* IMPLEMENTED */ +#endif /* OPENSSL_SECURE_MEMORY */ } int CRYPTO_secure_malloc_done(void) { -#ifdef IMPLEMENTED +#ifdef OPENSSL_SECURE_MEMORY if (secure_mem_used == 0) { sh_done(); secure_mem_initialized = 0; @@ -102,22 +98,22 @@ int CRYPTO_secure_malloc_done(void) sec_malloc_lock = NULL; return 1; } -#endif /* IMPLEMENTED */ +#endif /* OPENSSL_SECURE_MEMORY */ return 0; } int CRYPTO_secure_malloc_initialized(void) { -#ifdef IMPLEMENTED +#ifdef OPENSSL_SECURE_MEMORY return secure_mem_initialized; #else return 0; -#endif /* IMPLEMENTED */ +#endif /* OPENSSL_SECURE_MEMORY */ } void *CRYPTO_secure_malloc(size_t num, const char *file, int line) { -#ifdef IMPLEMENTED +#ifdef OPENSSL_SECURE_MEMORY void *ret; size_t actual_size; @@ -132,12 +128,12 @@ void *CRYPTO_secure_malloc(size_t num, const char *file, int line) return ret; #else return CRYPTO_malloc(num, file, line); -#endif /* IMPLEMENTED */ +#endif /* OPENSSL_SECURE_MEMORY */ } void *CRYPTO_secure_zalloc(size_t num, const char *file, int line) { -#ifdef IMPLEMENTED +#ifdef OPENSSL_SECURE_MEMORY if (secure_mem_initialized) /* CRYPTO_secure_malloc() zeroes allocations when it is implemented */ return CRYPTO_secure_malloc(num, file, line); @@ -147,7 +143,7 @@ void *CRYPTO_secure_zalloc(size_t num, const char *file, int line) void CRYPTO_secure_free(void *ptr, const char *file, int line) { -#ifdef IMPLEMENTED +#ifdef OPENSSL_SECURE_MEMORY size_t actual_size; if (ptr == NULL) @@ -164,13 +160,13 @@ void CRYPTO_secure_free(void *ptr, const char *file, int line) CRYPTO_THREAD_unlock(sec_malloc_lock); #else CRYPTO_free(ptr, file, line); -#endif /* IMPLEMENTED */ +#endif /* OPENSSL_SECURE_MEMORY */ } void CRYPTO_secure_clear_free(void *ptr, size_t num, const char *file, int line) { -#ifdef IMPLEMENTED +#ifdef OPENSSL_SECURE_MEMORY size_t actual_size; if (ptr == NULL) @@ -191,12 +187,12 @@ void CRYPTO_secure_clear_free(void *ptr, size_t num, return; OPENSSL_cleanse(ptr, num); CRYPTO_free(ptr, file, line); -#endif /* IMPLEMENTED */ +#endif /* OPENSSL_SECURE_MEMORY */ } int CRYPTO_secure_allocated(const void *ptr) { -#ifdef IMPLEMENTED +#ifdef OPENSSL_SECURE_MEMORY int ret; if (!secure_mem_initialized) @@ -207,21 +203,21 @@ int CRYPTO_secure_allocated(const void *ptr) return ret; #else return 0; -#endif /* IMPLEMENTED */ +#endif /* OPENSSL_SECURE_MEMORY */ } size_t CRYPTO_secure_used(void) { -#ifdef IMPLEMENTED +#ifdef OPENSSL_SECURE_MEMORY return secure_mem_used; #else return 0; -#endif /* IMPLEMENTED */ +#endif /* OPENSSL_SECURE_MEMORY */ } size_t CRYPTO_secure_actual_size(void *ptr) { -#ifdef IMPLEMENTED +#ifdef OPENSSL_SECURE_MEMORY size_t actual_size; CRYPTO_THREAD_write_lock(sec_malloc_lock); @@ -239,7 +235,7 @@ size_t CRYPTO_secure_actual_size(void *ptr) /* * SECURE HEAP IMPLEMENTATION */ -#ifdef IMPLEMENTED +#ifdef OPENSSL_SECURE_MEMORY /* @@ -647,4 +643,4 @@ static size_t sh_actual_size(char *ptr) OPENSSL_assert(sh_testbit(ptr, list, sh.bittable)); return sh.arena_size / (ONE << list); } -#endif /* IMPLEMENTED */ +#endif /* OPENSSL_SECURE_MEMORY */ diff --git a/crypto/o_fopen.c b/crypto/o_fopen.c index f08f99b414f5c..7d51ad725426c 100644 --- a/crypto/o_fopen.c +++ b/crypto/o_fopen.c @@ -25,14 +25,12 @@ # endif # endif +#include "e_os.h" #include "internal/cryptlib.h" #if !defined(OPENSSL_NO_STDIO) # include <stdio.h> -# ifdef _WIN32 -# include <windows.h> -# endif # ifdef __DJGPP__ # include <unistd.h> # endif diff --git a/crypto/pkcs12/p12_mutl.c b/crypto/pkcs12/p12_mutl.c index 88d1d66324e3a..0cbbed364a210 100644 --- a/crypto/pkcs12/p12_mutl.c +++ b/crypto/pkcs12/p12_mutl.c @@ -7,13 +7,13 @@ * https://www.openssl.org/source/license.html */ -# include <stdio.h> -# include "internal/cryptlib.h" -# include <openssl/crypto.h> -# include <openssl/hmac.h> -# include <openssl/rand.h> -# include <openssl/pkcs12.h> -# include "p12_lcl.h" +#include <stdio.h> +#include "internal/cryptlib.h" +#include <openssl/crypto.h> +#include <openssl/hmac.h> +#include <openssl/rand.h> +#include <openssl/pkcs12.h> +#include "p12_lcl.h" int PKCS12_mac_present(const PKCS12 *p12) { @@ -44,7 +44,7 @@ void PKCS12_get0_mac(const ASN1_OCTET_STRING **pmac, } } -# define TK26_MAC_KEY_LEN 32 +#define TK26_MAC_KEY_LEN 32 static int pkcs12_gen_gost_mac_key(const char *pass, int passlen, const unsigned char *salt, int saltlen, @@ -112,7 +112,7 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, if ((md_type_nid == NID_id_GostR3411_94 || md_type_nid == NID_id_GostR3411_2012_256 || md_type_nid == NID_id_GostR3411_2012_512) - && !getenv("LEGACY_GOST_PKCS12")) { + && ossl_safe_getenv("LEGACY_GOST_PKCS12") == NULL) { md_size = TK26_MAC_KEY_LEN; if (!pkcs12_gen_gost_mac_key(pass, passlen, salt, saltlen, iter, md_size, key, md_type)) { diff --git a/crypto/poly1305/poly1305_ieee754.c b/crypto/poly1305/poly1305_ieee754.c index 995a02e5c139c..7cfd968645ffe 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 fe15164451e8e..a243361b56e40 100644 --- a/crypto/rand/drbg_ctr.c +++ b/crypto/rand/drbg_ctr.c @@ -402,10 +402,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) @@ -417,9 +417,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_lib.c b/crypto/rand/drbg_lib.c index 729b49c943727..a13282181d6d1 100644 --- a/crypto/rand/drbg_lib.c +++ b/crypto/rand/drbg_lib.c @@ -82,6 +82,10 @@ static unsigned int slave_reseed_interval = SLAVE_RESEED_INTERVAL; static time_t master_reseed_time_interval = MASTER_RESEED_TIME_INTERVAL; static time_t slave_reseed_time_interval = SLAVE_RESEED_TIME_INTERVAL; +/* A logical OR of all used DRBG flag bits (currently there is only one) */ +static const unsigned int rand_drbg_used_flags = + RAND_DRBG_FLAG_CTR_NO_DF; + static RAND_DRBG *drbg_setup(RAND_DRBG *parent); static RAND_DRBG *rand_drbg_new(int secure, @@ -105,16 +109,27 @@ int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags) flags = rand_drbg_flags; } + /* If set is called multiple times - clear the old one */ + if (drbg->type != 0 && (type != drbg->type || flags != drbg->flags)) { + drbg->meth->uninstantiate(drbg); + rand_pool_free(drbg->adin_pool); + drbg->adin_pool = NULL; + } + drbg->state = DRBG_UNINITIALISED; drbg->flags = flags; drbg->type = type; switch (type) { default: + drbg->type = 0; + drbg->flags = 0; + drbg->meth = NULL; RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_UNSUPPORTED_DRBG_TYPE); return 0; case 0: /* Uninitialized; that's okay. */ + drbg->meth = NULL; return 1; case NID_aes_128_ctr: case NID_aes_192_ctr: @@ -123,8 +138,10 @@ int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags) break; } - if (ret == 0) + if (ret == 0) { + drbg->state = DRBG_ERROR; RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_ERROR_INITIALISING_DRBG); + } return ret; } @@ -147,7 +164,7 @@ int RAND_DRBG_set_defaults(int type, unsigned int flags) break; } - if ((flags & ~RAND_DRBG_USED_FLAGS) != 0) { + if ((flags & ~rand_drbg_used_flags) != 0) { RANDerr(RAND_F_RAND_DRBG_SET_DEFAULTS, RAND_R_UNSUPPORTED_DRBG_FLAGS); return 0; } @@ -224,11 +241,8 @@ static RAND_DRBG *rand_drbg_new(int secure, return drbg; -err: - if (drbg->secure) - OPENSSL_secure_free(drbg); - else - OPENSSL_free(drbg); + err: + RAND_DRBG_free(drbg); return NULL; } @@ -253,6 +267,7 @@ void RAND_DRBG_free(RAND_DRBG *drbg) if (drbg->meth != NULL) drbg->meth->uninstantiate(drbg); + rand_pool_free(drbg->adin_pool); CRYPTO_THREAD_lock_free(drbg->lock); CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DRBG, drbg, &drbg->ex_data); @@ -312,11 +327,18 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg, max_entropylen += drbg->max_noncelen; } + drbg->reseed_next_counter = tsan_load(&drbg->reseed_prop_counter); + if (drbg->reseed_next_counter) { + drbg->reseed_next_counter++; + if(!drbg->reseed_next_counter) + drbg->reseed_next_counter = 1; + } + if (drbg->get_entropy != NULL) 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; } @@ -337,29 +359,15 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg, } drbg->state = DRBG_READY; - drbg->generate_counter = 0; + drbg->reseed_gen_counter = 1; drbg->reseed_time = time(NULL); - if (drbg->reseed_counter > 0) { - if (drbg->parent == NULL) - drbg->reseed_counter++; - else - drbg->reseed_counter = drbg->parent->reseed_counter; - } + tsan_store(&drbg->reseed_prop_counter, drbg->reseed_next_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) { - RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, - RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED); - drbg->state = DRBG_ERROR; - } - rand_pool_free(drbg->pool); - drbg->pool = NULL; - } if (drbg->state == DRBG_READY) return 1; return 0; @@ -375,6 +383,7 @@ end: int RAND_DRBG_uninstantiate(RAND_DRBG *drbg) { if (drbg->meth == NULL) { + drbg->state = DRBG_ERROR; RANDerr(RAND_F_RAND_DRBG_UNINSTANTIATE, RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED); return 0; @@ -419,13 +428,21 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg, } drbg->state = DRBG_ERROR; + + drbg->reseed_next_counter = tsan_load(&drbg->reseed_prop_counter); + if (drbg->reseed_next_counter) { + drbg->reseed_next_counter++; + if(!drbg->reseed_next_counter) + drbg->reseed_next_counter = 1; + } + if (drbg->get_entropy != NULL) entropylen = drbg->get_entropy(drbg, &entropy, drbg->strength, drbg->min_entropylen, 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; } @@ -434,16 +451,11 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg, goto end; drbg->state = DRBG_READY; - drbg->generate_counter = 0; + drbg->reseed_gen_counter = 1; drbg->reseed_time = time(NULL); - if (drbg->reseed_counter > 0) { - if (drbg->parent == NULL) - drbg->reseed_counter++; - else - drbg->reseed_counter = drbg->parent->reseed_counter; - } + tsan_store(&drbg->reseed_prop_counter, drbg->reseed_next_counter); -end: + end: if (entropy != NULL && drbg->cleanup_entropy != NULL) drbg->cleanup_entropy(drbg, entropy, entropylen); if (drbg->state == DRBG_READY) @@ -475,10 +487,12 @@ int rand_drbg_restart(RAND_DRBG *drbg, const unsigned char *adin = NULL; size_t adinlen = 0; - if (drbg->pool != NULL) { + if (drbg->seed_pool != NULL) { RANDerr(RAND_F_RAND_DRBG_RESTART, ERR_R_INTERNAL_ERROR); - rand_pool_free(drbg->pool); - drbg->pool = NULL; + drbg->state = DRBG_ERROR; + rand_pool_free(drbg->seed_pool); + drbg->seed_pool = NULL; + return 0; } if (buffer != NULL) { @@ -486,24 +500,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); - if (drbg->pool == NULL) + drbg->seed_pool = rand_pool_attach(buffer, len, entropy); + if (drbg->seed_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; @@ -543,14 +558,8 @@ int rand_drbg_restart(RAND_DRBG *drbg, } } - /* check whether a given entropy pool was cleared properly during reseed */ - if (drbg->pool != NULL) { - drbg->state = DRBG_ERROR; - RANDerr(RAND_F_RAND_DRBG_RESTART, ERR_R_INTERNAL_ERROR); - rand_pool_free(drbg->pool); - drbg->pool = NULL; - return 0; - } + rand_pool_free(drbg->seed_pool); + drbg->seed_pool = NULL; return drbg->state == DRBG_READY; } @@ -600,7 +609,7 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen, } if (drbg->reseed_interval > 0) { - if (drbg->generate_counter >= drbg->reseed_interval) + if (drbg->reseed_gen_counter >= drbg->reseed_interval) reseed_required = 1; } if (drbg->reseed_time_interval > 0) { @@ -609,8 +618,11 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen, || now - drbg->reseed_time >= drbg->reseed_time_interval) reseed_required = 1; } - if (drbg->reseed_counter > 0 && drbg->parent != NULL) { - if (drbg->reseed_counter != drbg->parent->reseed_counter) + if (drbg->parent != NULL) { + unsigned int reseed_counter = tsan_load(&drbg->reseed_prop_counter); + if (reseed_counter > 0 + && tsan_load(&drbg->parent->reseed_prop_counter) + != reseed_counter) reseed_required = 1; } @@ -629,7 +641,7 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen, return 0; } - drbg->generate_counter++; + drbg->reseed_gen_counter++; return 1; } @@ -647,9 +659,18 @@ int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen) unsigned char *additional = NULL; size_t additional_len; size_t chunk; - size_t ret; + size_t ret = 0; + + if (drbg->adin_pool == NULL) { + if (drbg->type == 0) + goto err; + drbg->adin_pool = rand_pool_new(0, 0, drbg->max_adinlen); + if (drbg->adin_pool == NULL) + goto err; + } - additional_len = rand_drbg_get_additional_data(&additional, drbg->max_adinlen); + additional_len = rand_drbg_get_additional_data(drbg->adin_pool, + &additional); for ( ; outlen > 0; outlen -= chunk, out += chunk) { chunk = outlen; @@ -661,9 +682,9 @@ int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen) } ret = 1; -err: - if (additional_len != 0) - OPENSSL_secure_clear_free(additional, additional_len); + err: + if (additional != NULL) + rand_drbg_cleanup_additional_data(drbg->adin_pool, additional); return ret; } @@ -682,7 +703,8 @@ int RAND_DRBG_set_callbacks(RAND_DRBG *drbg, RAND_DRBG_get_nonce_fn get_nonce, RAND_DRBG_cleanup_nonce_fn cleanup_nonce) { - if (drbg->state != DRBG_UNINITIALISED) + if (drbg->state != DRBG_UNINITIALISED + || drbg->parent != NULL) return 0; drbg->get_entropy = get_entropy; drbg->cleanup_entropy = cleanup_entropy; @@ -859,7 +881,7 @@ static RAND_DRBG *drbg_setup(RAND_DRBG *parent) goto err; /* enable seed propagation */ - drbg->reseed_counter = 1; + tsan_store(&drbg->reseed_prop_counter, 1); /* * Ignore instantiation error to support just-in-time instantiation. @@ -948,11 +970,49 @@ static int drbg_bytes(unsigned char *out, int count) return ret; } +/* + * Calculates the minimum length of a full entropy buffer + * which is necessary to seed (i.e. instantiate) the DRBG + * successfully. + */ +size_t rand_drbg_seedlen(RAND_DRBG *drbg) +{ + /* + * If no os entropy source is available then RAND_seed(buffer, bufsize) + * is expected to succeed if and only if the buffer length satisfies + * the following requirements, which follow from the calculations + * in RAND_DRBG_instantiate(). + */ + size_t min_entropy = drbg->strength; + size_t min_entropylen = drbg->min_entropylen; + + /* + * Extra entropy for the random nonce in the absence of a + * get_nonce callback, see comment in RAND_DRBG_instantiate(). + */ + if (drbg->min_noncelen > 0 && drbg->get_nonce == NULL) { + min_entropy += drbg->strength / 2; + min_entropylen += drbg->min_noncelen; + } + + /* + * Convert entropy requirement from bits to bytes + * (dividing by 8 without rounding upwards, because + * all entropy requirements are divisible by 8). + */ + min_entropy >>= 3; + + /* Return a value that satisfies both requirements */ + return min_entropy > min_entropylen ? min_entropy : min_entropylen; +} + /* Implements the default OpenSSL RAND_add() method */ static int drbg_add(const void *buf, int num, double randomness) { int ret = 0; RAND_DRBG *drbg = RAND_DRBG_get0_master(); + size_t buflen; + size_t seedlen; if (drbg == NULL) return 0; @@ -960,20 +1020,49 @@ 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) { + rand_drbg_lock(drbg); + seedlen = rand_drbg_seedlen(drbg); + + buflen = (size_t)num; + + if (buflen < seedlen || randomness < (double) seedlen) { +#if defined(OPENSSL_RAND_SEED_NONE) + /* + * If no os entropy source is available, a reseeding will fail + * inevitably. So we use a trick to mix the buffer contents into + * the DRBG state without forcing a reseeding: we generate a + * dummy random byte, using the buffer content as additional data. + * Note: This won't work with RAND_DRBG_FLAG_CTR_NO_DF. + */ + unsigned char dummy[1]; + + ret = RAND_DRBG_generate(drbg, dummy, sizeof(dummy), 0, buf, buflen); + rand_drbg_unlock(drbg); + return ret; +#else + /* + * If an os entropy source is avaible then we declare the buffer content + * as additional data by setting randomness to zero and trigger a regular + * reseeding. + */ + randomness = 0.0; +#endif + } + + + if (randomness > (double)seedlen) { /* * 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)seedlen; } - rand_drbg_lock(drbg); - ret = rand_drbg_restart(drbg, buf, - (size_t)(unsigned int)num, - (size_t)(8*randomness)); + ret = rand_drbg_restart(drbg, buf, buflen, (size_t)(8 * randomness)); rand_drbg_unlock(drbg); return ret; diff --git a/crypto/rand/rand_err.c b/crypto/rand/rand_err.c index 31480a6828381..6a870455d50a8 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 94ffc96f20e2e..c3e9804dc07e5 100755 --- a/crypto/rand/rand_lcl.h +++ b/crypto/rand/rand_lcl.h @@ -16,6 +16,9 @@ # include <openssl/hmac.h> # include <openssl/ec.h> # include <openssl/rand_drbg.h> +# include "internal/tsan_assist.h" + +# include "internal/numbers.h" /* How many times to read the TSC as a randomness source. */ # define TSC_READ_COUNT 4 @@ -32,18 +35,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 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 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 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 */ @@ -54,7 +81,7 @@ typedef enum drbg_status_e { } DRBG_STATUS; -/* intantiate */ +/* instantiate */ typedef int (*RAND_DRBG_instantiate_fn)(RAND_DRBG *ctx, const unsigned char *ent, size_t entlen, @@ -68,7 +95,7 @@ typedef int (*RAND_DRBG_reseed_fn)(RAND_DRBG *ctx, size_t entlen, const unsigned char *adin, size_t adinlen); -/* generat output */ +/* generate output */ typedef int (*RAND_DRBG_generate_fn)(RAND_DRBG *ctx, unsigned char *out, size_t outlen, @@ -122,10 +149,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 */ }; /* @@ -139,7 +168,7 @@ struct rand_drbg_st { int type; /* the nid of the underlying algorithm */ /* * Stores the value of the rand_fork_count global as of when we last - * reseeded. The DRG reseeds automatically whenever drbg->fork_count != + * reseeded. The DRBG reseeds automatically whenever drbg->fork_count != * rand_fork_count. Used to provide fork-safety and reseed this DRBG in * the child process. */ @@ -147,14 +176,19 @@ 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 * with respect to how randomness is added to the RNG during reseeding * (see PR #4328). */ - struct rand_pool_st *pool; + struct rand_pool_st *seed_pool; + + /* + * Auxiliary pool for additional data. + */ + struct rand_pool_st *adin_pool; /* * The following parameters are setup by the per-type "init" function. @@ -180,7 +214,7 @@ struct rand_drbg_st { size_t max_perslen, max_adinlen; /* Counts the number of generate requests since the last reseed. */ - unsigned int generate_counter; + unsigned int reseed_gen_counter; /* * Maximum number of generate requests until a reseed is required. * This value is ignored if it is zero. @@ -203,7 +237,8 @@ struct rand_drbg_st { * is added by RAND_add() or RAND_seed() will have an immediate effect on * the output of RAND_bytes() resp. RAND_priv_bytes(). */ - unsigned int reseed_counter; + TSAN_QUALIFIER unsigned int reseed_prop_counter; + unsigned int reseed_next_counter; size_t seedlen; DRBG_STATUS state; @@ -245,7 +280,7 @@ extern int rand_fork_count; /* DRBG helpers */ int rand_drbg_restart(RAND_DRBG *drbg, const unsigned char *buffer, size_t len, size_t entropy); - +size_t rand_drbg_seedlen(RAND_DRBG *drbg); /* locking api */ int rand_drbg_lock(RAND_DRBG *drbg); int rand_drbg_unlock(RAND_DRBG *drbg); diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c index e9bc9522101ca..d8639c4a03f36 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -31,7 +31,7 @@ int rand_fork_count; static CRYPTO_RWLOCK *rand_nonce_lock; static int rand_nonce_count; -static int rand_cleaning_up = 0; +static int rand_inited = 0; #ifdef OPENSSL_RAND_SEED_RDTSC /* @@ -146,17 +146,13 @@ 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->seed_pool != NULL) { + pool = drbg->seed_pool; + pool->entropy_requested = entropy; + } else { + pool = rand_pool_new(entropy, min_len, max_len); + if (pool == NULL) + return 0; } if (drbg->parent) { @@ -178,6 +174,8 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg, prediction_resistance, NULL, 0) != 0) bytes = bytes_needed; + drbg->reseed_next_counter + = tsan_load(&drbg->parent->reseed_prop_counter); rand_drbg_unlock(drbg->parent); rand_pool_add_end(pool, bytes, 8 * bytes); @@ -206,7 +204,8 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg, } err: - rand_pool_free(pool); + if (drbg->seed_pool == NULL) + rand_pool_free(pool); return ret; } @@ -217,7 +216,8 @@ 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->seed_pool == NULL) + OPENSSL_secure_clear_free(out, outlen); } @@ -279,14 +279,9 @@ void rand_drbg_cleanup_nonce(RAND_DRBG *drbg, * On success it allocates a buffer at |*pout| and returns the length of * the data. The buffer should get freed using OPENSSL_secure_clear_free(). */ -size_t rand_drbg_get_additional_data(unsigned char **pout, size_t max_len) +size_t rand_drbg_get_additional_data(RAND_POOL *pool, unsigned char **pout) { size_t ret = 0; - RAND_POOL *pool; - - pool = rand_pool_new(0, 0, max_len); - if (pool == NULL) - return 0; if (rand_pool_add_additional_data(pool) == 0) goto err; @@ -295,14 +290,12 @@ size_t rand_drbg_get_additional_data(unsigned char **pout, size_t max_len) *pout = rand_pool_detach(pool); err: - rand_pool_free(pool); - return ret; } -void rand_drbg_cleanup_additional_data(unsigned char *out, size_t outlen) +void rand_drbg_cleanup_additional_data(RAND_POOL *pool, unsigned char *out) { - OPENSSL_secure_clear_free(out, outlen); + rand_pool_reattach(pool, out); } void rand_fork(void) @@ -326,13 +319,15 @@ DEFINE_RUN_ONCE_STATIC(do_rand_init) if (rand_nonce_lock == NULL) goto err2; - if (!rand_cleaning_up && !rand_pool_init()) + if (!rand_pool_init()) goto err3; + rand_inited = 1; return 1; err3: - rand_pool_cleanup(); + CRYPTO_THREAD_lock_free(rand_nonce_lock); + rand_nonce_lock = NULL; err2: CRYPTO_THREAD_lock_free(rand_meth_lock); rand_meth_lock = NULL; @@ -348,7 +343,8 @@ void rand_cleanup_int(void) { const RAND_METHOD *meth = default_RAND_meth; - rand_cleaning_up = 1; + if (!rand_inited) + return; if (meth != NULL && meth->cleanup != NULL) meth->cleanup(); @@ -362,6 +358,7 @@ void rand_cleanup_int(void) rand_meth_lock = NULL; CRYPTO_THREAD_lock_free(rand_nonce_lock); rand_nonce_lock = NULL; + rand_inited = 0; } /* @@ -370,7 +367,8 @@ void rand_cleanup_int(void) */ void RAND_keep_random_devices_open(int keep) { - rand_pool_keep_random_devices_open(keep); + if (RUN_ONCE(&rand_init, do_rand_init)) + rand_pool_keep_random_devices_open(keep); } /* @@ -405,7 +403,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 +428,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 +447,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; @@ -458,6 +457,38 @@ err: } /* + * 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 <master> 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. */ void rand_pool_free(RAND_POOL *pool) @@ -465,7 +496,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); } @@ -496,15 +534,27 @@ size_t rand_pool_length(RAND_POOL *pool) /* * Detach the |pool| buffer and return it to the caller. * It's the responsibility of the caller to free the buffer - * using OPENSSL_secure_clear_free(). + * using OPENSSL_secure_clear_free() or to re-attach it + * again to the pool using rand_pool_reattach(). */ unsigned char *rand_pool_detach(RAND_POOL *pool) { unsigned char *ret = pool->buffer; pool->buffer = NULL; + pool->entropy = 0; return ret; } +/* + * Re-attach the |pool| buffer. It is only allowed to pass + * the |buffer| which was previously detached from the same pool. + */ +void rand_pool_reattach(RAND_POOL *pool, unsigned char *buffer) +{ + pool->buffer = buffer; + OPENSSL_cleanse(pool->buffer, pool->len); + pool->len = 0; +} /* * If |entropy_factor| bits contain 1 bit of entropy, how many bytes does one @@ -524,7 +574,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 +590,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; } @@ -601,6 +651,11 @@ int rand_pool_add(RAND_POOL *pool, return 0; } + if (pool->buffer == NULL) { + RANDerr(RAND_F_RAND_POOL_ADD, ERR_R_INTERNAL_ERROR); + return 0; + } + if (len > 0) { memcpy(pool->buffer + pool->len, buffer, len); pool->len += len; @@ -632,6 +687,11 @@ unsigned char *rand_pool_add_begin(RAND_POOL *pool, size_t len) return NULL; } + if (pool->buffer == NULL) { + RANDerr(RAND_F_RAND_POOL_ADD_BEGIN, ERR_R_INTERNAL_ERROR); + return 0; + } + return pool->buffer + pool->len; } diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c index 9c62a04ebf894..9d8ffdd537965 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; @@ -375,21 +386,13 @@ static void close_random_device(size_t n) rd->fd = -1; } -static void open_random_devices(void) -{ - size_t i; - - for (i = 0; i < OSSL_NELEM(random_devices); i++) - (void)get_random_device(i); -} - int rand_pool_init(void) { size_t i; for (i = 0; i < OSSL_NELEM(random_devices); i++) random_devices[i].fd = -1; - open_random_devices(); + return 1; } @@ -403,16 +406,13 @@ void rand_pool_cleanup(void) void rand_pool_keep_random_devices_open(int keep) { - if (keep) - open_random_devices(); - else + if (!keep) rand_pool_cleanup(); + 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 +427,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 +448,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 +485,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 +522,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 }; @@ -577,7 +575,7 @@ int rand_pool_add_nonce_data(RAND_POOL *pool) /* * Add process id, thread id, and a high resolution timestamp to - * ensure that the nonce is unique whith high probability for + * ensure that the nonce is unique with high probability for * different process instances. */ data.pid = getpid(); diff --git a/crypto/rand/randfile.c b/crypto/rand/randfile.c index c652ddcf1e6c0..1b737d1ba2ba3 100644 --- a/crypto/rand/randfile.c +++ b/crypto/rand/randfile.c @@ -16,6 +16,7 @@ #include <openssl/crypto.h> #include <openssl/rand.h> +#include <openssl/rand_drbg.h> #include <openssl/buffer.h> #ifdef OPENSSL_SYS_VMS @@ -48,7 +49,7 @@ # define S_ISREG(m) ((m) & S_IFREG) # endif -#define RAND_FILE_SIZE 1024 +#define RAND_BUF_SIZE 1024 #define RFILE ".rnd" #ifdef OPENSSL_SYS_VMS @@ -74,7 +75,16 @@ static __FILE_ptr32 (*const vms_fopen)(const char *, const char *, ...) = */ int RAND_load_file(const char *file, long bytes) { - unsigned char buf[RAND_FILE_SIZE]; + /* + * The load buffer size exceeds the chunk size by the comfortable amount + * of 'RAND_DRBG_STRENGTH' bytes (not bits!). This is done on purpose + * to avoid calling RAND_add() with a small final chunk. Instead, such + * a small final chunk will be added together with the previous chunk + * (unless it's the only one). + */ +#define RAND_LOAD_BUF_SIZE (RAND_BUF_SIZE + RAND_DRBG_STRENGTH) + unsigned char buf[RAND_LOAD_BUF_SIZE]; + #ifndef OPENSSL_NO_POSIX_IO struct stat sb; #endif @@ -98,8 +108,12 @@ int RAND_load_file(const char *file, long bytes) return -1; } - if (!S_ISREG(sb.st_mode) && bytes < 0) - bytes = 256; + if (bytes < 0) { + if (S_ISREG(sb.st_mode)) + bytes = sb.st_size; + else + bytes = RAND_DRBG_STRENGTH; + } #endif /* * On VMS, setbuf() will only take 32-bit pointers, and a compilation @@ -124,9 +138,9 @@ int RAND_load_file(const char *file, long bytes) for ( ; ; ) { if (bytes > 0) - n = (bytes < RAND_FILE_SIZE) ? (int)bytes : RAND_FILE_SIZE; + n = (bytes <= RAND_LOAD_BUF_SIZE) ? (int)bytes : RAND_BUF_SIZE; else - n = RAND_FILE_SIZE; + n = RAND_LOAD_BUF_SIZE; i = fread(buf, 1, n, in); #ifdef EINTR if (ferror(in) && errno == EINTR){ @@ -148,12 +162,18 @@ int RAND_load_file(const char *file, long bytes) OPENSSL_cleanse(buf, sizeof(buf)); fclose(in); + if (!RAND_status()) { + RANDerr(RAND_F_RAND_LOAD_FILE, RAND_R_RESEED_ERROR); + ERR_add_error_data(2, "Filename=", file); + return -1; + } + return ret; } int RAND_write_file(const char *file) { - unsigned char buf[RAND_FILE_SIZE]; + unsigned char buf[RAND_BUF_SIZE]; int ret = -1; FILE *out = NULL; #ifndef OPENSSL_NO_POSIX_IO @@ -222,9 +242,9 @@ int RAND_write_file(const char *file) chmod(file, 0600); #endif - ret = fwrite(buf, 1, RAND_FILE_SIZE, out); + ret = fwrite(buf, 1, RAND_BUF_SIZE, out); fclose(out); - OPENSSL_cleanse(buf, RAND_FILE_SIZE); + OPENSSL_cleanse(buf, RAND_BUF_SIZE); return ret; } @@ -262,11 +282,9 @@ const char *RAND_file_name(char *buf, size_t size) } } #else - if (OPENSSL_issetugid() != 0) { - use_randfile = 0; - } else if ((s = getenv("RANDFILE")) == NULL || *s == '\0') { + if ((s = ossl_safe_getenv("RANDFILE")) == NULL || *s == '\0') { use_randfile = 0; - s = getenv("HOME"); + s = ossl_safe_getenv("HOME"); } #endif diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c index 72d1b5e0715d6..49c34b7c36c91 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_meth.c b/crypto/rsa/rsa_meth.c index f5880a73d0f7b..def19f375f920 100644 --- a/crypto/rsa/rsa_meth.c +++ b/crypto/rsa/rsa_meth.c @@ -163,13 +163,13 @@ int RSA_meth_set_priv_dec(RSA_METHOD *meth, /* Can be null */ int (*RSA_meth_get_mod_exp(const RSA_METHOD *meth)) - (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) + (BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx) { return meth->rsa_mod_exp; } int RSA_meth_set_mod_exp(RSA_METHOD *meth, - int (*mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, + int (*mod_exp) (BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx)) { meth->rsa_mod_exp = mod_exp; diff --git a/crypto/rsa/rsa_ossl.c b/crypto/rsa/rsa_ossl.c index d581777eec9bd..2b1b006c2801d 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 3bce19be9ea40..1184cf233eba2 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/crypto/sha/asm/sha512p8-ppc.pl b/crypto/sha/asm/sha512p8-ppc.pl index 2792800b475cb..0d4fdd292c07a 100755 --- a/crypto/sha/asm/sha512p8-ppc.pl +++ b/crypto/sha/asm/sha512p8-ppc.pl @@ -166,8 +166,8 @@ $func: addi r11,r11,32 stvx v30,r10,$sp stvx v31,r11,$sp - li r11,-4096+255 - stw $vrsave,`$FRAME+6*$SIZE_T-4`($sp) # save vrsave + li r11,-4096+255 # 0xfffff0ff + stw $vrsave,`$FRAME-6*$SIZE_T-4`($sp) # save vrsave li $x10,0x10 $PUSH r26,`$FRAME-6*$SIZE_T`($sp) li $x20,0x20 @@ -286,24 +286,17 @@ $code.=<<___ if ($SZ==8); stvx_u $G,$x30,$ctx ___ $code.=<<___; - li r10,`$LOCALS+15` + addi $offload,$sp,`$LOCALS+15` mtlr $lrsave - li r11,`$LOCALS+31` mtspr 256,$vrsave - lvx v24,r10,$sp # ABI says so - addi r10,r10,32 - lvx v25,r11,$sp - addi r11,r11,32 - lvx v26,r10,$sp - addi r10,r10,32 - lvx v27,r11,$sp - addi r11,r11,32 - lvx v28,r10,$sp - addi r10,r10,32 - lvx v29,r11,$sp - addi r11,r11,32 - lvx v30,r10,$sp - lvx v31,r11,$sp + lvx v24,$x00,$offload # ABI says so + lvx v25,$x10,$offload + lvx v26,$x20,$offload + lvx v27,$x30,$offload + lvx v28,$x40,$offload + lvx v29,$x50,$offload + lvx v30,$x60,$offload + lvx v31,$x70,$offload $POP r26,`$FRAME-6*$SIZE_T`($sp) $POP r27,`$FRAME-5*$SIZE_T`($sp) $POP r28,`$FRAME-4*$SIZE_T`($sp) diff --git a/crypto/siphash/siphash.c b/crypto/siphash/siphash.c index ff84a29f82152..be74a38d934df 100644 --- a/crypto/siphash/siphash.c +++ b/crypto/siphash/siphash.c @@ -94,7 +94,19 @@ int SipHash_set_hash_size(SIPHASH *ctx, size_t hash_size) && hash_size != SIPHASH_MAX_DIGEST_SIZE) return 0; - ctx->hash_size = hash_size; + /* + * It's possible that the key was set first. If the hash size changes, + * we need to adjust v1 (see SipHash_Init(). + */ + + /* Start by adjusting the stored size, to make things easier */ + ctx->hash_size = siphash_adjust_hash_size(ctx->hash_size); + + /* Now, adjust ctx->v1 if the old and the new size differ */ + if ((size_t)ctx->hash_size != hash_size) { + ctx->v1 ^= 0xee; + ctx->hash_size = hash_size; + } return 1; } diff --git a/crypto/sm2/sm2_crypt.c b/crypto/sm2/sm2_crypt.c index 9c69a4505487b..4389fc731edd8 100644 --- a/crypto/sm2/sm2_crypt.c +++ b/crypto/sm2/sm2_crypt.c @@ -11,6 +11,7 @@ #include "internal/sm2.h" #include "internal/sm2err.h" +#include "internal/ec_int.h" /* ecdh_KDF_X9_63() */ #include <openssl/err.h> #include <openssl/evp.h> #include <openssl/bn.h> @@ -203,7 +204,7 @@ int sm2_encrypt(const EC_KEY *key, } /* X9.63 with no salt happens to match the KDF used in SM2 */ - if (!ECDH_KDF_X9_62(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0, + if (!ecdh_KDF_X9_63(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0, digest)) { SM2err(SM2_F_SM2_ENCRYPT, ERR_R_EVP_LIB); goto done; @@ -344,7 +345,7 @@ int sm2_decrypt(const EC_KEY *key, if (BN_bn2binpad(x2, x2y2, field_size) < 0 || BN_bn2binpad(y2, x2y2 + field_size, field_size) < 0 - || !ECDH_KDF_X9_62(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0, + || !ecdh_KDF_X9_63(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0, digest)) { SM2err(SM2_F_SM2_DECRYPT, ERR_R_INTERNAL_ERROR); goto done; diff --git a/crypto/sm2/sm2_sign.c b/crypto/sm2/sm2_sign.c index e594ffd10a0bb..0f9c14cb5f4c1 100644 --- a/crypto/sm2/sm2_sign.c +++ b/crypto/sm2/sm2_sign.c @@ -12,6 +12,7 @@ #include "internal/sm2.h" #include "internal/sm2err.h" #include "internal/ec_int.h" /* ec_group_do_inverse_ord() */ +#include "internal/numbers.h" #include <openssl/err.h> #include <openssl/evp.h> #include <openssl/err.h> diff --git a/crypto/ui/ui_openssl.c b/crypto/ui/ui_openssl.c index 45d48202b5613..6b996134df49e 100644 --- a/crypto/ui/ui_openssl.c +++ b/crypto/ui/ui_openssl.c @@ -415,6 +415,24 @@ static int open_console(UI *ui) is_a_tty = 0; else # endif +# ifdef ENXIO + /* + * Solaris can return ENXIO. + * This should be ok + */ + if (errno == ENXIO) + is_a_tty = 0; + else +# endif +# ifdef EIO + /* + * Linux can return EIO. + * This should be ok + */ + if (errno == EIO) + is_a_tty = 0; + else +# endif # ifdef ENODEV /* * MacOS X returns ENODEV (Operation not supported by device), diff --git a/crypto/x509/by_dir.c b/crypto/x509/by_dir.c index 11ac52ce3c557..b3760dbadf3ab 100644 --- a/crypto/x509/by_dir.c +++ b/crypto/x509/by_dir.c @@ -73,7 +73,7 @@ static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, switch (cmd) { case X509_L_ADD_DIR: if (argl == X509_FILETYPE_DEFAULT) { - const char *dir = getenv(X509_get_default_cert_dir_env()); + const char *dir = ossl_safe_getenv(X509_get_default_cert_dir_env()); if (dir) ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM); diff --git a/crypto/x509/by_file.c b/crypto/x509/by_file.c index 78d7fbdf4488e..244512c9352b3 100644 --- a/crypto/x509/by_file.c +++ b/crypto/x509/by_file.c @@ -46,7 +46,7 @@ static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, switch (cmd) { case X509_L_FILE_LOAD: if (argl == X509_FILETYPE_DEFAULT) { - file = getenv(X509_get_default_cert_file_env()); + file = ossl_safe_getenv(X509_get_default_cert_file_env()); if (file) ok = (X509_load_cert_crl_file(ctx, file, X509_FILETYPE_PEM) != 0); diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 3a60d412daf86..61e81922b4dab 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -517,15 +517,14 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) /* check_purpose() makes the callback as needed */ if (purpose > 0 && !check_purpose(ctx, x, purpose, i, must_be_ca)) return 0; - /* Check pathlen if not self issued */ - if ((i > 1) && !(x->ex_flags & EXFLAG_SI) - && (x->ex_pathlen != -1) - && (plen > (x->ex_pathlen + proxy_path_length + 1))) { + /* Check pathlen */ + if ((i > 1) && (x->ex_pathlen != -1) + && (plen > (x->ex_pathlen + proxy_path_length))) { if (!verify_cb_cert(ctx, x, i, X509_V_ERR_PATH_LENGTH_EXCEEDED)) return 0; } - /* Increment path length if not self issued */ - if (!(x->ex_flags & EXFLAG_SI)) + /* Increment path length if not a self issued intermediate CA */ + if (i > 0 && (x->ex_flags & EXFLAG_SI) == 0) plen++; /* * If this certificate is a proxy certificate, the next certificate |