summaryrefslogtreecommitdiffstats
path: root/Don-t-feed-OS-RNG-output-into-the-OS-RNG.patch
blob: 3467adf4aeb817dfb1bde007e9a9c581b40c8ccb (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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
From dd0c141bfc858caa8470271205220a968db7ab51 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Mon, 12 Sep 2016 12:25:05 -0400
Subject: [PATCH] Don't feed OS RNG output into the OS RNG

krb5_c_random_os_entropy() now must be provided by PRNG modules.

ticket: 8499
(cherry picked from commit 0bbbc2bd3a42cfbd9e6eb34c273da8aaa077c29f)
---
 src/lib/crypto/krb/crypto_int.h   |  3 +-
 src/lib/crypto/krb/prng.c         | 60 +++++----------------------------------
 src/lib/crypto/krb/prng_fortuna.c | 26 ++++++++++++++++-
 src/lib/crypto/krb/prng_os.c      |  6 ++++
 4 files changed, 40 insertions(+), 55 deletions(-)

diff --git a/src/lib/crypto/krb/crypto_int.h b/src/lib/crypto/krb/crypto_int.h
index c054144..a205e3f 100644
--- a/src/lib/crypto/krb/crypto_int.h
+++ b/src/lib/crypto/krb/crypto_int.h
@@ -508,6 +508,7 @@ void krb5int_crypto_impl_cleanup(void);
  * PRNG modules must implement the following APIs from krb5.h:
  *   krb5_c_random_add_entropy
  *   krb5_c_random_make_octets
+ *   krb5_c_random_os_entropy
  *
  * PRNG modules should implement these functions.  They are called from the
  * crypto library init and cleanup functions, and can be used to setup and tear
@@ -517,7 +518,7 @@ int k5_prng_init(void);
 void k5_prng_cleanup(void);
 
 /* Used by PRNG modules to gather OS entropy.  Returns true on success. */
-krb5_boolean k5_get_os_entropy(unsigned char *buf, size_t len);
+krb5_boolean k5_get_os_entropy(unsigned char *buf, size_t len, int strong);
 
 /*** Inline helper functions ***/
 
diff --git a/src/lib/crypto/krb/prng.c b/src/lib/crypto/krb/prng.c
index e478b19..9ad24c1 100644
--- a/src/lib/crypto/krb/prng.c
+++ b/src/lib/crypto/krb/prng.c
@@ -36,11 +36,13 @@ krb5_c_random_seed(krb5_context context, krb5_data *data)
 #if defined(_WIN32)
 
 krb5_boolean
-k5_get_os_entropy(unsigned char *buf, size_t len)
+k5_get_os_entropy(unsigned char *buf, size_t len, int strong)
 {
     krb5_boolean result;
     HCRYPTPROV provider;
 
+    /* CryptGenRandom is always considered strong. */
+
     if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
                              CRYPT_VERIFYCONTEXT))
         return FALSE;
@@ -49,22 +51,6 @@ k5_get_os_entropy(unsigned char *buf, size_t len)
     return result;
 }
 
-krb5_error_code KRB5_CALLCONV
-krb5_c_random_os_entropy(krb5_context context, int strong, int *success)
-{
-    int oursuccess = 0;
-    char buf[1024];
-    krb5_data data = make_data(buf, sizeof(buf));
-
-    if (k5_get_os_entropy(buf, sizeof(buf)) &&
-        krb5_c_random_add_entropy(context, KRB5_C_RANDSOURCE_OSRAND,
-                                  &data) == 0)
-        oursuccess = 1;
-    if (success != NULL)
-        *success = oursuccess;
-    return 0;
-}
-
 #else /* not Windows */
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
@@ -107,44 +93,12 @@ cleanup:
 }
 
 krb5_boolean
-k5_get_os_entropy(unsigned char *buf, size_t len)
+k5_get_os_entropy(unsigned char *buf, size_t len, int strong)
 {
-    return read_entropy_from_device("/dev/urandom", buf, len);
-}
+    const char *device;
 
-/* Read entropy from device and contribute it to the PRNG.  Returns true on
- * success. */
-static krb5_boolean
-add_entropy_from_device(krb5_context context, const char *device)
-{
-    krb5_data data;
-    unsigned char buf[64];
-
-    if (!read_entropy_from_device(device, buf, sizeof(buf)))
-        return FALSE;
-    data = make_data(buf, sizeof(buf));
-    return (krb5_c_random_add_entropy(context, KRB5_C_RANDSOURCE_OSRAND,
-                                      &data) == 0);
-}
-
-krb5_error_code KRB5_CALLCONV
-krb5_c_random_os_entropy(krb5_context context, int strong, int *success)
-{
-    int unused;
-    int *oursuccess = (success != NULL) ? success : &unused;
-
-    *oursuccess = 0;
-    /* If we are getting strong data then try that first.  We are
-       guaranteed to cause a reseed of some kind if strong is true and
-       we have both /dev/random and /dev/urandom.  We want the strong
-       data included in the reseed so we get it first.*/
-    if (strong) {
-        if (add_entropy_from_device(context, "/dev/random"))
-            *oursuccess = 1;
-    }
-    if (add_entropy_from_device(context, "/dev/urandom"))
-        *oursuccess = 1;
-    return 0;
+    device = strong ? "/dev/random" : "/dev/urandom";
+    return read_entropy_from_device(device, buf, len);
 }
 
 #endif /* not Windows */
diff --git a/src/lib/crypto/krb/prng_fortuna.c b/src/lib/crypto/krb/prng_fortuna.c
index e70ffa3..017a119 100644
--- a/src/lib/crypto/krb/prng_fortuna.c
+++ b/src/lib/crypto/krb/prng_fortuna.c
@@ -366,7 +366,7 @@ k5_prng_init(void)
 #else
     last_pid = getpid();
 #endif
-    if (k5_get_os_entropy(osbuf, sizeof(osbuf))) {
+    if (k5_get_os_entropy(osbuf, sizeof(osbuf), 0)) {
         generator_reseed(&main_state, osbuf, sizeof(osbuf));
         have_entropy = TRUE;
     }
@@ -443,4 +443,28 @@ krb5_c_random_make_octets(krb5_context context, krb5_data *outdata)
     return 0;
 }
 
+krb5_error_code KRB5_CALLCONV
+krb5_c_random_os_entropy(krb5_context context, int strong, int *success)
+{
+    krb5_error_code ret;
+    krb5_data data;
+    uint8_t buf[64];
+    int status = 0;
+
+    if (!k5_get_os_entropy(buf, sizeof(buf), strong))
+        goto done;
+
+    data = make_data(buf, sizeof(buf));
+    ret = krb5_c_random_add_entropy(context, KRB5_C_RANDSOURCE_OSRAND, &data);
+    if (ret)
+        goto done;
+
+    status = 1;
+
+done:
+    if (success != NULL)
+        *success = status;
+    return 0;
+}
+
 #endif /* not TEST */
diff --git a/src/lib/crypto/krb/prng_os.c b/src/lib/crypto/krb/prng_os.c
index 730ed2e..ecfe351 100644
--- a/src/lib/crypto/krb/prng_os.c
+++ b/src/lib/crypto/krb/prng_os.c
@@ -91,3 +91,9 @@ krb5_c_random_make_octets(krb5_context context, krb5_data *outdata)
     }
     return 0;
 }
+
+krb5_error_code KRB5_CALLCONV
+krb5_c_random_os_entropy(krb5_context context, int strong, int *success)
+{
+    return 0;
+}
-- 
2.9.3