aboutsummaryrefslogtreecommitdiff
path: root/openssl-freefilesync/openssl-1.1.1-fips-post-rand.patch
blob: fc60e33e0db117fe01cb4d5b0e9068ae9f31805d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
diff -up openssl-1.1.1c/crypto/fips/fips.c.fips-post-rand openssl-1.1.1c/crypto/fips/fips.c
--- openssl-1.1.1c/crypto/fips/fips.c.fips-post-rand	2019-05-29 15:53:56.328216002 +0200
+++ openssl-1.1.1c/crypto/fips/fips.c	2019-05-29 15:53:56.359215457 +0200
@@ -68,6 +68,7 @@
 
 # include <openssl/fips.h>
 # include "internal/thread_once.h"
+# include "internal/rand_int.h"
 
 # ifndef PATH_MAX
 #  define PATH_MAX 1024
@@ -76,6 +77,7 @@
 static int fips_selftest_fail = 0;
 static int fips_mode = 0;
 static int fips_started = 0;
+static int fips_post = 0;
 
 static int fips_is_owning_thread(void);
 static int fips_set_owning_thread(void);
@@ -158,6 +160,11 @@ void fips_set_selftest_fail(void)
     fips_selftest_fail = 1;
 }
 
+int fips_in_post(void)
+{
+    return fips_post;
+}
+
 /* we implement what libfipscheck does ourselves */
 
 static int
@@ -445,6 +452,8 @@ int FIPS_module_mode_set(int onoff)
         }
 # endif
 
+        fips_post = 1;
+
         if (!FIPS_selftest()) {
             fips_selftest_fail = 1;
             ret = 0;
@@ -459,7 +468,12 @@ int FIPS_module_mode_set(int onoff)
             goto end;
         }
 
+        fips_post = 0;
+
         fips_set_mode(onoff);
+        /* force RNG reseed with entropy from getrandom() on next call */
+        rand_fork();
+
         ret = 1;
         goto end;
     }
diff -up openssl-1.1.1c/crypto/include/internal/fips_int.h.fips-post-rand openssl-1.1.1c/crypto/include/internal/fips_int.h
--- openssl-1.1.1c/crypto/include/internal/fips_int.h.fips-post-rand	2019-05-29 15:53:56.337215844 +0200
+++ openssl-1.1.1c/crypto/include/internal/fips_int.h	2019-05-29 15:53:56.359215457 +0200
@@ -77,6 +77,8 @@ int FIPS_selftest_hmac(void);
 int FIPS_selftest_drbg(void);
 int FIPS_selftest_cmac(void);
 
+int fips_in_post(void);
+
 int fips_pkey_signature_test(EVP_PKEY *pkey,
                                  const unsigned char *tbs, int tbslen,
                                  const unsigned char *kat,
diff -up openssl-1.1.1c/crypto/rand/rand_unix.c.fips-post-rand openssl-1.1.1c/crypto/rand/rand_unix.c
--- openssl-1.1.1c/crypto/rand/rand_unix.c.fips-post-rand	2019-05-28 15:12:21.000000000 +0200
+++ openssl-1.1.1c/crypto/rand/rand_unix.c	2019-05-29 16:54:16.471391802 +0200
@@ -16,10 +16,12 @@
 #include <openssl/rand.h>
 #include "rand_lcl.h"
 #include "internal/rand_int.h"
+#include "internal/fips_int.h"
 #include <stdio.h>
 #include "internal/dso.h"
 #if defined(__linux)
-# include <asm/unistd.h>
+# include <sys/syscall.h>
+# include <sys/random.h>
 #endif
 #if defined(__FreeBSD__)
 # include <sys/types.h>
@@ -279,7 +281,7 @@ static ssize_t sysctl_random(char *buf,
  * syscall_random(): Try to get random data using a system call
  * returns the number of bytes returned in buf, or < 0 on error.
  */
-static ssize_t syscall_random(void *buf, size_t buflen)
+static ssize_t syscall_random(void *buf, size_t buflen, int nonblock)
 {
     /*
      * Note: 'buflen' equals the size of the buffer which is used by the
@@ -301,6 +303,7 @@ static ssize_t syscall_random(void *buf,
      * - Linux since 3.17 with glibc 2.25
      * - FreeBSD since 12.0 (1200061)
      */
+#  if 0
 #  if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) && !defined(__hpux)
     extern int getentropy(void *buffer, size_t length) __attribute__((weak));
 
@@ -322,10 +325,10 @@ static ssize_t syscall_random(void *buf,
     if (p_getentropy.p != NULL)
         return p_getentropy.f(buf, buflen) == 0 ? (ssize_t)buflen : -1;
 #  endif
-
+#  endif
     /* Linux supports this since version 3.17 */
-#  if defined(__linux) && defined(__NR_getrandom)
-    return syscall(__NR_getrandom, buf, buflen, 0);
+#  if defined(__linux) && defined(SYS_getrandom)
+    return syscall(SYS_getrandom, buf, buflen, nonblock?GRND_NONBLOCK:0);
 #  elif (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(KERN_ARND)
     return sysctl_random(buf, buflen);
 #  else
@@ -475,8 +478,10 @@ size_t rand_pool_acquire_entropy(RAND_PO
     size_t bytes_needed;
     size_t entropy_available = 0;
     unsigned char *buffer;
-
 #   if defined(OPENSSL_RAND_SEED_GETRANDOM)
+    int in_post;
+
+    for (in_post = fips_in_post(); in_post >= 0; --in_post) {
     {
         ssize_t bytes;
         /* Maximum allowed number of consecutive unsuccessful attempts */
@@ -485,7 +490,7 @@ size_t rand_pool_acquire_entropy(RAND_PO
         bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
         while (bytes_needed != 0 && attempts-- > 0) {
             buffer = rand_pool_add_begin(pool, bytes_needed);
-            bytes = syscall_random(buffer, bytes_needed);
+            bytes = syscall_random(buffer, bytes_needed, in_post);
             if (bytes > 0) {
                 rand_pool_add_end(pool, bytes, 8 * bytes);
                 bytes_needed -= bytes;
@@ -540,8 +545,10 @@ size_t rand_pool_acquire_entropy(RAND_PO
             int attempts = 3;
             const int fd = get_random_device(i);
 
-            if (fd == -1)
+            if (fd == -1) {
+                OPENSSL_showfatal("Random device %s cannot be opened.\n", random_device_paths[i]);
                 continue;
+            }
 
             while (bytes_needed != 0 && attempts-- > 0) {
                 buffer = rand_pool_add_begin(pool, bytes_needed);
@@ -601,7 +608,9 @@ size_t rand_pool_acquire_entropy(RAND_PO
         }
     }
 #   endif
-
+#   ifdef OPENSSL_RAND_SEED_GETRANDOM
+    }
+#   endif
     return rand_pool_entropy_available(pool);
 #  endif
 }
bgstack15