summaryrefslogtreecommitdiffstats
path: root/freebsd/crypto
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-12-20 11:12:40 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-12-20 13:36:34 +0100
commit2b2563da953978f63e3e707f758fd600dcd19a32 (patch)
treea207b096c10788192b56025e8187f14d1b5a978d /freebsd/crypto
parentfreebsd/if_cpsw: Port. (diff)
downloadrtems-libbsd-2b2563da953978f63e3e707f758fd600dcd19a32.tar.bz2
Update to FreeBSD head 2018-12-20
Git mirror commit 19a6ceb89dbacf74697d493e48c388767126d418. It includes an update of wpa_supplicant to version 2.7. It includes an update of the OpenSSL baseline to version 1.1.1a. Update #3472.
Diffstat (limited to 'freebsd/crypto')
-rw-r--r--freebsd/crypto/openssl/crypto/LPdir_unix.c2
-rw-r--r--freebsd/crypto/openssl/crypto/async/arch/async_posix.h3
-rw-r--r--freebsd/crypto/openssl/crypto/bio/b_sock2.c2
-rw-r--r--freebsd/crypto/openssl/crypto/bio/bio_lib.c4
-rw-r--r--freebsd/crypto/openssl/crypto/bio/bss_log.c5
-rw-r--r--freebsd/crypto/openssl/crypto/bn/bn_exp.c2
-rw-r--r--freebsd/crypto/openssl/crypto/bn/bn_lib.c42
-rw-r--r--freebsd/crypto/openssl/crypto/conf/conf_api.c5
-rw-r--r--freebsd/crypto/openssl/crypto/conf/conf_mod.c7
-rw-r--r--freebsd/crypto/openssl/crypto/cryptlib.c2
-rw-r--r--freebsd/crypto/openssl/crypto/ct/ct_log.c2
-rw-r--r--freebsd/crypto/openssl/crypto/dsa/dsa_gen.c6
-rw-r--r--freebsd/crypto/openssl/crypto/dsa/dsa_ossl.c61
-rw-r--r--freebsd/crypto/openssl/crypto/ec/ec_ameth.c4
-rw-r--r--freebsd/crypto/openssl/crypto/ec/ec_mult.c6
-rw-r--r--freebsd/crypto/openssl/crypto/ec/ec_pmeth.c4
-rw-r--r--freebsd/crypto/openssl/crypto/ec/ecdh_kdf.c19
-rw-r--r--freebsd/crypto/openssl/crypto/engine/eng_devcrypto.c137
-rw-r--r--freebsd/crypto/openssl/crypto/engine/eng_list.c3
-rw-r--r--freebsd/crypto/openssl/crypto/evp/e_aes.c2
-rw-r--r--freebsd/crypto/openssl/crypto/evp/e_rc2.c10
-rw-r--r--freebsd/crypto/openssl/crypto/evp/pmeth_lib.c6
-rw-r--r--freebsd/crypto/openssl/crypto/getenv.c33
-rw-r--r--freebsd/crypto/openssl/crypto/include/internal/ec_int.h8
-rw-r--r--freebsd/crypto/openssl/crypto/include/internal/rand_int.h7
-rw-r--r--freebsd/crypto/openssl/crypto/kdf/hkdf.c14
-rw-r--r--freebsd/crypto/openssl/crypto/mem_sec.c50
-rw-r--r--freebsd/crypto/openssl/crypto/o_fopen.c4
-rw-r--r--freebsd/crypto/openssl/crypto/pkcs12/p12_mutl.c18
-rw-r--r--freebsd/crypto/openssl/crypto/rand/drbg_ctr.c12
-rw-r--r--freebsd/crypto/openssl/crypto/rand/drbg_lib.c225
-rw-r--r--freebsd/crypto/openssl/crypto/rand/rand_err.c1
-rw-r--r--freebsd/crypto/openssl/crypto/rand/rand_lcl.h69
-rw-r--r--freebsd/crypto/openssl/crypto/rand/rand_lib.c136
-rw-r--r--freebsd/crypto/openssl/crypto/rand/rand_unix.c56
-rw-r--r--freebsd/crypto/openssl/crypto/rand/randfile.c44
-rw-r--r--freebsd/crypto/openssl/crypto/rsa/rsa_lib.c16
-rw-r--r--freebsd/crypto/openssl/crypto/rsa/rsa_meth.c4
-rw-r--r--freebsd/crypto/openssl/crypto/rsa/rsa_ossl.c3
-rw-r--r--freebsd/crypto/openssl/crypto/siphash/siphash.c14
-rw-r--r--freebsd/crypto/openssl/crypto/sm2/sm2_crypt.c5
-rw-r--r--freebsd/crypto/openssl/crypto/sm2/sm2_sign.c1
-rw-r--r--freebsd/crypto/openssl/crypto/ui/ui_openssl.c18
-rw-r--r--freebsd/crypto/openssl/crypto/x509/by_dir.c2
-rw-r--r--freebsd/crypto/openssl/crypto/x509/by_file.c2
-rw-r--r--freebsd/crypto/openssl/crypto/x509/x509_vfy.c11
-rw-r--r--freebsd/crypto/openssl/e_os.h15
-rw-r--r--freebsd/crypto/openssl/include/internal/cryptlib.h2
-rw-r--r--freebsd/crypto/openssl/include/internal/tsan_assist.h6
-rw-r--r--freebsd/crypto/openssl/include/openssl/cryptoerr.h3
-rw-r--r--freebsd/crypto/openssl/include/openssl/ec.h13
-rw-r--r--freebsd/crypto/openssl/include/openssl/ocsp.h3
-rw-r--r--freebsd/crypto/openssl/include/openssl/opensslv.h4
-rw-r--r--freebsd/crypto/openssl/include/openssl/rand_drbg.h24
-rw-r--r--freebsd/crypto/openssl/include/openssl/randerr.h1
-rw-r--r--freebsd/crypto/openssl/include/openssl/rsa.h6
-rw-r--r--freebsd/crypto/openssl/include/openssl/ssl.h18
-rw-r--r--freebsd/crypto/openssl/include/openssl/symhacks.h17
-rw-r--r--freebsd/crypto/openssl/include/openssl/tls1.h1
-rw-r--r--freebsd/crypto/openssl/ssl/d1_lib.c93
-rw-r--r--freebsd/crypto/openssl/ssl/record/rec_layer_d1.c5
-rw-r--r--freebsd/crypto/openssl/ssl/record/record.h6
-rw-r--r--freebsd/crypto/openssl/ssl/record/record_locl.h2
-rw-r--r--freebsd/crypto/openssl/ssl/record/ssl3_record.c25
-rw-r--r--freebsd/crypto/openssl/ssl/s3_cbc.c7
-rw-r--r--freebsd/crypto/openssl/ssl/s3_enc.c8
-rw-r--r--freebsd/crypto/openssl/ssl/s3_lib.c24
-rw-r--r--freebsd/crypto/openssl/ssl/ssl_cert.c17
-rw-r--r--freebsd/crypto/openssl/ssl/ssl_ciph.c2
-rw-r--r--freebsd/crypto/openssl/ssl/ssl_lib.c62
-rw-r--r--freebsd/crypto/openssl/ssl/ssl_locl.h22
-rw-r--r--freebsd/crypto/openssl/ssl/statem/extensions.c12
-rw-r--r--freebsd/crypto/openssl/ssl/statem/extensions_clnt.c13
-rw-r--r--freebsd/crypto/openssl/ssl/statem/statem.c5
-rw-r--r--freebsd/crypto/openssl/ssl/statem/statem_clnt.c12
-rw-r--r--freebsd/crypto/openssl/ssl/statem/statem_lib.c59
-rw-r--r--freebsd/crypto/openssl/ssl/statem/statem_locl.h3
-rw-r--r--freebsd/crypto/openssl/ssl/statem/statem_srvr.c44
-rw-r--r--freebsd/crypto/openssl/ssl/t1_lib.c45
-rw-r--r--freebsd/crypto/openssl/ssl/tls13_enc.c16
80 files changed, 1140 insertions, 542 deletions
diff --git a/freebsd/crypto/openssl/crypto/LPdir_unix.c b/freebsd/crypto/openssl/crypto/LPdir_unix.c
index ba056031..130cb056 100644
--- a/freebsd/crypto/openssl/crypto/LPdir_unix.c
+++ b/freebsd/crypto/openssl/crypto/LPdir_unix.c
@@ -53,7 +53,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/freebsd/crypto/openssl/crypto/async/arch/async_posix.h b/freebsd/crypto/openssl/crypto/async/arch/async_posix.h
index b07c2cb0..62449fe6 100644
--- a/freebsd/crypto/openssl/crypto/async/arch/async_posix.h
+++ b/freebsd/crypto/openssl/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/freebsd/crypto/openssl/crypto/bio/b_sock2.c b/freebsd/crypto/openssl/crypto/bio/b_sock2.c
index b09e6e21..bee37c04 100644
--- a/freebsd/crypto/openssl/crypto/bio/b_sock2.c
+++ b/freebsd/crypto/openssl/crypto/bio/b_sock2.c
@@ -135,7 +135,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/freebsd/crypto/openssl/crypto/bio/bio_lib.c b/freebsd/crypto/openssl/crypto/bio/bio_lib.c
index a669714d..6a817c7c 100644
--- a/freebsd/crypto/openssl/crypto/bio/bio_lib.c
+++ b/freebsd/crypto/openssl/crypto/bio/bio_lib.c
@@ -54,7 +54,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;
@@ -62,7 +62,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/freebsd/crypto/openssl/crypto/bio/bss_log.c b/freebsd/crypto/openssl/crypto/bio/bss_log.c
index 66421e3d..9d162e5a 100644
--- a/freebsd/crypto/openssl/crypto/bio/bss_log.c
+++ b/freebsd/crypto/openssl/crypto/bio/bss_log.c
@@ -410,4 +410,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/freebsd/crypto/openssl/crypto/bn/bn_exp.c b/freebsd/crypto/openssl/crypto/bn/bn_exp.c
index 016d944a..7379621f 100644
--- a/freebsd/crypto/openssl/crypto/bn/bn_exp.c
+++ b/freebsd/crypto/openssl/crypto/bn/bn_exp.c
@@ -1079,7 +1079,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/freebsd/crypto/openssl/crypto/bn/bn_lib.c b/freebsd/crypto/openssl/crypto/bn/bn_lib.c
index 9d55124a..55215433 100644
--- a/freebsd/crypto/openssl/crypto/bn/bn_lib.c
+++ b/freebsd/crypto/openssl/crypto/bn/bn_lib.c
@@ -769,26 +769,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/freebsd/crypto/openssl/crypto/conf/conf_api.c b/freebsd/crypto/openssl/crypto/conf/conf_api.c
index ccb6a2d2..cdf01601 100644
--- a/freebsd/crypto/openssl/crypto/conf/conf_api.c
+++ b/freebsd/crypto/openssl/crypto/conf/conf_api.c
@@ -12,6 +12,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>
@@ -84,7 +85,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;
}
@@ -97,7 +98,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/freebsd/crypto/openssl/crypto/conf/conf_mod.c b/freebsd/crypto/openssl/crypto/conf/conf_mod.c
index 52fc9911..dd8ba390 100644
--- a/freebsd/crypto/openssl/crypto/conf/conf_mod.c
+++ b/freebsd/crypto/openssl/crypto/conf/conf_mod.c
@@ -494,11 +494,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/freebsd/crypto/openssl/crypto/cryptlib.c b/freebsd/crypto/openssl/crypto/cryptlib.c
index 1c2bf796..0262eb4a 100644
--- a/freebsd/crypto/openssl/crypto/cryptlib.c
+++ b/freebsd/crypto/openssl/crypto/cryptlib.c
@@ -206,7 +206,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/freebsd/crypto/openssl/crypto/ct/ct_log.c b/freebsd/crypto/openssl/crypto/ct/ct_log.c
index b234fc6b..0d40ca3b 100644
--- a/freebsd/crypto/openssl/crypto/ct/ct_log.c
+++ b/freebsd/crypto/openssl/crypto/ct/ct_log.c
@@ -139,7 +139,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/freebsd/crypto/openssl/crypto/dsa/dsa_gen.c b/freebsd/crypto/openssl/crypto/dsa/dsa_gen.c
index 739abcd8..84d18b3d 100644
--- a/freebsd/crypto/openssl/crypto/dsa/dsa_gen.c
+++ b/freebsd/crypto/openssl/crypto/dsa/dsa_gen.c
@@ -329,6 +329,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/freebsd/crypto/openssl/crypto/dsa/dsa_ossl.c b/freebsd/crypto/openssl/crypto/dsa/dsa_ossl.c
index c7e729d3..09d2c440 100644
--- a/freebsd/crypto/openssl/crypto/dsa/dsa_ossl.c
+++ b/freebsd/crypto/openssl/crypto/dsa/dsa_ossl.c
@@ -11,6 +11,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"
@@ -25,6 +26,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",
@@ -180,9 +183,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);
@@ -191,8 +194,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) {
@@ -203,9 +205,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 */
@@ -223,6 +225,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,
@@ -240,14 +243,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))
@@ -260,8 +266,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);
@@ -275,7 +281,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;
}
@@ -395,3 +400,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/freebsd/crypto/openssl/crypto/ec/ec_ameth.c b/freebsd/crypto/openssl/crypto/ec/ec_ameth.c
index a4ecf814..35e892e7 100644
--- a/freebsd/crypto/openssl/crypto/ec/ec_ameth.c
+++ b/freebsd/crypto/openssl/crypto/ec/ec_ameth.c
@@ -701,7 +701,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);
@@ -866,7 +866,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/freebsd/crypto/openssl/crypto/ec/ec_mult.c b/freebsd/crypto/openssl/crypto/ec/ec_mult.c
index afdb9fc5..5bfa3868 100644
--- a/freebsd/crypto/openssl/crypto/ec/ec_mult.c
+++ b/freebsd/crypto/openssl/crypto/ec/ec_mult.c
@@ -208,8 +208,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;
}
@@ -246,7 +246,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/freebsd/crypto/openssl/crypto/ec/ec_pmeth.c b/freebsd/crypto/openssl/crypto/ec/ec_pmeth.c
index c8d99316..41ca7813 100644
--- a/freebsd/crypto/openssl/crypto/ec/ec_pmeth.c
+++ b/freebsd/crypto/openssl/crypto/ec/ec_pmeth.c
@@ -211,7 +211,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;
@@ -283,7 +283,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/freebsd/crypto/openssl/crypto/ec/ecdh_kdf.c b/freebsd/crypto/openssl/crypto/ec/ecdh_kdf.c
index cb850803..9a176c68 100644
--- a/freebsd/crypto/openssl/crypto/ec/ecdh_kdf.c
+++ b/freebsd/crypto/openssl/crypto/ec/ecdh_kdf.c
@@ -1,7 +1,7 @@
#include <machine/rtems-bsd-user-space.h>
/*
- * 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
@@ -12,12 +12,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)
@@ -68,3 +69,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/freebsd/crypto/openssl/crypto/engine/eng_devcrypto.c b/freebsd/crypto/openssl/crypto/engine/eng_devcrypto.c
index 8e643ad3..ed24d478 100644
--- a/freebsd/crypto/openssl/crypto/engine/eng_devcrypto.c
+++ b/freebsd/crypto/openssl/crypto/engine/eng_devcrypto.c
@@ -26,10 +26,19 @@
#include "internal/engine.h"
+/* #define ENGINE_DEVCRYPTO_DEBUG */
+
#ifdef CRYPTO_ALGORITHM_MIN
# 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
@@ -41,7 +50,6 @@
*****/
struct cipher_ctx {
- int cfd;
struct session_op sess;
/* to pass from init to do_cipher */
@@ -71,7 +79,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 },
@@ -137,19 +145,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;
}
@@ -188,7 +190,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;
}
@@ -214,14 +216,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;
}
@@ -235,14 +233,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";
@@ -257,7 +251,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] =
@@ -283,8 +277,6 @@ static void prepare_cipher_methods()
cipher_data[i].nid;
}
}
-
- close(cfd);
}
static const EVP_CIPHER *get_cipher_method(int nid)
@@ -310,7 +302,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;
@@ -331,11 +323,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
/******************************************************************************
*
@@ -348,7 +341,6 @@ static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
*****/
struct digest_ctx {
- int cfd;
struct session_op sess;
int init;
};
@@ -415,19 +407,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;
}
@@ -446,7 +431,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)
@@ -474,7 +459,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;
}
@@ -482,16 +467,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;
}
@@ -504,14 +511,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));
@@ -524,7 +527,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,
@@ -534,6 +537,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))) {
@@ -543,8 +547,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)
@@ -570,7 +572,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;
@@ -600,9 +602,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;
}
/*
@@ -613,23 +618,33 @@ 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) {
+#ifndef ENGINE_DEVCRYPTO_DEBUG
+ if (errno != ENOENT)
+#endif
+ 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
@@ -666,7 +681,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/freebsd/crypto/openssl/crypto/engine/eng_list.c b/freebsd/crypto/openssl/crypto/engine/eng_list.c
index b38a826a..e3851cf5 100644
--- a/freebsd/crypto/openssl/crypto/engine/eng_list.c
+++ b/freebsd/crypto/openssl/crypto/engine/eng_list.c
@@ -322,8 +322,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/freebsd/crypto/openssl/crypto/evp/e_aes.c b/freebsd/crypto/openssl/crypto/evp/e_aes.c
index 7c2e780a..1c86559f 100644
--- a/freebsd/crypto/openssl/crypto/evp/e_aes.c
+++ b/freebsd/crypto/openssl/crypto/evp/e_aes.c
@@ -2243,7 +2243,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/freebsd/crypto/openssl/crypto/evp/e_rc2.c b/freebsd/crypto/openssl/crypto/evp/e_rc2.c
index 24f33206..769cf605 100644
--- a/freebsd/crypto/openssl/crypto/evp/e_rc2.c
+++ b/freebsd/crypto/openssl/crypto/evp/e_rc2.c
@@ -1,7 +1,7 @@
#include <machine/rtems-bsd-user-space.h>
/*
- * 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
@@ -94,7 +94,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)
@@ -138,8 +139,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/freebsd/crypto/openssl/crypto/evp/pmeth_lib.c b/freebsd/crypto/openssl/crypto/evp/pmeth_lib.c
index 50a2aff9..a2f40331 100644
--- a/freebsd/crypto/openssl/crypto/evp/pmeth_lib.c
+++ b/freebsd/crypto/openssl/crypto/evp/pmeth_lib.c
@@ -839,21 +839,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/freebsd/crypto/openssl/crypto/getenv.c b/freebsd/crypto/openssl/crypto/getenv.c
new file mode 100644
index 00000000..e653c714
--- /dev/null
+++ b/freebsd/crypto/openssl/crypto/getenv.c
@@ -0,0 +1,33 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * 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/freebsd/crypto/openssl/crypto/include/internal/ec_int.h b/freebsd/crypto/openssl/crypto/include/internal/ec_int.h
index bb4b5129..182c39cc 100644
--- a/freebsd/crypto/openssl/crypto/include/internal/ec_int.h
+++ b/freebsd/crypto/openssl/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/freebsd/crypto/openssl/crypto/include/internal/rand_int.h b/freebsd/crypto/openssl/crypto/include/internal/rand_int.h
index d91ee4c9..888cab1b 100644
--- a/freebsd/crypto/openssl/crypto/include/internal/rand_int.h
+++ b/freebsd/crypto/openssl/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/freebsd/crypto/openssl/crypto/kdf/hkdf.c b/freebsd/crypto/openssl/crypto/kdf/hkdf.c
index 4b452a8d..62788d90 100644
--- a/freebsd/crypto/openssl/crypto/kdf/hkdf.c
+++ b/freebsd/crypto/openssl/crypto/kdf/hkdf.c
@@ -177,6 +177,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)
{
@@ -238,7 +250,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/freebsd/crypto/openssl/crypto/mem_sec.c b/freebsd/crypto/openssl/crypto/mem_sec.c
index 7b2fc311..9d5b9975 100644
--- a/freebsd/crypto/openssl/crypto/mem_sec.c
+++ b/freebsd/crypto/openssl/crypto/mem_sec.c
@@ -22,12 +22,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>
@@ -53,7 +49,7 @@
# define MAP_ANON MAP_ANONYMOUS
#endif
-#ifdef IMPLEMENTED
+#ifdef OPENSSL_SECURE_MEMORY
static size_t secure_mem_used;
static int secure_mem_initialized;
@@ -73,7 +69,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) {
@@ -91,12 +87,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;
@@ -104,22 +100,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;
@@ -134,12 +130,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);
@@ -149,7 +145,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)
@@ -166,13 +162,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)
@@ -193,12 +189,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)
@@ -209,21 +205,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);
@@ -241,7 +237,7 @@ size_t CRYPTO_secure_actual_size(void *ptr)
/*
* SECURE HEAP IMPLEMENTATION
*/
-#ifdef IMPLEMENTED
+#ifdef OPENSSL_SECURE_MEMORY
/*
@@ -649,4 +645,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/freebsd/crypto/openssl/crypto/o_fopen.c b/freebsd/crypto/openssl/crypto/o_fopen.c
index 9d1e02a5..f9e4c82f 100644
--- a/freebsd/crypto/openssl/crypto/o_fopen.c
+++ b/freebsd/crypto/openssl/crypto/o_fopen.c
@@ -27,14 +27,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/freebsd/crypto/openssl/crypto/pkcs12/p12_mutl.c b/freebsd/crypto/openssl/crypto/pkcs12/p12_mutl.c
index 04084aa8..5a07e03e 100644
--- a/freebsd/crypto/openssl/crypto/pkcs12/p12_mutl.c
+++ b/freebsd/crypto/openssl/crypto/pkcs12/p12_mutl.c
@@ -9,13 +9,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)
{
@@ -46,7 +46,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,
@@ -114,7 +114,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/freebsd/crypto/openssl/crypto/rand/drbg_ctr.c b/freebsd/crypto/openssl/crypto/rand/drbg_ctr.c
index eac95a4e..5710875e 100644
--- a/freebsd/crypto/openssl/crypto/rand/drbg_ctr.c
+++ b/freebsd/crypto/openssl/crypto/rand/drbg_ctr.c
@@ -404,10 +404,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)
@@ -419,9 +419,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/freebsd/crypto/openssl/crypto/rand/drbg_lib.c b/freebsd/crypto/openssl/crypto/rand/drbg_lib.c
index 619b4406..86dd1166 100644
--- a/freebsd/crypto/openssl/crypto/rand/drbg_lib.c
+++ b/freebsd/crypto/openssl/crypto/rand/drbg_lib.c
@@ -84,6 +84,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,
@@ -107,16 +111,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:
@@ -125,8 +140,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;
}
@@ -149,7 +166,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;
}
@@ -226,11 +243,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;
}
@@ -255,6 +269,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);
@@ -314,11 +329,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;
}
@@ -339,29 +361,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;
@@ -377,6 +385,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;
@@ -421,13 +430,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;
}
@@ -436,16 +453,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)
@@ -477,10 +489,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) {
@@ -488,24 +502,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;
@@ -545,14 +560,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;
}
@@ -602,7 +611,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) {
@@ -611,8 +620,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;
}
@@ -631,7 +643,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;
}
@@ -649,9 +661,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;
@@ -663,9 +684,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;
}
@@ -684,7 +705,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;
@@ -861,7 +883,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.
@@ -950,11 +972,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;
@@ -962,20 +1022,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/freebsd/crypto/openssl/crypto/rand/rand_err.c b/freebsd/crypto/openssl/crypto/rand/rand_err.c
index 9fe58350..c8f2e67c 100644
--- a/freebsd/crypto/openssl/crypto/rand/rand_err.c
+++ b/freebsd/crypto/openssl/crypto/rand/rand_err.c
@@ -46,6 +46,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/freebsd/crypto/openssl/crypto/rand/rand_lcl.h b/freebsd/crypto/openssl/crypto/rand/rand_lcl.h
index 94ffc96f..c3e9804d 100644
--- a/freebsd/crypto/openssl/crypto/rand/rand_lcl.h
+++ b/freebsd/crypto/openssl/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/freebsd/crypto/openssl/crypto/rand/rand_lib.c b/freebsd/crypto/openssl/crypto/rand/rand_lib.c
index aeef669f..a6553d78 100644
--- a/freebsd/crypto/openssl/crypto/rand/rand_lib.c
+++ b/freebsd/crypto/openssl/crypto/rand/rand_lib.c
@@ -33,7 +33,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
/*
@@ -148,17 +148,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) {
@@ -180,6 +176,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);
@@ -208,7 +206,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;
}
@@ -219,7 +218,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);
}
@@ -281,14 +281,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;
@@ -297,14 +292,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)
@@ -328,13 +321,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;
@@ -350,7 +345,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();
@@ -364,6 +360,7 @@ void rand_cleanup_int(void)
rand_meth_lock = NULL;
CRYPTO_THREAD_lock_free(rand_nonce_lock);
rand_nonce_lock = NULL;
+ rand_inited = 0;
}
/*
@@ -372,7 +369,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);
}
/*
@@ -407,7 +405,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;
@@ -432,17 +430,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) {
@@ -450,7 +449,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;
@@ -460,6 +459,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)
@@ -467,7 +498,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);
}
@@ -498,15 +536,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
@@ -526,7 +576,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)
@@ -542,8 +592,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;
}
@@ -603,6 +653,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;
@@ -634,6 +689,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/freebsd/crypto/openssl/crypto/rand/rand_unix.c b/freebsd/crypto/openssl/crypto/rand/rand_unix.c
index 34d58ea3..7a93ceb4 100644
--- a/freebsd/crypto/openssl/crypto/rand/rand_unix.c
+++ b/freebsd/crypto/openssl/crypto/rand/rand_unix.c
@@ -79,6 +79,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"
@@ -88,8 +99,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
@@ -246,6 +255,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.
@@ -256,7 +266,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.
@@ -304,8 +314,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;
@@ -377,21 +388,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;
}
@@ -405,16 +408,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)
{
@@ -429,9 +429,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.
@@ -452,14 +450,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 */
@@ -489,7 +487,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;
@@ -526,19 +524,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 };
@@ -579,7 +577,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/freebsd/crypto/openssl/crypto/rand/randfile.c b/freebsd/crypto/openssl/crypto/rand/randfile.c
index 3f401f8f..de3c15dc 100644
--- a/freebsd/crypto/openssl/crypto/rand/randfile.c
+++ b/freebsd/crypto/openssl/crypto/rand/randfile.c
@@ -18,6 +18,7 @@
#include <openssl/crypto.h>
#include <openssl/rand.h>
+#include <openssl/rand_drbg.h>
#include <openssl/buffer.h>
#ifdef OPENSSL_SYS_VMS
@@ -50,7 +51,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
@@ -76,7 +77,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
@@ -100,8 +110,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
@@ -126,9 +140,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){
@@ -150,12 +164,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
@@ -224,9 +244,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;
}
@@ -264,11 +284,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/freebsd/crypto/openssl/crypto/rsa/rsa_lib.c b/freebsd/crypto/openssl/crypto/rsa/rsa_lib.c
index e1c1ac47..c0edd05e 100644
--- a/freebsd/crypto/openssl/crypto/rsa/rsa_lib.c
+++ b/freebsd/crypto/openssl/crypto/rsa/rsa_lib.c
@@ -127,8 +127,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);
@@ -198,7 +198,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;
}
@@ -215,11 +215,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;
}
@@ -237,15 +237,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/freebsd/crypto/openssl/crypto/rsa/rsa_meth.c b/freebsd/crypto/openssl/crypto/rsa/rsa_meth.c
index 928d86c9..1196728b 100644
--- a/freebsd/crypto/openssl/crypto/rsa/rsa_meth.c
+++ b/freebsd/crypto/openssl/crypto/rsa/rsa_meth.c
@@ -165,13 +165,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/freebsd/crypto/openssl/crypto/rsa/rsa_ossl.c b/freebsd/crypto/openssl/crypto/rsa/rsa_ossl.c
index 05ee159f..43fc5a6c 100644
--- a/freebsd/crypto/openssl/crypto/rsa/rsa_ossl.c
+++ b/freebsd/crypto/openssl/crypto/rsa/rsa_ossl.c
@@ -682,10 +682,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/freebsd/crypto/openssl/crypto/siphash/siphash.c b/freebsd/crypto/openssl/crypto/siphash/siphash.c
index 66665b1b..38c60137 100644
--- a/freebsd/crypto/openssl/crypto/siphash/siphash.c
+++ b/freebsd/crypto/openssl/crypto/siphash/siphash.c
@@ -96,7 +96,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/freebsd/crypto/openssl/crypto/sm2/sm2_crypt.c b/freebsd/crypto/openssl/crypto/sm2/sm2_crypt.c
index 094e7dd2..56af9cf5 100644
--- a/freebsd/crypto/openssl/crypto/sm2/sm2_crypt.c
+++ b/freebsd/crypto/openssl/crypto/sm2/sm2_crypt.c
@@ -13,6 +13,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>
@@ -205,7 +206,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;
@@ -346,7 +347,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/freebsd/crypto/openssl/crypto/sm2/sm2_sign.c b/freebsd/crypto/openssl/crypto/sm2/sm2_sign.c
index 10db5bc1..1f912dba 100644
--- a/freebsd/crypto/openssl/crypto/sm2/sm2_sign.c
+++ b/freebsd/crypto/openssl/crypto/sm2/sm2_sign.c
@@ -14,6 +14,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/freebsd/crypto/openssl/crypto/ui/ui_openssl.c b/freebsd/crypto/openssl/crypto/ui/ui_openssl.c
index 9c3875a0..3d07aff7 100644
--- a/freebsd/crypto/openssl/crypto/ui/ui_openssl.c
+++ b/freebsd/crypto/openssl/crypto/ui/ui_openssl.c
@@ -417,6 +417,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/freebsd/crypto/openssl/crypto/x509/by_dir.c b/freebsd/crypto/openssl/crypto/x509/by_dir.c
index 4ca30064..e05e72ae 100644
--- a/freebsd/crypto/openssl/crypto/x509/by_dir.c
+++ b/freebsd/crypto/openssl/crypto/x509/by_dir.c
@@ -75,7 +75,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/freebsd/crypto/openssl/crypto/x509/by_file.c b/freebsd/crypto/openssl/crypto/x509/by_file.c
index 8ebdeecd..66ec85e5 100644
--- a/freebsd/crypto/openssl/crypto/x509/by_file.c
+++ b/freebsd/crypto/openssl/crypto/x509/by_file.c
@@ -48,7 +48,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/freebsd/crypto/openssl/crypto/x509/x509_vfy.c b/freebsd/crypto/openssl/crypto/x509/x509_vfy.c
index ca6022f8..00b33f3e 100644
--- a/freebsd/crypto/openssl/crypto/x509/x509_vfy.c
+++ b/freebsd/crypto/openssl/crypto/x509/x509_vfy.c
@@ -519,15 +519,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
diff --git a/freebsd/crypto/openssl/e_os.h b/freebsd/crypto/openssl/e_os.h
index 5769029b..53405938 100644
--- a/freebsd/crypto/openssl/e_os.h
+++ b/freebsd/crypto/openssl/e_os.h
@@ -245,7 +245,7 @@ extern FILE *_imp___iob;
Finally, we add the VMS C facility code 0x35a000, because there are some
programs, such as Perl, that will reinterpret the code back to something
- POSIXly. 'man perlvms' explains it further.
+ POSIX. 'man perlvms' explains it further.
NOTE: the perlvms manual wants to turn all codes 2 to 255 into success
codes (status type = 1). I couldn't disagree more. Fortunately, the
@@ -317,8 +317,15 @@ struct servent *getservbyname(const char *name, const char *proto);
# endif
/* end vxworks */
-#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
-# define CRYPTO_memcmp memcmp
-#endif
+# ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+# define CRYPTO_memcmp memcmp
+# endif
+/* unistd.h 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 OPENSSL_SECURE_MEMORY /* secure memory is implemented */
+# endif
#endif
diff --git a/freebsd/crypto/openssl/include/internal/cryptlib.h b/freebsd/crypto/openssl/include/internal/cryptlib.h
index a6087351..329ef620 100644
--- a/freebsd/crypto/openssl/include/internal/cryptlib.h
+++ b/freebsd/crypto/openssl/include/internal/cryptlib.h
@@ -81,6 +81,8 @@ void OPENSSL_showfatal(const char *fmta, ...);
void crypto_cleanup_all_ex_data_int(void);
int openssl_init_fork_handlers(void);
+char *ossl_safe_getenv(const char *name);
+
extern CRYPTO_RWLOCK *memdbg_lock;
int openssl_strerror_r(int errnum, char *buf, size_t buflen);
# if !defined(OPENSSL_NO_STDIO)
diff --git a/freebsd/crypto/openssl/include/internal/tsan_assist.h b/freebsd/crypto/openssl/include/internal/tsan_assist.h
index 2c763834..f30ffe39 100644
--- a/freebsd/crypto/openssl/include/internal/tsan_assist.h
+++ b/freebsd/crypto/openssl/include/internal/tsan_assist.h
@@ -57,6 +57,7 @@
# define tsan_load(ptr) atomic_load_explicit((ptr), memory_order_relaxed)
# define tsan_store(ptr, val) atomic_store_explicit((ptr), (val), memory_order_relaxed)
# define tsan_counter(ptr) atomic_fetch_add_explicit((ptr), 1, memory_order_relaxed)
+# define tsan_decr(ptr) atomic_fetch_add_explicit((ptr), -1, memory_order_relaxed)
# define tsan_ld_acq(ptr) atomic_load_explicit((ptr), memory_order_acquire)
# define tsan_st_rel(ptr, val) atomic_store_explicit((ptr), (val), memory_order_release)
# endif
@@ -69,6 +70,7 @@
# define tsan_load(ptr) __atomic_load_n((ptr), __ATOMIC_RELAXED)
# define tsan_store(ptr, val) __atomic_store_n((ptr), (val), __ATOMIC_RELAXED)
# define tsan_counter(ptr) __atomic_fetch_add((ptr), 1, __ATOMIC_RELAXED)
+# define tsan_decr(ptr) __atomic_fetch_add((ptr), -1, __ATOMIC_RELAXED)
# define tsan_ld_acq(ptr) __atomic_load_n((ptr), __ATOMIC_ACQUIRE)
# define tsan_st_rel(ptr, val) __atomic_store_n((ptr), (val), __ATOMIC_RELEASE)
# endif
@@ -113,8 +115,11 @@
# pragma intrinsic(_InterlockedExchangeAdd64)
# define tsan_counter(ptr) (sizeof(*(ptr)) == 8 ? _InterlockedExchangeAdd64((ptr), 1) \
: _InterlockedExchangeAdd((ptr), 1))
+# define tsan_decr(ptr) (sizeof(*(ptr)) == 8 ? _InterlockedExchangeAdd64((ptr), -1) \
+ : _InterlockedExchangeAdd((ptr), -1))
# else
# define tsan_counter(ptr) _InterlockedExchangeAdd((ptr), 1)
+# define tsan_decr(ptr) _InterlockedExchangeAdd((ptr), -1)
# endif
# if !defined(_ISO_VOLATILE)
# define tsan_ld_acq(ptr) (*(ptr))
@@ -129,6 +134,7 @@
# define tsan_load(ptr) (*(ptr))
# define tsan_store(ptr, val) (*(ptr) = (val))
# define tsan_counter(ptr) ((*(ptr))++)
+# define tsan_decr(ptr) ((*(ptr))--)
/*
* Lack of tsan_ld_acq and tsan_ld_rel means that compiler support is not
* sophisticated enough to support them. Code that relies on them should be
diff --git a/freebsd/crypto/openssl/include/openssl/cryptoerr.h b/freebsd/crypto/openssl/include/openssl/cryptoerr.h
index e127ff60..10723d04 100644
--- a/freebsd/crypto/openssl/include/openssl/cryptoerr.h
+++ b/freebsd/crypto/openssl/include/openssl/cryptoerr.h
@@ -14,6 +14,9 @@
# ifdef __cplusplus
extern "C"
# endif
+
+# include <openssl/symhacks.h>
+
int ERR_load_CRYPTO_strings(void);
/*
diff --git a/freebsd/crypto/openssl/include/openssl/ec.h b/freebsd/crypto/openssl/include/openssl/ec.h
index 4d70da70..347cfb6d 100644
--- a/freebsd/crypto/openssl/include/openssl/ec.h
+++ b/freebsd/crypto/openssl/include/openssl/ec.h
@@ -1107,6 +1107,11 @@ const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key);
int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth);
EC_KEY *EC_KEY_new_method(ENGINE *engine);
+/** The old name for ecdh_KDF_X9_63
+ * The ECDH KDF specification has been mistakingly attributed to ANSI X9.62,
+ * it is actually specified in ANSI X9.63.
+ * This identifier is retained for backwards 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,
@@ -1457,7 +1462,13 @@ void EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth,
# define EVP_PKEY_CTRL_GET1_ID_LEN (EVP_PKEY_ALG_CTRL + 13)
/* KDF types */
# define EVP_PKEY_ECDH_KDF_NONE 1
-# define EVP_PKEY_ECDH_KDF_X9_62 2
+# define EVP_PKEY_ECDH_KDF_X9_63 2
+/** The old name for EVP_PKEY_ECDH_KDF_X9_63
+ * The ECDH KDF specification has been mistakingly attributed to ANSI X9.62,
+ * it is actually specified in ANSI X9.63.
+ * This identifier is retained for backwards compatibility
+ */
+# define EVP_PKEY_ECDH_KDF_X9_62 EVP_PKEY_ECDH_KDF_X9_63
# ifdef __cplusplus
diff --git a/freebsd/crypto/openssl/include/openssl/ocsp.h b/freebsd/crypto/openssl/include/openssl/ocsp.h
index 937b3227..0a17166b 100644
--- a/freebsd/crypto/openssl/include/openssl/ocsp.h
+++ b/freebsd/crypto/openssl/include/openssl/ocsp.h
@@ -93,7 +93,6 @@ typedef struct ocsp_resp_bytes_st OCSP_RESPBYTES;
# define V_OCSP_RESPID_KEY 1
DEFINE_STACK_OF(OCSP_RESPID)
-DECLARE_ASN1_FUNCTIONS(OCSP_RESPID)
typedef struct ocsp_revoked_info_st OCSP_REVOKEDINFO;
@@ -162,8 +161,6 @@ int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it,
int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx, ASN1_VALUE **pval,
const ASN1_ITEM *it);
BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx);
-int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it,
- ASN1_VALUE *val);
int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path);
int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req);
int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx,
diff --git a/freebsd/crypto/openssl/include/openssl/opensslv.h b/freebsd/crypto/openssl/include/openssl/opensslv.h
index 363359d9..e8790316 100644
--- a/freebsd/crypto/openssl/include/openssl/opensslv.h
+++ b/freebsd/crypto/openssl/include/openssl/opensslv.h
@@ -39,8 +39,8 @@ extern "C" {
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
* major minor fix final patch/beta)
*/
-# define OPENSSL_VERSION_NUMBER 0x1010100fL
-# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1-freebsd 11 Sep 2018"
+# define OPENSSL_VERSION_NUMBER 0x1010101fL
+# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1a-freebsd 20 Nov 2018"
/*-
* The macros below are to be used for shared library (.so, .dll, ...)
diff --git a/freebsd/crypto/openssl/include/openssl/rand_drbg.h b/freebsd/crypto/openssl/include/openssl/rand_drbg.h
index 282356e1..45b731b7 100644
--- a/freebsd/crypto/openssl/include/openssl/rand_drbg.h
+++ b/freebsd/crypto/openssl/include/openssl/rand_drbg.h
@@ -12,23 +12,31 @@
# include <time.h>
# include <openssl/ossl_typ.h>
+# include <openssl/obj_mac.h>
+/*
+ * RAND_DRBG flags
+ *
+ * Note: if new flags are added, the constant `rand_drbg_used_flags`
+ * in drbg_lib.c needs to be updated accordingly.
+ */
/* In CTR mode, disable derivation function ctr_df */
# define RAND_DRBG_FLAG_CTR_NO_DF 0x1
-/* A logical OR of all used flag bits (currently there is only one) */
-# define RAND_DRBG_USED_FLAGS ( \
- RAND_DRBG_FLAG_CTR_NO_DF \
- )
+
+# if OPENSSL_API_COMPAT < 0x10200000L
+/* This #define was replaced by an internal constant and should not be used. */
+# define RAND_DRBG_USED_FLAGS (RAND_DRBG_FLAG_CTR_NO_DF)
+# endif
/*
* Default security strength (in the sense of [NIST SP 800-90Ar1])
*
* NIST SP 800-90Ar1 supports the strength of the DRBG being smaller than that
- * of the cipher by collecting less entropy. The current DRBG implemantion does
- * not take RAND_DRBG_STRENGTH into account and sets the strength of the DRBG
- * to that of the cipher.
+ * of the cipher by collecting less entropy. The current DRBG implementation
+ * does not take RAND_DRBG_STRENGTH into account and sets the strength of the
+ * DRBG to that of the cipher.
*
* RAND_DRBG_STRENGTH is currently only used for the legacy RAND
* implementation.
@@ -37,7 +45,9 @@
* NID_aes_256_ctr
*/
# define RAND_DRBG_STRENGTH 256
+/* Default drbg type */
# define RAND_DRBG_TYPE NID_aes_256_ctr
+/* Default drbg flags */
# define RAND_DRBG_FLAGS 0
diff --git a/freebsd/crypto/openssl/include/openssl/randerr.h b/freebsd/crypto/openssl/include/openssl/randerr.h
index 128f4dea..599a2a18 100644
--- a/freebsd/crypto/openssl/include/openssl/randerr.h
+++ b/freebsd/crypto/openssl/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/freebsd/crypto/openssl/include/openssl/rsa.h b/freebsd/crypto/openssl/include/openssl/rsa.h
index a611b6a0..cdce1264 100644
--- a/freebsd/crypto/openssl/include/openssl/rsa.h
+++ b/freebsd/crypto/openssl/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)
@@ -456,9 +456,9 @@ int RSA_meth_set_priv_dec(RSA_METHOD *rsa,
unsigned char *to, RSA *rsa,
int padding));
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);
int RSA_meth_set_mod_exp(RSA_METHOD *rsa,
- int (*mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa,
+ int (*mod_exp) (BIGNUM *r0, const BIGNUM *i, RSA *rsa,
BN_CTX *ctx));
int (*RSA_meth_get_bn_mod_exp(const RSA_METHOD *meth))
(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
diff --git a/freebsd/crypto/openssl/include/openssl/ssl.h b/freebsd/crypto/openssl/include/openssl/ssl.h
index 0a18a435..d6b1b4e6 100644
--- a/freebsd/crypto/openssl/include/openssl/ssl.h
+++ b/freebsd/crypto/openssl/include/openssl/ssl.h
@@ -1271,7 +1271,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
# define SSL_CTRL_SET_VERIFY_CERT_STORE 106
# define SSL_CTRL_SET_CHAIN_CERT_STORE 107
# define SSL_CTRL_GET_PEER_SIGNATURE_NID 108
-# define SSL_CTRL_GET_SERVER_TMP_KEY 109
+# define SSL_CTRL_GET_PEER_TMP_KEY 109
# define SSL_CTRL_GET_RAW_CIPHERLIST 110
# define SSL_CTRL_GET_EC_POINT_FORMATS 111
# define SSL_CTRL_GET_CHAIN_CERTS 115
@@ -1290,6 +1290,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG 129
# define SSL_CTRL_GET_MIN_PROTO_VERSION 130
# define SSL_CTRL_GET_MAX_PROTO_VERSION 131
+# define SSL_CTRL_GET_SIGNATURE_NID 132
+# define SSL_CTRL_GET_TMP_KEY 133
# define SSL_CERT_SET_FIRST 1
# define SSL_CERT_SET_NEXT 2
# define SSL_CERT_SET_SERVER 3
@@ -1410,10 +1412,14 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
(char *)(clist))
# define SSL_set1_client_certificate_types(s, clist, clistlen) \
SSL_ctrl(s,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen,(char *)(clist))
+# define SSL_get_signature_nid(s, pn) \
+ SSL_ctrl(s,SSL_CTRL_GET_SIGNATURE_NID,0,pn)
# define SSL_get_peer_signature_nid(s, pn) \
SSL_ctrl(s,SSL_CTRL_GET_PEER_SIGNATURE_NID,0,pn)
-# define SSL_get_server_tmp_key(s, pk) \
- SSL_ctrl(s,SSL_CTRL_GET_SERVER_TMP_KEY,0,pk)
+# define SSL_get_peer_tmp_key(s, pk) \
+ SSL_ctrl(s,SSL_CTRL_GET_PEER_TMP_KEY,0,pk)
+# define SSL_get_tmp_key(s, pk) \
+ SSL_ctrl(s,SSL_CTRL_GET_TMP_KEY,0,pk)
# define SSL_get0_raw_cipherlist(s, plst) \
SSL_ctrl(s,SSL_CTRL_GET_RAW_CIPHERLIST,0,plst)
# define SSL_get0_ec_point_formats(s, plst) \
@@ -1435,6 +1441,12 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
# define SSL_get_max_proto_version(s) \
SSL_ctrl(s, SSL_CTRL_GET_MAX_PROTO_VERSION, 0, NULL)
+/* Backwards compatibility, original 1.1.0 names */
+# define SSL_CTRL_GET_SERVER_TMP_KEY \
+ SSL_CTRL_GET_PEER_TMP_KEY
+# define SSL_get_server_tmp_key(s, pk) \
+ SSL_get_peer_tmp_key(s, pk)
+
/*
* The following symbol names are old and obsolete. They are kept
* for compatibility reasons only and should not be used anymore.
diff --git a/freebsd/crypto/openssl/include/openssl/symhacks.h b/freebsd/crypto/openssl/include/openssl/symhacks.h
index caf1f1a7..156ea6e4 100644
--- a/freebsd/crypto/openssl/include/openssl/symhacks.h
+++ b/freebsd/crypto/openssl/include/openssl/symhacks.h
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-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
@@ -28,21 +28,6 @@
# undef i2d_ECPKPARAMETERS
# define i2d_ECPKPARAMETERS i2d_UC_ECPKPARAMETERS
-/*
- * These functions do not seem to exist! However, I'm paranoid... Original
- * command in x509v3.h: These functions are being redefined in another
- * directory, and clash when the linker is case-insensitive, so let's hide
- * them a little, by giving them an extra 'o' at the beginning of the name...
- */
-# undef X509v3_cleanup_extensions
-# define X509v3_cleanup_extensions oX509v3_cleanup_extensions
-# undef X509v3_add_extension
-# define X509v3_add_extension oX509v3_add_extension
-# undef X509v3_add_netscape_extensions
-# define X509v3_add_netscape_extensions oX509v3_add_netscape_extensions
-# undef X509v3_add_standard_extensions
-# define X509v3_add_standard_extensions oX509v3_add_standard_extensions
-
/* This one clashes with CMS_data_create */
# undef cms_Data_create
# define cms_Data_create priv_cms_Data_create
diff --git a/freebsd/crypto/openssl/include/openssl/tls1.h b/freebsd/crypto/openssl/include/openssl/tls1.h
index 2e46cf80..e13b5dd4 100644
--- a/freebsd/crypto/openssl/include/openssl/tls1.h
+++ b/freebsd/crypto/openssl/include/openssl/tls1.h
@@ -241,6 +241,7 @@ __owur int SSL_export_keying_material_early(SSL *s, unsigned char *out,
size_t contextlen);
int SSL_get_peer_signature_type_nid(const SSL *s, int *pnid);
+int SSL_get_signature_type_nid(const SSL *s, int *pnid);
int SSL_get_sigalgs(SSL *s, int idx,
int *psign, int *phash, int *psignandhash,
diff --git a/freebsd/crypto/openssl/ssl/d1_lib.c b/freebsd/crypto/openssl/ssl/d1_lib.c
index 749bf40a..ed89a484 100644
--- a/freebsd/crypto/openssl/ssl/d1_lib.c
+++ b/freebsd/crypto/openssl/ssl/d1_lib.c
@@ -1,7 +1,7 @@
#include <machine/rtems-bsd-user-space.h>
/*
- * Copyright 2005-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2005-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
@@ -447,15 +447,14 @@ static void get_current_time(struct timeval *t)
#ifndef OPENSSL_NO_SOCK
int DTLSv1_listen(SSL *s, BIO_ADDR *client)
{
- int next, n, ret = 0, clearpkt = 0;
+ int next, n, ret = 0;
unsigned char cookie[DTLS1_COOKIE_LENGTH];
unsigned char seq[SEQ_NUM_SIZE];
const unsigned char *data;
- unsigned char *buf;
- size_t fragoff, fraglen, msglen;
+ unsigned char *buf, *wbuf;
+ size_t fragoff, fraglen, msglen, reclen, align = 0;
unsigned int rectype, versmajor, msgseq, msgtype, clientvers, cookielen;
BIO *rbio, *wbio;
- BUF_MEM *bufm;
BIO_ADDR *tmpclient = NULL;
PACKET pkt, msgpkt, msgpayload, session, cookiepkt;
@@ -479,13 +478,6 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
}
/*
- * We only peek at incoming ClientHello's until we're sure we are going to
- * to respond with a HelloVerifyRequest. If its a ClientHello with a valid
- * cookie then we leave it in the BIO for accept to handle.
- */
- BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 1, NULL);
-
- /*
* Note: This check deliberately excludes DTLS1_BAD_VER because that version
* requires the MAC to be calculated *including* the first ClientHello
* (without the cookie). Since DTLSv1_listen is stateless that cannot be
@@ -497,35 +489,32 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
return -1;
}
- if (s->init_buf == NULL) {
- if ((bufm = BUF_MEM_new()) == NULL) {
- SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_MALLOC_FAILURE);
- return -1;
- }
-
- if (!BUF_MEM_grow(bufm, SSL3_RT_MAX_PLAIN_LENGTH)) {
- BUF_MEM_free(bufm);
- SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_MALLOC_FAILURE);
- return -1;
- }
- s->init_buf = bufm;
+ if (!ssl3_setup_buffers(s)) {
+ /* SSLerr already called */
+ return -1;
}
- buf = (unsigned char *)s->init_buf->data;
+ buf = RECORD_LAYER_get_rbuf(&s->rlayer)->buf;
+ wbuf = RECORD_LAYER_get_wbuf(&s->rlayer)[0].buf;
+#if defined(SSL3_ALIGN_PAYLOAD)
+# if SSL3_ALIGN_PAYLOAD != 0
+ /*
+ * Using SSL3_RT_HEADER_LENGTH here instead of DTLS1_RT_HEADER_LENGTH for
+ * consistency with ssl3_read_n. In practice it should make no difference
+ * for sensible values of SSL3_ALIGN_PAYLOAD because the difference between
+ * SSL3_RT_HEADER_LENGTH and DTLS1_RT_HEADER_LENGTH is exactly 8
+ */
+ align = (size_t)buf + SSL3_RT_HEADER_LENGTH;
+ align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD);
+# endif
+#endif
+ buf += align;
do {
/* Get a packet */
clear_sys_error();
- /*
- * Technically a ClientHello could be SSL3_RT_MAX_PLAIN_LENGTH
- * + DTLS1_RT_HEADER_LENGTH bytes long. Normally init_buf does not store
- * the record header as well, but we do here. We've set up init_buf to
- * be the standard size for simplicity. In practice we shouldn't ever
- * receive a ClientHello as long as this. If we do it will get dropped
- * in the record length check below.
- */
- n = BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH);
-
+ n = BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH
+ + DTLS1_RT_HEADER_LENGTH);
if (n <= 0) {
if (BIO_should_retry(rbio)) {
/* Non-blocking IO */
@@ -534,9 +523,6 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
return -1;
}
- /* If we hit any problems we need to clear this packet from the BIO */
- clearpkt = 1;
-
if (!PACKET_buf_init(&pkt, buf, n)) {
SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_INTERNAL_ERROR);
return -1;
@@ -589,6 +575,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH);
goto end;
}
+ reclen = PACKET_remaining(&msgpkt);
/*
* We allow data remaining at the end of the packet because there could
* be a second record (but we ignore it)
@@ -708,14 +695,6 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
* to resend, we just drop it.
*/
- /*
- * Dump the read packet, we don't need it any more. Ignore return
- * value
- */
- BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 0, NULL);
- BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH);
- BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 1, NULL);
-
/* Generate the cookie */
if (s->ctx->app_gen_cookie_cb == NULL ||
s->ctx->app_gen_cookie_cb(s, cookie, &cookielen) == 0 ||
@@ -734,7 +713,11 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
: s->version;
/* Construct the record and message headers */
- if (!WPACKET_init(&wpkt, s->init_buf)
+ if (!WPACKET_init_static_len(&wpkt,
+ wbuf,
+ ssl_get_max_send_fragment(s)
+ + DTLS1_RT_HEADER_LENGTH,
+ 0)
|| !WPACKET_put_bytes_u8(&wpkt, SSL3_RT_HANDSHAKE)
|| !WPACKET_put_bytes_u16(&wpkt, version)
/*
@@ -792,8 +775,8 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
* plus one byte for the message content type. The source is the
* last 3 bytes of the message header
*/
- memcpy(&buf[DTLS1_RT_HEADER_LENGTH + 1],
- &buf[DTLS1_RT_HEADER_LENGTH + DTLS1_HM_HEADER_LENGTH - 3],
+ memcpy(&wbuf[DTLS1_RT_HEADER_LENGTH + 1],
+ &wbuf[DTLS1_RT_HEADER_LENGTH + DTLS1_HM_HEADER_LENGTH - 3],
3);
if (s->msg_callback)
@@ -817,7 +800,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
tmpclient = NULL;
/* TODO(size_t): convert this call */
- if (BIO_write(wbio, buf, wreclen) < (int)wreclen) {
+ if (BIO_write(wbio, wbuf, wreclen) < (int)wreclen) {
if (BIO_should_retry(wbio)) {
/*
* Non-blocking IO...but we're stateless, so we're just
@@ -867,15 +850,13 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
if (BIO_dgram_get_peer(rbio, client) <= 0)
BIO_ADDR_clear(client);
+ /* Buffer the record in the processed_rcds queue */
+ if (!dtls_buffer_listen_record(s, reclen, seq, align))
+ return -1;
+
ret = 1;
- clearpkt = 0;
end:
BIO_ADDR_free(tmpclient);
- BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 0, NULL);
- if (clearpkt) {
- /* Dump this packet. Ignore return value */
- BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH);
- }
return ret;
}
#endif
diff --git a/freebsd/crypto/openssl/ssl/record/rec_layer_d1.c b/freebsd/crypto/openssl/ssl/record/rec_layer_d1.c
index b147229e..ff3d01aa 100644
--- a/freebsd/crypto/openssl/ssl/record/rec_layer_d1.c
+++ b/freebsd/crypto/openssl/ssl/record/rec_layer_d1.c
@@ -187,14 +187,11 @@ int dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
return -1;
}
- /* insert should not fail, since duplicates are dropped */
if (pqueue_insert(queue->q, item) == NULL) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DTLS1_BUFFER_RECORD,
- ERR_R_INTERNAL_ERROR);
+ /* Must be a duplicate so ignore it */
OPENSSL_free(rdata->rbuf.buf);
OPENSSL_free(rdata);
pitem_free(item);
- return -1;
}
return 1;
diff --git a/freebsd/crypto/openssl/ssl/record/record.h b/freebsd/crypto/openssl/ssl/record/record.h
index 32db8212..af56206e 100644
--- a/freebsd/crypto/openssl/ssl/record/record.h
+++ b/freebsd/crypto/openssl/ssl/record/record.h
@@ -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
@@ -188,6 +188,8 @@ typedef struct record_layer_st {
((rl)->d->processed_rcds)
#define DTLS_RECORD_LAYER_get_unprocessed_rcds(rl) \
((rl)->d->unprocessed_rcds)
+#define RECORD_LAYER_get_rbuf(rl) (&(rl)->rbuf)
+#define RECORD_LAYER_get_wbuf(rl) ((rl)->wbuf)
void RECORD_LAYER_init(RECORD_LAYER *rl, SSL *s);
void RECORD_LAYER_clear(RECORD_LAYER *rl);
@@ -230,3 +232,5 @@ __owur int dtls1_write_bytes(SSL *s, int type, const void *buf, size_t len,
int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
size_t len, int create_empty_fragment, size_t *written);
void dtls1_reset_seq_numbers(SSL *s, int rw);
+int dtls_buffer_listen_record(SSL *s, size_t len, unsigned char *seq,
+ size_t off);
diff --git a/freebsd/crypto/openssl/ssl/record/record_locl.h b/freebsd/crypto/openssl/ssl/record/record_locl.h
index 07fd7ab6..5e8dd7f7 100644
--- a/freebsd/crypto/openssl/ssl/record/record_locl.h
+++ b/freebsd/crypto/openssl/ssl/record/record_locl.h
@@ -18,8 +18,6 @@
/* Functions/macros provided by the RECORD_LAYER component */
-#define RECORD_LAYER_get_rbuf(rl) (&(rl)->rbuf)
-#define RECORD_LAYER_get_wbuf(rl) ((rl)->wbuf)
#define RECORD_LAYER_get_rrec(rl) ((rl)->rrec)
#define RECORD_LAYER_set_packet(rl, p) ((rl)->packet = (p))
#define RECORD_LAYER_reset_packet_length(rl) ((rl)->packet_length = 0)
diff --git a/freebsd/crypto/openssl/ssl/record/ssl3_record.c b/freebsd/crypto/openssl/ssl/record/ssl3_record.c
index d7e47474..781167f9 100644
--- a/freebsd/crypto/openssl/ssl/record/ssl3_record.c
+++ b/freebsd/crypto/openssl/ssl/record/ssl3_record.c
@@ -2032,3 +2032,28 @@ int dtls1_get_record(SSL *s)
return 1;
}
+
+int dtls_buffer_listen_record(SSL *s, size_t len, unsigned char *seq, size_t off)
+{
+ SSL3_RECORD *rr;
+
+ rr = RECORD_LAYER_get_rrec(&s->rlayer);
+ memset(rr, 0, sizeof(SSL3_RECORD));
+
+ rr->length = len;
+ rr->type = SSL3_RT_HANDSHAKE;
+ memcpy(rr->seq_num, seq, sizeof(rr->seq_num));
+ rr->off = off;
+
+ s->rlayer.packet = RECORD_LAYER_get_rbuf(&s->rlayer)->buf;
+ s->rlayer.packet_length = DTLS1_RT_HEADER_LENGTH + len;
+ rr->data = s->rlayer.packet + DTLS1_RT_HEADER_LENGTH;
+
+ if (dtls1_buffer_record(s, &(s->rlayer.d->processed_rcds),
+ SSL3_RECORD_get_seq_num(s->rlayer.rrec)) <= 0) {
+ /* SSLfatal() already called */
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/freebsd/crypto/openssl/ssl/s3_cbc.c b/freebsd/crypto/openssl/ssl/s3_cbc.c
index 4774ab51..4cc7ab1f 100644
--- a/freebsd/crypto/openssl/ssl/s3_cbc.c
+++ b/freebsd/crypto/openssl/ssl/s3_cbc.c
@@ -1,7 +1,7 @@
#include <machine/rtems-bsd-user-space.h>
/*
- * Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2012-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
@@ -258,12 +258,13 @@ int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
* of hash termination (0x80 + 64-bit length) don't fit in the final
* block, we say that the final two blocks can vary based on the padding.
* TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not
- * required to be minimal. Therefore we say that the final six blocks can
+ * required to be minimal. Therefore we say that the final |variance_blocks|
+ * blocks can
* vary based on the padding. Later in the function, if the message is
* short and there obviously cannot be this many blocks then
* variance_blocks can be reduced.
*/
- variance_blocks = is_sslv3 ? 2 : 6;
+ variance_blocks = is_sslv3 ? 2 : ( ((255 + 1 + md_size + md_block_size - 1) / md_block_size) + 1);
/*
* From now on we're dealing with the MAC, which conceptually has 13
* bytes of `header' before the start of the data (TLS) or 71/75 bytes
diff --git a/freebsd/crypto/openssl/ssl/s3_enc.c b/freebsd/crypto/openssl/ssl/s3_enc.c
index fb8cd81d..baaec955 100644
--- a/freebsd/crypto/openssl/ssl/s3_enc.c
+++ b/freebsd/crypto/openssl/ssl/s3_enc.c
@@ -444,15 +444,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)
@@ -465,6 +466,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/freebsd/crypto/openssl/ssl/s3_lib.c b/freebsd/crypto/openssl/ssl/s3_lib.c
index 57680ac2..e1a10f0e 100644
--- a/freebsd/crypto/openssl/ssl/s3_lib.c
+++ b/freebsd/crypto/openssl/ssl/s3_lib.c
@@ -3683,9 +3683,15 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
*(int *)parg = s->s3->tmp.peer_sigalg->hash;
return 1;
- case SSL_CTRL_GET_SERVER_TMP_KEY:
+ case SSL_CTRL_GET_SIGNATURE_NID:
+ if (s->s3->tmp.sigalg == NULL)
+ return 0;
+ *(int *)parg = s->s3->tmp.sigalg->hash;
+ return 1;
+
+ case SSL_CTRL_GET_PEER_TMP_KEY:
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC)
- if (s->server || s->session == NULL || s->s3->peer_tmp == NULL) {
+ if (s->session == NULL || s->s3->peer_tmp == NULL) {
return 0;
} else {
EVP_PKEY_up_ref(s->s3->peer_tmp);
@@ -3695,6 +3701,20 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
#else
return 0;
#endif
+
+ case SSL_CTRL_GET_TMP_KEY:
+#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC)
+ if (s->session == NULL || s->s3->tmp.pkey == NULL) {
+ return 0;
+ } else {
+ EVP_PKEY_up_ref(s->s3->tmp.pkey);
+ *(EVP_PKEY **)parg = s->s3->tmp.pkey;
+ return 1;
+ }
+#else
+ return 0;
+#endif
+
#ifndef OPENSSL_NO_EC
case SSL_CTRL_GET_EC_POINT_FORMATS:
{
diff --git a/freebsd/crypto/openssl/ssl/ssl_cert.c b/freebsd/crypto/openssl/ssl/ssl_cert.c
index ab682bf8..c78097a7 100644
--- a/freebsd/crypto/openssl/ssl/ssl_cert.c
+++ b/freebsd/crypto/openssl/ssl/ssl_cert.c
@@ -503,17 +503,17 @@ const STACK_OF(X509_NAME) *SSL_get0_CA_list(const SSL *s)
void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list)
{
- SSL_CTX_set0_CA_list(ctx, name_list);
+ set0_CA_list(&ctx->client_ca_names, name_list);
}
STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx)
{
- return ctx->ca_names;
+ return ctx->client_ca_names;
}
void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list)
{
- SSL_set0_CA_list(s, name_list);
+ set0_CA_list(&s->client_ca_names, name_list);
}
const STACK_OF(X509_NAME) *SSL_get0_peer_CA_list(const SSL *s)
@@ -525,7 +525,8 @@ STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s)
{
if (!s->server)
return s->s3 != NULL ? s->s3->tmp.peer_ca_names : NULL;
- return s->ca_names != NULL ? s->ca_names : s->ctx->ca_names;
+ return s->client_ca_names != NULL ? s->client_ca_names
+ : s->ctx->client_ca_names;
}
static int add_ca_name(STACK_OF(X509_NAME) **sk, const X509 *x)
@@ -563,12 +564,12 @@ int SSL_CTX_add1_to_CA_list(SSL_CTX *ctx, const X509 *x)
*/
int SSL_add_client_CA(SSL *ssl, X509 *x)
{
- return add_ca_name(&ssl->ca_names, x);
+ return add_ca_name(&ssl->client_ca_names, x);
}
int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x)
{
- return add_ca_name(&ctx->ca_names, x);
+ return add_ca_name(&ctx->client_ca_names, x);
}
static int xname_cmp(const X509_NAME *a, const X509_NAME *b)
@@ -953,8 +954,8 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx,
if (level >= 2 && c->algorithm_enc == SSL_RC4)
return 0;
/* Level 3: forward secure ciphersuites only */
- if (level >= 3 && (c->min_tls != TLS1_3_VERSION ||
- !(c->algorithm_mkey & (SSL_kEDH | SSL_kEECDH))))
+ if (level >= 3 && c->min_tls != TLS1_3_VERSION &&
+ !(c->algorithm_mkey & (SSL_kEDH | SSL_kEECDH)))
return 0;
break;
}
diff --git a/freebsd/crypto/openssl/ssl/ssl_ciph.c b/freebsd/crypto/openssl/ssl/ssl_ciph.c
index 65f92ead..1b1fd6dc 100644
--- a/freebsd/crypto/openssl/ssl/ssl_ciph.c
+++ b/freebsd/crypto/openssl/ssl/ssl_ciph.c
@@ -1303,7 +1303,7 @@ static int ciphersuite_cb(const char *elem, int len, void *arg)
return 1;
}
-int set_ciphersuites(STACK_OF(SSL_CIPHER) **currciphers, const char *str)
+static __owur int set_ciphersuites(STACK_OF(SSL_CIPHER) **currciphers, const char *str)
{
STACK_OF(SSL_CIPHER) *newciphers = sk_SSL_CIPHER_new_null();
diff --git a/freebsd/crypto/openssl/ssl/ssl_lib.c b/freebsd/crypto/openssl/ssl/ssl_lib.c
index 3a8c6b94..b9b4da4d 100644
--- a/freebsd/crypto/openssl/ssl/ssl_lib.c
+++ b/freebsd/crypto/openssl/ssl/ssl_lib.c
@@ -656,6 +656,10 @@ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth)
ctx->method = meth;
+ if (!SSL_CTX_set_ciphersuites(ctx, TLS_DEFAULT_CIPHERSUITES)) {
+ SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION, SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS);
+ return 0;
+ }
sk = ssl_create_cipher_list(ctx->method,
ctx->tls13_ciphersuites,
&(ctx->cipher_list),
@@ -1194,6 +1198,7 @@ void SSL_free(SSL *s)
EVP_MD_CTX_free(s->pha_dgst);
sk_X509_NAME_pop_free(s->ca_names, X509_NAME_free);
+ sk_X509_NAME_pop_free(s->client_ca_names, X509_NAME_free);
sk_X509_pop_free(s->verified_chain, X509_free);
@@ -2953,6 +2958,9 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
if ((ret->ca_names = sk_X509_NAME_new_null()) == NULL)
goto err;
+ if ((ret->client_ca_names = sk_X509_NAME_new_null()) == NULL)
+ goto err;
+
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data))
goto err;
@@ -3110,6 +3118,7 @@ void SSL_CTX_free(SSL_CTX *a)
sk_SSL_CIPHER_free(a->tls13_ciphersuites);
ssl_cert_free(a->cert);
sk_X509_NAME_pop_free(a->ca_names, X509_NAME_free);
+ sk_X509_NAME_pop_free(a->client_ca_names, X509_NAME_free);
sk_X509_pop_free(a->extra_certs, X509_free);
a->comp_methods = NULL;
#ifndef OPENSSL_NO_SRTP
@@ -3655,10 +3664,38 @@ const char *SSL_get_version(const SSL *s)
return ssl_protocol_to_string(s->version);
}
-SSL *SSL_dup(SSL *s)
+static int dup_ca_names(STACK_OF(X509_NAME) **dst, STACK_OF(X509_NAME) *src)
{
STACK_OF(X509_NAME) *sk;
X509_NAME *xn;
+ int i;
+
+ if (src == NULL) {
+ *dst = NULL;
+ return 1;
+ }
+
+ if ((sk = sk_X509_NAME_new_null()) == NULL)
+ return 0;
+ for (i = 0; i < sk_X509_NAME_num(src); i++) {
+ xn = X509_NAME_dup(sk_X509_NAME_value(src, i));
+ if (xn == NULL) {
+ sk_X509_NAME_pop_free(sk, X509_NAME_free);
+ return 0;
+ }
+ if (sk_X509_NAME_insert(sk, xn, i) == 0) {
+ X509_NAME_free(xn);
+ sk_X509_NAME_pop_free(sk, X509_NAME_free);
+ return 0;
+ }
+ }
+ *dst = sk;
+
+ return 1;
+}
+
+SSL *SSL_dup(SSL *s)
+{
SSL *ret;
int i;
@@ -3763,18 +3800,10 @@ SSL *SSL_dup(SSL *s)
goto err;
/* Dup the client_CA list */
- if (s->ca_names != NULL) {
- if ((sk = sk_X509_NAME_dup(s->ca_names)) == NULL)
- goto err;
- ret->ca_names = sk;
- for (i = 0; i < sk_X509_NAME_num(sk); i++) {
- xn = sk_X509_NAME_value(sk, i);
- if (sk_X509_NAME_set(sk, i, X509_NAME_dup(xn)) == NULL) {
- X509_NAME_free(xn);
- goto err;
- }
- }
- }
+ if (!dup_ca_names(&ret->ca_names, s->ca_names)
+ || !dup_ca_names(&ret->client_ca_names, s->client_ca_names))
+ goto err;
+
return ret;
err:
@@ -5104,7 +5133,8 @@ static int nss_keylog_int(const char *prefix,
size_t i;
size_t prefix_len;
- if (ssl->ctx->keylog_callback == NULL) return 1;
+ if (ssl->ctx->keylog_callback == NULL)
+ return 1;
/*
* Our output buffer will contain the following strings, rendered with
@@ -5115,7 +5145,7 @@ static int nss_keylog_int(const char *prefix,
* hexadecimal, so we need a buffer that is twice their lengths.
*/
prefix_len = strlen(prefix);
- out_len = prefix_len + (2*parameter_1_len) + (2*parameter_2_len) + 3;
+ out_len = prefix_len + (2 * parameter_1_len) + (2 * parameter_2_len) + 3;
if ((out = cursor = OPENSSL_malloc(out_len)) == NULL) {
SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, SSL_F_NSS_KEYLOG_INT,
ERR_R_MALLOC_FAILURE);
@@ -5139,7 +5169,7 @@ static int nss_keylog_int(const char *prefix,
*cursor = '\0';
ssl->ctx->keylog_callback(ssl, (const char *)out);
- OPENSSL_free(out);
+ OPENSSL_clear_free(out, out_len);
return 1;
}
diff --git a/freebsd/crypto/openssl/ssl/ssl_locl.h b/freebsd/crypto/openssl/ssl/ssl_locl.h
index e8819e7a..70e5a174 100644
--- a/freebsd/crypto/openssl/ssl/ssl_locl.h
+++ b/freebsd/crypto/openssl/ssl/ssl_locl.h
@@ -471,7 +471,11 @@ struct ssl_method_st {
long (*ssl_ctx_callback_ctrl) (SSL_CTX *s, int cb_id, void (*fp) (void));
};
-# define TLS13_MAX_RESUMPTION_PSK_LENGTH 64
+/*
+ * Matches the length of PSK_MAX_PSK_LEN. We keep it the same value for
+ * consistency, even in the event of OPENSSL_NO_PSK being defined.
+ */
+# define TLS13_MAX_RESUMPTION_PSK_LENGTH 256
/*-
* Lets make this into an ASN.1 type structure as follows
@@ -850,9 +854,11 @@ struct ssl_ctx_st {
/*
* What we put in certificate_authorities extension for TLS 1.3
* (ClientHello and CertificateRequest) or just client cert requests for
- * earlier versions.
+ * earlier versions. If client_ca_names is populated then it is only used
+ * for client cert requests, and in preference to ca_names.
*/
STACK_OF(X509_NAME) *ca_names;
+ STACK_OF(X509_NAME) *client_ca_names;
/*
* Default values to use in SSL structures follow (these are copied by
@@ -1229,8 +1235,14 @@ struct ssl_st {
long verify_result;
/* extra application data */
CRYPTO_EX_DATA ex_data;
- /* for server side, keep the list of CA_dn we can use */
+ /*
+ * What we put in certificate_authorities extension for TLS 1.3
+ * (ClientHello and CertificateRequest) or just client cert requests for
+ * earlier versions. If client_ca_names is populated then it is only used
+ * for client cert requests, and in preference to ca_names.
+ */
STACK_OF(X509_NAME) *ca_names;
+ STACK_OF(X509_NAME) *client_ca_names;
CRYPTO_REF_COUNT references;
/* protocol behaviour */
uint32_t options;
@@ -2251,7 +2263,6 @@ __owur int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b);
DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id);
__owur int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap,
const SSL_CIPHER *const *bp);
-__owur int set_ciphersuites(STACK_OF(SSL_CIPHER) **currciphers, const char *str);
__owur STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
STACK_OF(SSL_CIPHER) *tls13_ciphersuites,
STACK_OF(SSL_CIPHER) **cipher_list,
@@ -2561,6 +2572,9 @@ __owur int tls1_process_sigalgs(SSL *s);
__owur int tls1_set_peer_legacy_sigalg(SSL *s, const EVP_PKEY *pkey);
__owur int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd);
__owur size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs);
+# ifndef OPENSSL_NO_EC
+__owur int tls_check_sigalg_curve(const SSL *s, int curve);
+# endif
__owur int tls12_check_peer_sigalg(SSL *s, uint16_t, EVP_PKEY *pkey);
__owur int ssl_set_client_disabled(SSL *s);
__owur int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op, int echde);
diff --git a/freebsd/crypto/openssl/ssl/statem/extensions.c b/freebsd/crypto/openssl/ssl/statem/extensions.c
index a6491c3d..d75460f2 100644
--- a/freebsd/crypto/openssl/ssl/statem/extensions.c
+++ b/freebsd/crypto/openssl/ssl/statem/extensions.c
@@ -964,7 +964,7 @@ static int final_server_name(SSL *s, unsigned int context, int sent)
*/
if (SSL_IS_FIRST_HANDSHAKE(s) && s->ctx != s->session_ctx) {
tsan_counter(&s->ctx->stats.sess_accept);
- tsan_counter(&s->session_ctx->stats.sess_accept);
+ tsan_decr(&s->session_ctx->stats.sess_accept);
}
/*
@@ -1200,7 +1200,7 @@ static EXT_RETURN tls_construct_certificate_authorities(SSL *s, WPACKET *pkt,
X509 *x,
size_t chainidx)
{
- const STACK_OF(X509_NAME) *ca_sk = SSL_get0_CA_list(s);
+ const STACK_OF(X509_NAME) *ca_sk = get_ca_names(s);
if (ca_sk == NULL || sk_X509_NAME_num(ca_sk) == 0)
return EXT_RETURN_NOT_SENT;
@@ -1213,7 +1213,7 @@ static EXT_RETURN tls_construct_certificate_authorities(SSL *s, WPACKET *pkt,
return EXT_RETURN_FAIL;
}
- if (!construct_ca_names(s, pkt)) {
+ if (!construct_ca_names(s, ca_sk, pkt)) {
/* SSLfatal() already called */
return EXT_RETURN_FAIL;
}
@@ -1532,10 +1532,12 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart,
*/
if (s->hello_retry_request == SSL_HRR_PENDING) {
size_t hdatalen;
+ long hdatalen_l;
void *hdata;
- hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
- if (hdatalen <= 0) {
+ hdatalen = hdatalen_l =
+ BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
+ if (hdatalen_l <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PSK_DO_BINDER,
SSL_R_BAD_HANDSHAKE_LENGTH);
goto err;
diff --git a/freebsd/crypto/openssl/ssl/statem/extensions_clnt.c b/freebsd/crypto/openssl/ssl/statem/extensions_clnt.c
index d58ae79b..a64d5367 100644
--- a/freebsd/crypto/openssl/ssl/statem/extensions_clnt.c
+++ b/freebsd/crypto/openssl/ssl/statem/extensions_clnt.c
@@ -117,7 +117,7 @@ EXT_RETURN tls_construct_ctos_srp(SSL *s, WPACKET *pkt, unsigned int context,
#ifndef OPENSSL_NO_EC
static int use_ecc(SSL *s)
{
- int i, end;
+ int i, end, ret = 0;
unsigned long alg_k, alg_a;
STACK_OF(SSL_CIPHER) *cipher_stack = NULL;
@@ -125,7 +125,7 @@ static int use_ecc(SSL *s)
if (s->version == SSL3_VERSION)
return 0;
- cipher_stack = SSL_get_ciphers(s);
+ cipher_stack = SSL_get1_supported_ciphers(s);
end = sk_SSL_CIPHER_num(cipher_stack);
for (i = 0; i < end; i++) {
const SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
@@ -134,11 +134,14 @@ static int use_ecc(SSL *s)
alg_a = c->algorithm_auth;
if ((alg_k & (SSL_kECDHE | SSL_kECDHEPSK))
|| (alg_a & SSL_aECDSA)
- || c->min_tls >= TLS1_3_VERSION)
- return 1;
+ || c->min_tls >= TLS1_3_VERSION) {
+ ret = 1;
+ break;
+ }
}
- return 0;
+ sk_SSL_CIPHER_free(cipher_stack);
+ return ret;
}
EXT_RETURN tls_construct_ctos_ec_pt_formats(SSL *s, WPACKET *pkt,
diff --git a/freebsd/crypto/openssl/ssl/statem/statem.c b/freebsd/crypto/openssl/ssl/statem/statem.c
index 32e87690..ad50677d 100644
--- a/freebsd/crypto/openssl/ssl/statem/statem.c
+++ b/freebsd/crypto/openssl/ssl/statem/statem.c
@@ -120,11 +120,12 @@ void ossl_statem_set_renegotiate(SSL *s)
void ossl_statem_fatal(SSL *s, int al, int func, int reason, const char *file,
int line)
{
+ ERR_put_error(ERR_LIB_SSL, func, reason, file, line);
/* We shouldn't call SSLfatal() twice. Once is enough */
- assert(s->statem.state != MSG_FLOW_ERROR);
+ if (s->statem.in_init && s->statem.state == MSG_FLOW_ERROR)
+ return;
s->statem.in_init = 1;
s->statem.state = MSG_FLOW_ERROR;
- ERR_put_error(ERR_LIB_SSL, func, reason, file, line);
if (al != SSL_AD_NO_ALERT
&& s->statem.enc_write_state != ENC_WRITE_STATE_INVALID)
ssl3_send_alert(s, SSL3_AL_FATAL, al);
diff --git a/freebsd/crypto/openssl/ssl/statem/statem_clnt.c b/freebsd/crypto/openssl/ssl/statem/statem_clnt.c
index 574ec01e..154a9d45 100644
--- a/freebsd/crypto/openssl/ssl/statem/statem_clnt.c
+++ b/freebsd/crypto/openssl/ssl/statem/statem_clnt.c
@@ -1097,6 +1097,7 @@ WORK_STATE ossl_statem_client_post_process_message(SSL *s, WORK_STATE wst)
ERR_R_INTERNAL_ERROR);
return WORK_ERROR;
+ case TLS_ST_CR_CERT_VRFY:
case TLS_ST_CR_CERT_REQ:
return tls_prepare_client_certificate(s, wst);
}
@@ -2565,6 +2566,17 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
/* we should setup a certificate to return.... */
s->s3->tmp.cert_req = 1;
+ /*
+ * In TLSv1.3 we don't prepare the client certificate yet. We wait until
+ * after the CertificateVerify message has been received. This is because
+ * in TLSv1.3 the CertificateRequest arrives before the Certificate message
+ * but in TLSv1.2 it is the other way around. We want to make sure that
+ * SSL_get_peer_certificate() returns something sensible in
+ * client_cert_cb.
+ */
+ if (SSL_IS_TLS13(s) && s->post_handshake_auth != SSL_PHA_REQUESTED)
+ return MSG_PROCESS_CONTINUE_READING;
+
return MSG_PROCESS_CONTINUE_PROCESSING;
}
diff --git a/freebsd/crypto/openssl/ssl/statem/statem_lib.c b/freebsd/crypto/openssl/ssl/statem/statem_lib.c
index 1ea719c7..e8c96f27 100644
--- a/freebsd/crypto/openssl/ssl/statem/statem_lib.c
+++ b/freebsd/crypto/openssl/ssl/statem/statem_lib.c
@@ -205,9 +205,10 @@ static int get_cert_verify_tbs_data(SSL *s, unsigned char *tls13tbs,
*hdatalen = TLS13_TBS_PREAMBLE_SIZE + hashlen;
} else {
size_t retlen;
+ long retlen_l;
- retlen = BIO_get_mem_data(s->s3->handshake_buffer, hdata);
- if (retlen <= 0) {
+ retlen = retlen_l = BIO_get_mem_data(s->s3->handshake_buffer, hdata);
+ if (retlen_l <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_GET_CERT_VERIFY_TBS_DATA,
ERR_R_INTERNAL_ERROR);
return 0;
@@ -496,7 +497,18 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
}
}
- ret = MSG_PROCESS_CONTINUE_READING;
+ /*
+ * In TLSv1.3 on the client side we make sure we prepare the client
+ * certificate after the CertVerify instead of when we get the
+ * CertificateRequest. This is because in TLSv1.3 the CertificateRequest
+ * comes *before* the Certificate message. In TLSv1.2 it comes after. We
+ * want to make sure that SSL_get_peer_certificate() will return the actual
+ * server certificate from the client_cert_cb callback.
+ */
+ if (!s->server && SSL_IS_TLS13(s) && s->s3->tmp.cert_req == 1)
+ ret = MSG_PROCESS_CONTINUE_PROCESSING;
+ else
+ ret = MSG_PROCESS_CONTINUE_READING;
err:
BIO_free(s->s3->handshake_buffer);
s->s3->handshake_buffer = NULL;
@@ -1497,6 +1509,10 @@ static int ssl_method_error(const SSL *s, const SSL_METHOD *method)
static int is_tls13_capable(const SSL *s)
{
int i;
+#ifndef OPENSSL_NO_EC
+ int curve;
+ EC_KEY *eckey;
+#endif
#ifndef OPENSSL_NO_PSK
if (s->psk_server_callback != NULL)
@@ -1517,8 +1533,25 @@ static int is_tls13_capable(const SSL *s)
default:
break;
}
- if (ssl_has_cert(s, i))
+ if (!ssl_has_cert(s, i))
+ continue;
+#ifndef OPENSSL_NO_EC
+ if (i != SSL_PKEY_ECC)
+ return 1;
+ /*
+ * Prior to TLSv1.3 sig algs allowed any curve to be used. TLSv1.3 is
+ * more restrictive so check that our sig algs are consistent with this
+ * EC cert. See section 4.2.3 of RFC8446.
+ */
+ eckey = EVP_PKEY_get0_EC_KEY(s->cert->pkeys[SSL_PKEY_ECC].privatekey);
+ if (eckey == NULL)
+ continue;
+ curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey));
+ if (tls_check_sigalg_curve(s, curve))
return 1;
+#else
+ return 1;
+#endif
}
return 0;
@@ -2263,10 +2296,24 @@ int parse_ca_names(SSL *s, PACKET *pkt)
return 0;
}
-int construct_ca_names(SSL *s, WPACKET *pkt)
+const STACK_OF(X509_NAME) *get_ca_names(SSL *s)
{
- const STACK_OF(X509_NAME) *ca_sk = SSL_get0_CA_list(s);
+ const STACK_OF(X509_NAME) *ca_sk = NULL;;
+
+ if (s->server) {
+ ca_sk = SSL_get_client_CA_list(s);
+ if (ca_sk != NULL && sk_X509_NAME_num(ca_sk) == 0)
+ ca_sk = NULL;
+ }
+
+ if (ca_sk == NULL)
+ ca_sk = SSL_get0_CA_list(s);
+ return ca_sk;
+}
+
+int construct_ca_names(SSL *s, const STACK_OF(X509_NAME) *ca_sk, WPACKET *pkt)
+{
/* Start sub-packet for client CA list */
if (!WPACKET_start_sub_packet_u16(pkt)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_CA_NAMES,
diff --git a/freebsd/crypto/openssl/ssl/statem/statem_locl.h b/freebsd/crypto/openssl/ssl/statem/statem_locl.h
index 25e56e4e..6b8cf37f 100644
--- a/freebsd/crypto/openssl/ssl/statem/statem_locl.h
+++ b/freebsd/crypto/openssl/ssl/statem/statem_locl.h
@@ -61,7 +61,8 @@ int create_synthetic_message_hash(SSL *s, const unsigned char *hashval,
size_t hashlen, const unsigned char *hrr,
size_t hrrlen);
int parse_ca_names(SSL *s, PACKET *pkt);
-int construct_ca_names(SSL *s, WPACKET *pkt);
+const STACK_OF(X509_NAME) *get_ca_names(SSL *s);
+int construct_ca_names(SSL *s, const STACK_OF(X509_NAME) *ca_sk, WPACKET *pkt);
size_t construct_key_exchange_tbs(SSL *s, unsigned char **ptbs,
const void *param, size_t paramlen);
diff --git a/freebsd/crypto/openssl/ssl/statem/statem_srvr.c b/freebsd/crypto/openssl/ssl/statem/statem_srvr.c
index f9c06aaf..c9bee6ba 100644
--- a/freebsd/crypto/openssl/ssl/statem/statem_srvr.c
+++ b/freebsd/crypto/openssl/ssl/statem/statem_srvr.c
@@ -1521,8 +1521,10 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt)
* So check cookie length...
*/
if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) {
- if (clienthello->dtls_cookie_len == 0)
+ if (clienthello->dtls_cookie_len == 0) {
+ OPENSSL_free(clienthello);
return MSG_PROCESS_FINISHED_READING;
+ }
}
}
@@ -2058,10 +2060,6 @@ static int tls_early_post_process_client_hello(SSL *s)
#else
s->session->compress_meth = (comp == NULL) ? 0 : comp->id;
#endif
- if (!tls1_set_server_sigalgs(s)) {
- /* SSLfatal() already called */
- goto err;
- }
}
sk_SSL_CIPHER_free(ciphers);
@@ -2229,19 +2227,25 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst)
if (wst == WORK_MORE_B) {
if (!s->hit || SSL_IS_TLS13(s)) {
/* Let cert callback update server certificates if required */
- if (!s->hit && s->cert->cert_cb != NULL) {
- int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg);
- if (rv == 0) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS_POST_PROCESS_CLIENT_HELLO,
- SSL_R_CERT_CB_ERROR);
- goto err;
+ if (!s->hit) {
+ if (s->cert->cert_cb != NULL) {
+ int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg);
+ if (rv == 0) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR,
+ SSL_F_TLS_POST_PROCESS_CLIENT_HELLO,
+ SSL_R_CERT_CB_ERROR);
+ goto err;
+ }
+ if (rv < 0) {
+ s->rwstate = SSL_X509_LOOKUP;
+ return WORK_MORE_B;
+ }
+ s->rwstate = SSL_NOTHING;
}
- if (rv < 0) {
- s->rwstate = SSL_X509_LOOKUP;
- return WORK_MORE_B;
+ if (!tls1_set_server_sigalgs(s)) {
+ /* SSLfatal already called */
+ goto err;
}
- s->rwstate = SSL_NOTHING;
}
/* In TLSv1.3 we selected the ciphersuite before resumption */
@@ -2878,7 +2882,7 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt)
}
}
- if (!construct_ca_names(s, pkt)) {
+ if (!construct_ca_names(s, get_ca_names(s), pkt)) {
/* SSLfatal() already called */
return 0;
}
@@ -3224,6 +3228,12 @@ static int tls_process_cke_ecdhe(SSL *s, PACKET *pkt)
SSL_R_LENGTH_MISMATCH);
goto err;
}
+ if (skey == NULL) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_ECDHE,
+ SSL_R_MISSING_TMP_ECDH_KEY);
+ goto err;
+ }
+
ckey = EVP_PKEY_new();
if (ckey == NULL || EVP_PKEY_copy_parameters(ckey, skey) <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_ECDHE,
diff --git a/freebsd/crypto/openssl/ssl/t1_lib.c b/freebsd/crypto/openssl/ssl/t1_lib.c
index 923b501f..88f26f05 100644
--- a/freebsd/crypto/openssl/ssl/t1_lib.c
+++ b/freebsd/crypto/openssl/ssl/t1_lib.c
@@ -345,6 +345,10 @@ int tls1_set_groups(uint16_t **pext, size_t *pextlen,
*/
unsigned long dup_list = 0;
+ if (ngroups == 0) {
+ SSLerr(SSL_F_TLS1_SET_GROUPS, SSL_R_BAD_LENGTH);
+ return 0;
+ }
if ((glist = OPENSSL_malloc(ngroups * sizeof(*glist))) == NULL) {
SSLerr(SSL_F_TLS1_SET_GROUPS, ERR_R_MALLOC_FAILURE);
return 0;
@@ -947,6 +951,39 @@ size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs)
}
}
+#ifndef OPENSSL_NO_EC
+/*
+ * Called by servers only. Checks that we have a sig alg that supports the
+ * specified EC curve.
+ */
+int tls_check_sigalg_curve(const SSL *s, int curve)
+{
+ const uint16_t *sigs;
+ size_t siglen, i;
+
+ if (s->cert->conf_sigalgs) {
+ sigs = s->cert->conf_sigalgs;
+ siglen = s->cert->conf_sigalgslen;
+ } else {
+ sigs = tls12_sigalgs;
+ siglen = OSSL_NELEM(tls12_sigalgs);
+ }
+
+ for (i = 0; i < siglen; i++) {
+ const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(sigs[i]);
+
+ if (lu == NULL)
+ continue;
+ if (lu->sig == EVP_PKEY_EC
+ && lu->curve != NID_undef
+ && curve == lu->curve)
+ return 1;
+ }
+
+ return 0;
+}
+#endif
+
/*
* Check signature algorithm is consistent with sent supported signature
* algorithms and if so set relevant digest and signature scheme in
@@ -1089,6 +1126,14 @@ int SSL_get_peer_signature_type_nid(const SSL *s, int *pnid)
return 1;
}
+int SSL_get_signature_type_nid(const SSL *s, int *pnid)
+{
+ if (s->s3->tmp.sigalg == NULL)
+ return 0;
+ *pnid = s->s3->tmp.sigalg->sig;
+ return 1;
+}
+
/*
* Set a mask of disabled algorithms: an algorithm is disabled if it isn't
* supported, doesn't appear in supported signature algorithms, isn't supported
diff --git a/freebsd/crypto/openssl/ssl/tls13_enc.c b/freebsd/crypto/openssl/ssl/tls13_enc.c
index cd100126..0e8c4bc3 100644
--- a/freebsd/crypto/openssl/ssl/tls13_enc.c
+++ b/freebsd/crypto/openssl/ssl/tls13_enc.c
@@ -15,7 +15,14 @@
#include <openssl/evp.h>
#include <openssl/kdf.h>
-#define TLS13_MAX_LABEL_LEN 246
+/*
+ * RFC 8446, 7.1 Key Schedule, says:
+ * Note: With common hash functions, any label longer than 12 characters
+ * requires an additional iteration of the hash function to compute.
+ * The labels in this specification have all been chosen to fit within
+ * this limit.
+ */
+#define TLS13_MAX_LABEL_LEN 12
/* Always filled with zeros */
static const unsigned char default_zeros[EVP_MAX_MD_SIZE];
@@ -31,14 +38,15 @@ int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret,
const unsigned char *data, size_t datalen,
unsigned char *out, size_t outlen)
{
- const unsigned char label_prefix[] = "tls13 ";
+ static const unsigned char label_prefix[] = "tls13 ";
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
int ret;
size_t hkdflabellen;
size_t hashlen;
/*
- * 2 bytes for length of whole HkdfLabel + 1 byte for length of combined
- * prefix and label + bytes for the label itself + bytes for the hash
+ * 2 bytes for length of derived secret + 1 byte for length of combined
+ * prefix and label + bytes for the label itself + 1 byte length of hash
+ * + bytes for the hash itself
*/
unsigned char hkdflabel[sizeof(uint16_t) + sizeof(uint8_t) +
+ sizeof(label_prefix) + TLS13_MAX_LABEL_LEN