Blame SOURCES/openssl-1.1.1-upstream-sync.patch

acdedc
diff -up openssl-1.1.1c/crypto/dsa/dsa_ameth.c.sync openssl-1.1.1c/crypto/dsa/dsa_ameth.c
acdedc
--- openssl-1.1.1c/crypto/dsa/dsa_ameth.c.sync	2019-05-28 15:12:21.000000000 +0200
acdedc
+++ openssl-1.1.1c/crypto/dsa/dsa_ameth.c	2019-05-29 17:10:39.768187283 +0200
acdedc
@@ -503,7 +503,7 @@ static int dsa_pkey_ctrl(EVP_PKEY *pkey,
acdedc
 
acdedc
     case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
acdedc
         *(int *)arg2 = NID_sha256;
acdedc
-        return 2;
acdedc
+        return 1;
acdedc
 
acdedc
     default:
acdedc
         return -2;
acdedc
diff -up openssl-1.1.1c/crypto/err/err.c.sync openssl-1.1.1c/crypto/err/err.c
acdedc
--- openssl-1.1.1c/crypto/err/err.c.sync	2019-05-28 15:12:21.000000000 +0200
acdedc
+++ openssl-1.1.1c/crypto/err/err.c	2019-05-29 17:07:13.345793792 +0200
acdedc
@@ -184,8 +184,8 @@ static ERR_STRING_DATA *int_err_get_item
acdedc
 }
acdedc
 
acdedc
 #ifndef OPENSSL_NO_ERR
acdedc
-/* A measurement on Linux 2018-11-21 showed about 3.5kib */
acdedc
-# define SPACE_SYS_STR_REASONS 4 * 1024
acdedc
+/* 2019-05-21: Russian and Ukrainian locales on Linux require more than 6,5 kB */
acdedc
+# define SPACE_SYS_STR_REASONS 8 * 1024
acdedc
 # define NUM_SYS_STR_REASONS 127
acdedc
 
acdedc
 static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
acdedc
@@ -219,21 +219,23 @@ static void build_SYS_str_reasons(void)
acdedc
         ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];
acdedc
 
acdedc
         str->error = ERR_PACK(ERR_LIB_SYS, 0, i);
acdedc
-        if (str->string == NULL) {
acdedc
+        /*
acdedc
+         * If we have used up all the space in strerror_pool,
acdedc
+         * there's no point in calling openssl_strerror_r()
acdedc
+         */
acdedc
+        if (str->string == NULL && cnt < sizeof(strerror_pool)) {
acdedc
             if (openssl_strerror_r(i, cur, sizeof(strerror_pool) - cnt)) {
acdedc
                 size_t l = strlen(cur);
acdedc
 
acdedc
                 str->string = cur;
acdedc
                 cnt += l;
acdedc
-                if (cnt > sizeof(strerror_pool))
acdedc
-                    cnt = sizeof(strerror_pool);
acdedc
                 cur += l;
acdedc
 
acdedc
                 /*
acdedc
                  * VMS has an unusual quirk of adding spaces at the end of
acdedc
-                 * some (most? all?) messages.  Lets trim them off.
acdedc
+                 * some (most? all?) messages. Lets trim them off.
acdedc
                  */
acdedc
-                while (ossl_isspace(cur[-1])) {
acdedc
+                while (cur > strerror_pool && ossl_isspace(cur[-1])) {
acdedc
                     cur--;
acdedc
                     cnt--;
acdedc
                 }
acdedc
diff -up openssl-1.1.1c/crypto/rand/rand_lib.c.sync openssl-1.1.1c/crypto/rand/rand_lib.c
acdedc
--- openssl-1.1.1c/crypto/rand/rand_lib.c.sync	2019-05-29 17:20:17.175099183 +0200
acdedc
+++ openssl-1.1.1c/crypto/rand/rand_lib.c	2019-05-30 11:51:20.784850208 +0200
acdedc
@@ -239,8 +239,9 @@ size_t rand_drbg_get_nonce(RAND_DRBG *dr
acdedc
     struct {
acdedc
         void * instance;
acdedc
         int count;
acdedc
-    } data = { NULL, 0 };
acdedc
+    } data;
acdedc
 
acdedc
+    memset(&data, 0, sizeof(data));
acdedc
     pool = rand_pool_new(0, min_len, max_len);
acdedc
     if (pool == NULL)
acdedc
         return 0;
acdedc
From 6c2f347c78a530407b5310497080810094427920 Mon Sep 17 00:00:00 2001
acdedc
From: Matt Caswell <matt@openssl.org>
acdedc
Date: Wed, 17 Apr 2019 11:09:05 +0100
acdedc
Subject: [PATCH 1/2] Defer sending a KeyUpdate until after pending writes are
acdedc
 complete
acdedc
acdedc
If we receive a KeyUpdate message (update requested) from the peer while
acdedc
we are in the middle of a write, we should defer sending the responding
acdedc
KeyUpdate message until after the current write is complete. We do this
acdedc
by waiting to send the KeyUpdate until the next time we write and there is
acdedc
no pending write data.
acdedc
acdedc
This does imply a subtle change in behaviour. Firstly the responding
acdedc
KeyUpdate message won't be sent straight away as it is now. Secondly if
acdedc
the peer sends multiple KeyUpdates without us doing any writing then we
acdedc
will only send one response, as opposed to previously where we sent a
acdedc
response for each KeyUpdate received.
acdedc
acdedc
Fixes #8677
acdedc
acdedc
Reviewed-by: Ben Kaduk <kaduk@mit.edu>
acdedc
(Merged from https://github.com/openssl/openssl/pull/8773)
acdedc
acdedc
(cherry picked from commit feb9e31c40c49de6384dd0413685e9b5a15adc99)
acdedc
---
acdedc
 ssl/record/rec_layer_s3.c | 7 +++++++
acdedc
 ssl/statem/statem_clnt.c  | 6 ------
acdedc
 ssl/statem/statem_lib.c   | 7 ++-----
acdedc
 ssl/statem/statem_srvr.c  | 6 ------
acdedc
 4 files changed, 9 insertions(+), 17 deletions(-)
acdedc
acdedc
diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c
acdedc
index b2f97ef905..b65137c332 100644
acdedc
--- a/ssl/record/rec_layer_s3.c
acdedc
+++ b/ssl/record/rec_layer_s3.c
acdedc
@@ -373,6 +373,13 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len,
acdedc
 
acdedc
     s->rlayer.wnum = 0;
acdedc
 
acdedc
+    /*
acdedc
+     * If we are supposed to be sending a KeyUpdate then go into init unless we
acdedc
+     * have writes pending - in which case we should finish doing that first.
acdedc
+     */
acdedc
+    if (wb->left == 0 && s->key_update != SSL_KEY_UPDATE_NONE)
acdedc
+        ossl_statem_set_in_init(s, 1);
acdedc
+
acdedc
     /*
acdedc
      * When writing early data on the server side we could be "in_init" in
acdedc
      * between receiving the EoED and the CF - but we don't want to handle those
acdedc
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
acdedc
index 87800cd835..6410414fb6 100644
acdedc
--- a/ssl/statem/statem_clnt.c
acdedc
+++ b/ssl/statem/statem_clnt.c
acdedc
@@ -473,12 +473,6 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s)
acdedc
         return WRITE_TRAN_CONTINUE;
acdedc
 
acdedc
     case TLS_ST_CR_KEY_UPDATE:
acdedc
-        if (s->key_update != SSL_KEY_UPDATE_NONE) {
acdedc
-            st->hand_state = TLS_ST_CW_KEY_UPDATE;
acdedc
-            return WRITE_TRAN_CONTINUE;
acdedc
-        }
acdedc
-        /* Fall through */
acdedc
-
acdedc
     case TLS_ST_CW_KEY_UPDATE:
acdedc
     case TLS_ST_CR_SESSION_TICKET:
acdedc
     case TLS_ST_CW_FINISHED:
acdedc
diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c
acdedc
index c0482b0a90..2960dafa52 100644
acdedc
--- a/ssl/statem/statem_lib.c
acdedc
+++ b/ssl/statem/statem_lib.c
acdedc
@@ -645,12 +645,9 @@ MSG_PROCESS_RETURN tls_process_key_update(SSL *s, PACKET *pkt)
acdedc
     /*
acdedc
      * If we get a request for us to update our sending keys too then, we need
acdedc
      * to additionally send a KeyUpdate message. However that message should
acdedc
-     * not also request an update (otherwise we get into an infinite loop). We
acdedc
-     * ignore a request for us to update our sending keys too if we already
acdedc
-     * sent close_notify.
acdedc
+     * not also request an update (otherwise we get into an infinite loop).
acdedc
      */
acdedc
-    if (updatetype == SSL_KEY_UPDATE_REQUESTED
acdedc
-            && (s->shutdown & SSL_SENT_SHUTDOWN) == 0)
acdedc
+    if (updatetype == SSL_KEY_UPDATE_REQUESTED)
acdedc
         s->key_update = SSL_KEY_UPDATE_NOT_REQUESTED;
acdedc
 
acdedc
     if (!tls13_update_key(s, 0)) {
acdedc
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
acdedc
index d454326a99..04a23320fc 100644
acdedc
--- a/ssl/statem/statem_srvr.c
acdedc
+++ b/ssl/statem/statem_srvr.c
acdedc
@@ -502,12 +502,6 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s)
acdedc
         return WRITE_TRAN_CONTINUE;
acdedc
 
acdedc
     case TLS_ST_SR_KEY_UPDATE:
acdedc
-        if (s->key_update != SSL_KEY_UPDATE_NONE) {
acdedc
-            st->hand_state = TLS_ST_SW_KEY_UPDATE;
acdedc
-            return WRITE_TRAN_CONTINUE;
acdedc
-        }
acdedc
-        /* Fall through */
acdedc
-
acdedc
     case TLS_ST_SW_KEY_UPDATE:
acdedc
         st->hand_state = TLS_ST_OK;
acdedc
         return WRITE_TRAN_CONTINUE;
acdedc
-- 
acdedc
2.20.1
acdedc
acdedc
From c8feb1039ccc4cd11e6db084df1446bf863bee1e Mon Sep 17 00:00:00 2001
acdedc
From: Matt Caswell <matt@openssl.org>
acdedc
Date: Wed, 17 Apr 2019 10:30:53 +0100
acdedc
Subject: [PATCH 2/2] Write a test for receiving a KeyUpdate (update requested)
acdedc
 while writing
acdedc
acdedc
Reviewed-by: Ben Kaduk <kaduk@mit.edu>
acdedc
(Merged from https://github.com/openssl/openssl/pull/8773)
acdedc
acdedc
(cherry picked from commit a77b4dba237d001073d2d1c5d55c674a196c949f)
acdedc
---
acdedc
 test/sslapitest.c | 92 +++++++++++++++++++++++++++++++++++++++++++++
acdedc
 test/ssltestlib.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++
acdedc
 test/ssltestlib.h |  3 ++
acdedc
 3 files changed, 191 insertions(+)
acdedc
acdedc
diff --git a/test/sslapitest.c b/test/sslapitest.c
acdedc
index 2261fe4a7a..577342644d 100644
acdedc
--- a/test/sslapitest.c
acdedc
+++ b/test/sslapitest.c
acdedc
@@ -4290,6 +4290,11 @@ static int test_key_update(void)
acdedc
                 || !TEST_int_eq(SSL_read(serverssl, buf, sizeof(buf)),
acdedc
                                          strlen(mess)))
acdedc
             goto end;
acdedc
+
acdedc
+        if (!TEST_int_eq(SSL_write(serverssl, mess, strlen(mess)), strlen(mess))
acdedc
+                || !TEST_int_eq(SSL_read(clientssl, buf, sizeof(buf)),
acdedc
+                                         strlen(mess)))
acdedc
+            goto end;
acdedc
     }
acdedc
 
acdedc
     testresult = 1;
acdedc
@@ -4302,6 +4307,91 @@ static int test_key_update(void)
acdedc
 
acdedc
     return testresult;
acdedc
 }
acdedc
+
acdedc
+/*
acdedc
+ * Test we can handle a KeyUpdate (update requested) message while write data
acdedc
+ * is pending.
acdedc
+ * Test 0: Client sends KeyUpdate while Server is writing
acdedc
+ * Test 1: Server sends KeyUpdate while Client is writing
acdedc
+ */
acdedc
+static int test_key_update_in_write(int tst)
acdedc
+{
acdedc
+    SSL_CTX *cctx = NULL, *sctx = NULL;
acdedc
+    SSL *clientssl = NULL, *serverssl = NULL;
acdedc
+    int testresult = 0;
acdedc
+    char buf[20];
acdedc
+    static char *mess = "A test message";
acdedc
+    BIO *bretry = BIO_new(bio_s_always_retry());
acdedc
+    BIO *tmp = NULL;
acdedc
+    SSL *peerupdate = NULL, *peerwrite = NULL;
acdedc
+
acdedc
+    if (!TEST_ptr(bretry)
acdedc
+            || !TEST_true(create_ssl_ctx_pair(TLS_server_method(),
acdedc
+                                              TLS_client_method(),
acdedc
+                                              TLS1_3_VERSION,
acdedc
+                                              0,
acdedc
+                                              &sctx, &cctx, cert, privkey))
acdedc
+            || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
acdedc
+                                             NULL, NULL))
acdedc
+            || !TEST_true(create_ssl_connection(serverssl, clientssl,
acdedc
+                                                SSL_ERROR_NONE)))
acdedc
+        goto end;
acdedc
+
acdedc
+    peerupdate = tst == 0 ? clientssl : serverssl;
acdedc
+    peerwrite = tst == 0 ? serverssl : clientssl;
acdedc
+
acdedc
+    if (!TEST_true(SSL_key_update(peerupdate, SSL_KEY_UPDATE_REQUESTED))
acdedc
+            || !TEST_true(SSL_do_handshake(peerupdate)))
acdedc
+        goto end;
acdedc
+
acdedc
+    /* Swap the writing endpoint's write BIO to force a retry */
acdedc
+    tmp = SSL_get_wbio(peerwrite);
acdedc
+    if (!TEST_ptr(tmp) || !TEST_true(BIO_up_ref(tmp))) {
acdedc
+        tmp = NULL;
acdedc
+        goto end;
acdedc
+    }
acdedc
+    SSL_set0_wbio(peerwrite, bretry);
acdedc
+    bretry = NULL;
acdedc
+
acdedc
+    /* Write data that we know will fail with SSL_ERROR_WANT_WRITE */
acdedc
+    if (!TEST_int_eq(SSL_write(peerwrite, mess, strlen(mess)), -1)
acdedc
+            || !TEST_int_eq(SSL_get_error(peerwrite, 0), SSL_ERROR_WANT_WRITE))
acdedc
+        goto end;
acdedc
+
acdedc
+    /* Reinstate the original writing endpoint's write BIO */
acdedc
+    SSL_set0_wbio(peerwrite, tmp);
acdedc
+    tmp = NULL;
acdedc
+
acdedc
+    /* Now read some data - we will read the key update */
acdedc
+    if (!TEST_int_eq(SSL_read(peerwrite, buf, sizeof(buf)), -1)
acdedc
+            || !TEST_int_eq(SSL_get_error(peerwrite, 0), SSL_ERROR_WANT_READ))
acdedc
+        goto end;
acdedc
+
acdedc
+    /*
acdedc
+     * Complete the write we started previously and read it from the other
acdedc
+     * endpoint
acdedc
+     */
acdedc
+    if (!TEST_int_eq(SSL_write(peerwrite, mess, strlen(mess)), strlen(mess))
acdedc
+            || !TEST_int_eq(SSL_read(peerupdate, buf, sizeof(buf)), strlen(mess)))
acdedc
+        goto end;
acdedc
+
acdedc
+    /* Write more data to ensure we send the KeyUpdate message back */
acdedc
+    if (!TEST_int_eq(SSL_write(peerwrite, mess, strlen(mess)), strlen(mess))
acdedc
+            || !TEST_int_eq(SSL_read(peerupdate, buf, sizeof(buf)), strlen(mess)))
acdedc
+        goto end;
acdedc
+
acdedc
+    testresult = 1;
acdedc
+
acdedc
+ end:
acdedc
+    SSL_free(serverssl);
acdedc
+    SSL_free(clientssl);
acdedc
+    SSL_CTX_free(sctx);
acdedc
+    SSL_CTX_free(cctx);
acdedc
+    BIO_free(bretry);
acdedc
+    BIO_free(tmp);
acdedc
+
acdedc
+    return testresult;
acdedc
+}
acdedc
 #endif /* OPENSSL_NO_TLS1_3 */
acdedc
 
acdedc
 static int test_ssl_clear(int idx)
acdedc
@@ -5982,6 +6072,7 @@ int setup_tests(void)
acdedc
 #ifndef OPENSSL_NO_TLS1_3
acdedc
     ADD_ALL_TESTS(test_export_key_mat_early, 3);
acdedc
     ADD_TEST(test_key_update);
acdedc
+    ADD_ALL_TESTS(test_key_update_in_write, 2);
acdedc
 #endif
acdedc
     ADD_ALL_TESTS(test_ssl_clear, 2);
acdedc
     ADD_ALL_TESTS(test_max_fragment_len_ext, OSSL_NELEM(max_fragment_len_test));
acdedc
@@ -6002,4 +6093,5 @@ int setup_tests(void)
acdedc
 void cleanup_tests(void)
acdedc
 {
acdedc
     bio_s_mempacket_test_free();
acdedc
+    bio_s_always_retry_free();
acdedc
 }
acdedc
diff --git a/test/ssltestlib.c b/test/ssltestlib.c
acdedc
index 05139be750..e1038620ac 100644
acdedc
--- a/test/ssltestlib.c
acdedc
+++ b/test/ssltestlib.c
acdedc
@@ -62,9 +62,11 @@ static int tls_dump_puts(BIO *bp, const char *str);
acdedc
 /* Choose a sufficiently large type likely to be unused for this custom BIO */
acdedc
 #define BIO_TYPE_TLS_DUMP_FILTER  (0x80 | BIO_TYPE_FILTER)
acdedc
 #define BIO_TYPE_MEMPACKET_TEST    0x81
acdedc
+#define BIO_TYPE_ALWAYS_RETRY      0x82
acdedc
 
acdedc
 static BIO_METHOD *method_tls_dump = NULL;
acdedc
 static BIO_METHOD *meth_mem = NULL;
acdedc
+static BIO_METHOD *meth_always_retry = NULL;
acdedc
 
acdedc
 /* Note: Not thread safe! */
acdedc
 const BIO_METHOD *bio_f_tls_dump_filter(void)
acdedc
@@ -612,6 +614,100 @@ static int mempacket_test_puts(BIO *bio, const char *str)
acdedc
     return mempacket_test_write(bio, str, strlen(str));
acdedc
 }
acdedc
 
acdedc
+static int always_retry_new(BIO *bi);
acdedc
+static int always_retry_free(BIO *a);
acdedc
+static int always_retry_read(BIO *b, char *out, int outl);
acdedc
+static int always_retry_write(BIO *b, const char *in, int inl);
acdedc
+static long always_retry_ctrl(BIO *b, int cmd, long num, void *ptr);
acdedc
+static int always_retry_gets(BIO *bp, char *buf, int size);
acdedc
+static int always_retry_puts(BIO *bp, const char *str);
acdedc
+
acdedc
+const BIO_METHOD *bio_s_always_retry(void)
acdedc
+{
acdedc
+    if (meth_always_retry == NULL) {
acdedc
+        if (!TEST_ptr(meth_always_retry = BIO_meth_new(BIO_TYPE_ALWAYS_RETRY,
acdedc
+                                                       "Always Retry"))
acdedc
+            || !TEST_true(BIO_meth_set_write(meth_always_retry,
acdedc
+                                             always_retry_write))
acdedc
+            || !TEST_true(BIO_meth_set_read(meth_always_retry,
acdedc
+                                            always_retry_read))
acdedc
+            || !TEST_true(BIO_meth_set_puts(meth_always_retry,
acdedc
+                                            always_retry_puts))
acdedc
+            || !TEST_true(BIO_meth_set_gets(meth_always_retry,
acdedc
+                                            always_retry_gets))
acdedc
+            || !TEST_true(BIO_meth_set_ctrl(meth_always_retry,
acdedc
+                                            always_retry_ctrl))
acdedc
+            || !TEST_true(BIO_meth_set_create(meth_always_retry,
acdedc
+                                              always_retry_new))
acdedc
+            || !TEST_true(BIO_meth_set_destroy(meth_always_retry,
acdedc
+                                               always_retry_free)))
acdedc
+            return NULL;
acdedc
+    }
acdedc
+    return meth_always_retry;
acdedc
+}
acdedc
+
acdedc
+void bio_s_always_retry_free(void)
acdedc
+{
acdedc
+    BIO_meth_free(meth_always_retry);
acdedc
+}
acdedc
+
acdedc
+static int always_retry_new(BIO *bio)
acdedc
+{
acdedc
+    BIO_set_init(bio, 1);
acdedc
+    return 1;
acdedc
+}
acdedc
+
acdedc
+static int always_retry_free(BIO *bio)
acdedc
+{
acdedc
+    BIO_set_data(bio, NULL);
acdedc
+    BIO_set_init(bio, 0);
acdedc
+    return 1;
acdedc
+}
acdedc
+
acdedc
+static int always_retry_read(BIO *bio, char *out, int outl)
acdedc
+{
acdedc
+    BIO_set_retry_read(bio);
acdedc
+    return -1;
acdedc
+}
acdedc
+
acdedc
+static int always_retry_write(BIO *bio, const char *in, int inl)
acdedc
+{
acdedc
+    BIO_set_retry_write(bio);
acdedc
+    return -1;
acdedc
+}
acdedc
+
acdedc
+static long always_retry_ctrl(BIO *bio, int cmd, long num, void *ptr)
acdedc
+{
acdedc
+    long ret = 1;
acdedc
+
acdedc
+    switch (cmd) {
acdedc
+    case BIO_CTRL_FLUSH:
acdedc
+        BIO_set_retry_write(bio);
acdedc
+        /* fall through */
acdedc
+    case BIO_CTRL_EOF:
acdedc
+    case BIO_CTRL_RESET:
acdedc
+    case BIO_CTRL_DUP:
acdedc
+    case BIO_CTRL_PUSH:
acdedc
+    case BIO_CTRL_POP:
acdedc
+    default:
acdedc
+        ret = 0;
acdedc
+        break;
acdedc
+    }
acdedc
+    return ret;
acdedc
+}
acdedc
+
acdedc
+static int always_retry_gets(BIO *bio, char *buf, int size)
acdedc
+{
acdedc
+    BIO_set_retry_read(bio);
acdedc
+    return -1;
acdedc
+}
acdedc
+
acdedc
+static int always_retry_puts(BIO *bio, const char *str)
acdedc
+{
acdedc
+    BIO_set_retry_write(bio);
acdedc
+    return -1;
acdedc
+}
acdedc
+
acdedc
 int create_ssl_ctx_pair(const SSL_METHOD *sm, const SSL_METHOD *cm,
acdedc
                         int min_proto_version, int max_proto_version,
acdedc
                         SSL_CTX **sctx, SSL_CTX **cctx, char *certfile,
acdedc
diff --git a/test/ssltestlib.h b/test/ssltestlib.h
acdedc
index fa19e7d80d..56e323f5bc 100644
acdedc
--- a/test/ssltestlib.h
acdedc
+++ b/test/ssltestlib.h
acdedc
@@ -30,6 +30,9 @@ void bio_f_tls_dump_filter_free(void);
acdedc
 const BIO_METHOD *bio_s_mempacket_test(void);
acdedc
 void bio_s_mempacket_test_free(void);
acdedc
 
acdedc
+const BIO_METHOD *bio_s_always_retry(void);
acdedc
+void bio_s_always_retry_free(void);
acdedc
+
acdedc
 /* Packet types - value 0 is reserved */
acdedc
 #define INJECT_PACKET                   1
acdedc
 #define INJECT_PACKET_IGNORE_REC_SEQ    2
acdedc
-- 
acdedc
2.20.1
acdedc
067bfb
diff -up openssl-1.1.1c/include/internal/constant_time_locl.h.valgrind openssl-1.1.1c/include/internal/constant_time_locl.h
067bfb
--- openssl-1.1.1c/include/internal/constant_time_locl.h.valgrind	2019-05-28 15:12:21.000000000 +0200
067bfb
+++ openssl-1.1.1c/include/internal/constant_time_locl.h	2019-06-24 15:02:12.796053536 +0200
067bfb
@@ -213,18 +213,66 @@ static ossl_inline unsigned char constan
067bfb
     return constant_time_eq_8((unsigned)(a), (unsigned)(b));
067bfb
 }
067bfb
 
067bfb
+/* Returns the value unmodified, but avoids optimizations. */
067bfb
+static ossl_inline unsigned int value_barrier(unsigned int a)
067bfb
+{
067bfb
+#if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
067bfb
+    unsigned int r;
067bfb
+    __asm__("" : "=r"(r) : "0"(a));
067bfb
+#else
067bfb
+    volatile unsigned int r = a;
067bfb
+#endif
067bfb
+    return r;
067bfb
+}
067bfb
+
067bfb
+/* Convenience method for uint32_t. */
067bfb
+static ossl_inline uint32_t value_barrier_32(uint32_t a)
067bfb
+{
067bfb
+#if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
067bfb
+    uint32_t r;
067bfb
+    __asm__("" : "=r"(r) : "0"(a));
067bfb
+#else
067bfb
+    volatile uint32_t r = a;
067bfb
+#endif
067bfb
+    return r;
067bfb
+}
067bfb
+
067bfb
+/* Convenience method for uint64_t. */
067bfb
+static ossl_inline uint64_t value_barrier_64(uint64_t a)
067bfb
+{
067bfb
+#if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
067bfb
+    uint64_t r;
067bfb
+    __asm__("" : "=r"(r) : "0"(a));
067bfb
+#else
067bfb
+    volatile uint64_t r = a;
067bfb
+#endif
067bfb
+    return r;
067bfb
+}
067bfb
+
067bfb
+/* Convenience method for size_t. */
067bfb
+static ossl_inline size_t value_barrier_s(size_t a)
067bfb
+{
067bfb
+#if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
067bfb
+    size_t r;
067bfb
+    __asm__("" : "=r"(r) : "0"(a));
067bfb
+#else
067bfb
+    volatile size_t r = a;
067bfb
+#endif
067bfb
+    return r;
067bfb
+}
067bfb
+
067bfb
 static ossl_inline unsigned int constant_time_select(unsigned int mask,
067bfb
                                                      unsigned int a,
067bfb
                                                      unsigned int b)
067bfb
 {
067bfb
-    return (mask & a) | (~mask & b);
067bfb
+    return (value_barrier(mask) & a) | (value_barrier(~mask) & b);
067bfb
 }
067bfb
 
067bfb
 static ossl_inline size_t constant_time_select_s(size_t mask,
067bfb
                                                  size_t a,
067bfb
                                                  size_t b)
067bfb
 {
067bfb
-    return (mask & a) | (~mask & b);
067bfb
+    return (value_barrier_s(mask) & a) | (value_barrier_s(~mask) & b);
067bfb
 }
067bfb
 
067bfb
 static ossl_inline unsigned char constant_time_select_8(unsigned char mask,
067bfb
@@ -249,13 +297,13 @@ static ossl_inline int constant_time_sel
067bfb
 static ossl_inline uint32_t constant_time_select_32(uint32_t mask, uint32_t a,
067bfb
                                                     uint32_t b)
067bfb
 {
067bfb
-    return (mask & a) | (~mask & b);
067bfb
+    return (value_barrier_32(mask) & a) | (value_barrier_32(~mask) & b);
067bfb
 }
067bfb
 
067bfb
 static ossl_inline uint64_t constant_time_select_64(uint64_t mask, uint64_t a,
067bfb
                                                     uint64_t b)
067bfb
 {
067bfb
-    return (mask & a) | (~mask & b);
067bfb
+    return (value_barrier_64(mask) & a) | (value_barrier_64(~mask) & b);
067bfb
 }
067bfb
 
067bfb
 /*