summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatthew <>2014-06-19 00:13:22 +0000
committermatthew <>2014-06-19 00:13:22 +0000
commit621a34760179b1387de8337f525f1c9dedf54fad (patch)
tree8d5a4c9f2628f7ba9b7a476867a2fa97f9a4b63b
parentea52171d7ee0bb85a996dc2021440e122bf0357d (diff)
downloadopenbsd-621a34760179b1387de8337f525f1c9dedf54fad.tar.gz
openbsd-621a34760179b1387de8337f525f1c9dedf54fad.tar.bz2
openbsd-621a34760179b1387de8337f525f1c9dedf54fad.zip
Move rs_chacha and rs_buf into the same memory page and don't mark it
MAP_INHERIT_ZERO anymore. This restores arc4random's previous behavior where fork children would mix in some randomness from the parent process. New behavior noticed by deraadt ok deraadt, tedu
-rw-r--r--src/lib/libc/crypt/arc4random.c53
1 files changed, 31 insertions, 22 deletions
diff --git a/src/lib/libc/crypt/arc4random.c b/src/lib/libc/crypt/arc4random.c
index 03eb047f98..985fa8a0e5 100644
--- a/src/lib/libc/crypt/arc4random.c
+++ b/src/lib/libc/crypt/arc4random.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: arc4random.c,v 1.34 2014/06/17 00:37:07 matthew Exp $ */ 1/* $OpenBSD: arc4random.c,v 1.35 2014/06/19 00:13:22 matthew Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996, David Mazieres <dm@uun.org> 4 * Copyright (c) 1996, David Mazieres <dm@uun.org>
@@ -49,12 +49,17 @@
49#define BLOCKSZ 64 49#define BLOCKSZ 64
50#define RSBUFSZ (16*BLOCKSZ) 50#define RSBUFSZ (16*BLOCKSZ)
51 51
52/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */
52static struct { 53static struct {
53 size_t rs_have; /* valid bytes at end of rs_buf */ 54 size_t rs_have; /* valid bytes at end of rs_buf */
54 size_t rs_count; /* bytes till reseed */ 55 size_t rs_count; /* bytes till reseed */
55 chacha_ctx rs_chacha; /* chacha context for random keystream */
56} *rs; 56} *rs;
57static u_char *rs_buf; /* keystream blocks */ 57
58/* Preserved in fork children. */
59static struct {
60 chacha_ctx rs_chacha; /* chacha context for random keystream */
61 u_char rs_buf[RSBUFSZ]; /* keystream blocks */
62} *rsx;
58 63
59static inline void _rs_rekey(u_char *dat, size_t datlen); 64static inline void _rs_rekey(u_char *dat, size_t datlen);
60 65
@@ -66,21 +71,19 @@ _rs_init(u_char *buf, size_t n)
66 71
67 if (rs == NULL) { 72 if (rs == NULL) {
68 if ((rs = mmap(NULL, sizeof(*rs), PROT_READ|PROT_WRITE, 73 if ((rs = mmap(NULL, sizeof(*rs), PROT_READ|PROT_WRITE,
69 MAP_ANON, -1, 0)) == MAP_FAILED) 74 MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
70 abort(); 75 abort();
71 if (minherit(rs, sizeof(*rs), MAP_INHERIT_ZERO) == -1) 76 if (minherit(rs, sizeof(*rs), MAP_INHERIT_ZERO) == -1)
72 abort(); 77 abort();
73 } 78 }
74 if (rs_buf == NULL) { 79 if (rsx == NULL) {
75 if ((rs_buf = mmap(NULL, RSBUFSZ, PROT_READ|PROT_WRITE, 80 if ((rsx = mmap(NULL, sizeof(*rsx), PROT_READ|PROT_WRITE,
76 MAP_ANON, -1, 0)) == MAP_FAILED) 81 MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
77 abort();
78 if (minherit(rs_buf, RSBUFSZ, MAP_INHERIT_ZERO) == -1)
79 abort(); 82 abort();
80 } 83 }
81 84
82 chacha_keysetup(&rs->rs_chacha, buf, KEYSZ * 8, 0); 85 chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8, 0);
83 chacha_ivsetup(&rs->rs_chacha, buf + KEYSZ); 86 chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ);
84} 87}
85 88
86static void 89static void
@@ -99,7 +102,7 @@ _rs_stir(void)
99 102
100 /* invalidate rs_buf */ 103 /* invalidate rs_buf */
101 rs->rs_have = 0; 104 rs->rs_have = 0;
102 memset(rs_buf, 0, RSBUFSZ); 105 memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
103 106
104 rs->rs_count = 1600000; 107 rs->rs_count = 1600000;
105} 108}
@@ -119,36 +122,40 @@ static inline void
119_rs_rekey(u_char *dat, size_t datlen) 122_rs_rekey(u_char *dat, size_t datlen)
120{ 123{
121#ifndef KEYSTREAM_ONLY 124#ifndef KEYSTREAM_ONLY
122 memset(rs_buf, 0,RSBUFSZ); 125 memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
123#endif 126#endif
124 /* fill rs_buf with the keystream */ 127 /* fill rs_buf with the keystream */
125 chacha_encrypt_bytes(&rs->rs_chacha, rs_buf, rs_buf, RSBUFSZ); 128 chacha_encrypt_bytes(&rsx->rs_chacha, rsx->rs_buf,
129 rsx->rs_buf, sizeof(rsx->rs_buf));
126 /* mix in optional user provided data */ 130 /* mix in optional user provided data */
127 if (dat) { 131 if (dat) {
128 size_t i, m; 132 size_t i, m;
129 133
130 m = MIN(datlen, KEYSZ + IVSZ); 134 m = MIN(datlen, KEYSZ + IVSZ);
131 for (i = 0; i < m; i++) 135 for (i = 0; i < m; i++)
132 rs_buf[i] ^= dat[i]; 136 rsx->rs_buf[i] ^= dat[i];
133 } 137 }
134 /* immediately reinit for backtracking resistance */ 138 /* immediately reinit for backtracking resistance */
135 _rs_init(rs_buf, KEYSZ + IVSZ); 139 _rs_init(rsx->rs_buf, KEYSZ + IVSZ);
136 memset(rs_buf, 0, KEYSZ + IVSZ); 140 memset(rsx->rs_buf, 0, KEYSZ + IVSZ);
137 rs->rs_have = RSBUFSZ - KEYSZ - IVSZ; 141 rs->rs_have = sizeof(rsx->rs_buf) - KEYSZ - IVSZ;
138} 142}
139 143
140static inline void 144static inline void
141_rs_random_buf(void *_buf, size_t n) 145_rs_random_buf(void *_buf, size_t n)
142{ 146{
143 u_char *buf = (u_char *)_buf; 147 u_char *buf = (u_char *)_buf;
148 u_char *keystream;
144 size_t m; 149 size_t m;
145 150
146 _rs_stir_if_needed(n); 151 _rs_stir_if_needed(n);
147 while (n > 0) { 152 while (n > 0) {
148 if (rs->rs_have > 0) { 153 if (rs->rs_have > 0) {
149 m = MIN(n, rs->rs_have); 154 m = MIN(n, rs->rs_have);
150 memcpy(buf, rs_buf + RSBUFSZ - rs->rs_have, m); 155 keystream = rsx->rs_buf + sizeof(rsx->rs_buf)
151 memset(rs_buf + RSBUFSZ - rs->rs_have, 0, m); 156 - rs->rs_have;
157 memcpy(buf, keystream, m);
158 memset(keystream, 0, m);
152 buf += m; 159 buf += m;
153 n -= m; 160 n -= m;
154 rs->rs_have -= m; 161 rs->rs_have -= m;
@@ -161,11 +168,13 @@ _rs_random_buf(void *_buf, size_t n)
161static inline void 168static inline void
162_rs_random_u32(u_int32_t *val) 169_rs_random_u32(u_int32_t *val)
163{ 170{
171 u_char *keystream;
164 _rs_stir_if_needed(sizeof(*val)); 172 _rs_stir_if_needed(sizeof(*val));
165 if (rs->rs_have < sizeof(*val)) 173 if (rs->rs_have < sizeof(*val))
166 _rs_rekey(NULL, 0); 174 _rs_rekey(NULL, 0);
167 memcpy(val, rs_buf + RSBUFSZ - rs->rs_have, sizeof(*val)); 175 keystream = rsx->rs_buf + sizeof(rsx->rs_buf) - rs->rs_have;
168 memset(rs_buf + RSBUFSZ - rs->rs_have, 0, sizeof(*val)); 176 memcpy(val, keystream, sizeof(*val));
177 memset(keystream, 0, sizeof(*val));
169 rs->rs_have -= sizeof(*val); 178 rs->rs_have -= sizeof(*val);
170} 179}
171 180