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

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