File 0005-err-err.c-add-err_clear_last_constant_time.patch of Package openssl-1_0_0.21013

From 8db50d6dafc67fbaa0380420fc1f74f977d16606 Mon Sep 17 00:00:00 2001
From: Andy Polyakov <appro@openssl.org>
Date: Sat, 1 Sep 2018 12:19:30 +0200
Subject: [PATCH 1/5] err/err.c: add err_clear_last_constant_time.

Expected usage pattern is to unconditionally set error and then
wipe it if there was no actual error.

Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(cherry picked from commit f658a3b64d8750642f4975090740865f770c2a1b)

Resolved conflicts:
	crypto/err/err.c
	crypto/constant_time_locl.h

(Merged from https://github.com/openssl/openssl/pull/7737)
---
 crypto/constant_time_locl.h |  6 ++++++
 crypto/err/err.c            | 38 +++++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/crypto/constant_time_locl.h b/crypto/constant_time_locl.h
index c786aea949..a5734f2fec 100644
--- a/crypto/constant_time_locl.h
+++ b/crypto/constant_time_locl.h
@@ -204,6 +204,12 @@ static inline int constant_time_select_int(unsigned int mask, int a, int b)
     return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b)));
 }
 
+/*
+ * Expected usage pattern is to unconditionally set error and then
+ * wipe it if there was no actual error. |clear| is 1 or 0.
+ */
+void err_clear_last_constant_time(int clear);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/crypto/err/err.c b/crypto/err/err.c
index e9ef2156e1..5ce774a3f5 100644
--- a/crypto/err/err.c
+++ b/crypto/err/err.c
@@ -118,6 +118,7 @@
 #include <openssl/buffer.h>
 #include <openssl/bio.h>
 #include <openssl/err.h>
+#include "constant_time_locl.h"
 
 DECLARE_LHASH_OF(ERR_STRING_DATA);
 DECLARE_LHASH_OF(ERR_STATE);
@@ -1156,3 +1157,40 @@ int ERR_pop_to_mark(void)
     es->err_flags[es->top] &= ~ERR_FLAG_MARK;
     return 1;
 }
+
+#ifdef UINTPTR_T
+# undef UINTPTR_T
+#endif
+/*
+ * uintptr_t is the answer, but unformtunately we can't assume that all
+ * compilers supported by 1.0.2 have it :-(
+ */
+#if defined(OPENSSL_SYS_VMS) && __INITIAL_POINTER_SIZE==64
+/*
+ * But we can't use size_t on VMS, because it adheres to sizeof(size_t)==4
+ * even in 64-bit builds, which means that it won't work as mask.
+ */
+# define UINTPTR_T unsigned long long
+#else
+# define UINTPTR_T size_t
+#endif
+
+void err_clear_last_constant_time(int clear)
+{
+    ERR_STATE *es;
+    int top;
+
+    es = ERR_get_state();
+    if (es == NULL)
+        return;
+
+    top = es->top;
+
+    es->err_flags[top] &= ~(0 - clear);
+    es->err_buffer[top] &= ~(0UL - clear);
+    es->err_file[top] = (const char *)((UINTPTR_T)es->err_file[top] &
+                                       ~((UINTPTR_T)0 - clear));
+    es->err_line[top] |= 0 - clear;
+
+    es->top = (top + ERR_NUM_ERRORS - clear) % ERR_NUM_ERRORS;
+}
-- 
2.20.1

openSUSE Build Service is sponsored by