Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/ttssh2/ttxssh/arc4random.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10261 - (show annotations) (download) (as text)
Sun Sep 11 05:26:32 2022 UTC (20 months, 2 weeks ago) by nmaya
File MIME type: text/x-csrc
File size: 5140 byte(s)
OpenSSL のときだけ arc4random.c/h と chacha.c/h が使われるようにした

- LibreSSL のときは compat/stdlib.h を include し LibreSSL の関数を利用する

- RAND_bytes() を呼ぶと LibreSSL の crypto/rand/rand_lib.c の RAND_bytes()
から TTSSH の arc4random.c の arc4random_buf() が呼ばれる状態を解消
1 /* OPENBSD ORIGINAL: lib/libc/crypto/arc4random.c */
2
3 /* $OpenBSD: arc4random.c,v 1.31 2014/05/31 10:32:12 jca Exp $ */
4
5 /*
6 * Copyright (c) 1996, David Mazieres <dm@uun.org>
7 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
8 * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
9 *
10 * Permission to use, copy, modify, and distribute this software for any
11 * purpose with or without fee is hereby granted, provided that the above
12 * copyright notice and this permission notice appear in all copies.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 */
22
23 /*
24 * ChaCha based random number generator for OpenBSD.
25 * openssh-portable: openbsd-compat/arc4random.c
26 */
27
28 /*
29 * with LibreSSL, use getentropy() instead of RAND_bytes().
30 * OpenBSD: lib/libcrypto/arc4random/getentropy_win.c
31 * $OpenBSD: getentropy_win.c,v 1.6 2020/11/11 10:41:24 bcook Exp $
32 */
33
34
35 #include <sys/types.h>
36
37 #include <stdlib.h>
38 #include <string.h>
39 #include <process.h>
40
41 #define KEYSTREAM_ONLY
42 #include "ttxssh.h"
43
44 /*
45 * �����\�[�X�� OpenSSL �����������g������
46 * LibreSSL �������� libressl/crypto/compat/arc4random.c,
47 * crypto/compat/getentropy_win.c ���g������
48 */
49 #ifndef LIBRESSL_VERSION_NUMBER
50
51 #include "arc4random.h"
52 #include "chacha.h"
53
54 #ifndef LIBRESSL_VERSION_NUMBER
55 #include <openssl/rand.h>
56 #include <openssl/err.h>
57 #else
58 #include <bcrypt.h>
59 #endif
60
61 /* OpenSSH isn't multithreaded */
62 #define _ARC4_LOCK()
63 #define _ARC4_UNLOCK()
64
65 #define KEYSZ 32
66 #define IVSZ 8
67 #define BLOCKSZ 64
68 #define RSBUFSZ (16*BLOCKSZ)
69 static int rs_initialized;
70 static int rs_stir_pid;
71 static struct chacha_ctx rs; /* chacha context for random keystream */
72 static u_char rs_buf[RSBUFSZ]; /* keystream blocks */
73 static size_t rs_have; /* valid bytes at end of rs_buf */
74 static size_t rs_count; /* bytes till reseed */
75
76 static void _rs_rekey(u_char *dat, size_t datlen);
77
78 static void
79 _rs_init(u_char *buf, size_t n)
80 {
81 if (n < KEYSZ + IVSZ)
82 return;
83 chacha_keysetup(&rs, buf, KEYSZ * 8);
84 chacha_ivsetup(&rs, buf + KEYSZ, NULL);
85 }
86
87 #ifdef LIBRESSL_VERSION_NUMBER
88 /*
89 * On Windows, BCryptGenRandom with BCRYPT_USE_SYSTEM_PREFERRED_RNG is supposed
90 * to be a well-seeded, cryptographically strong random number generator.
91 * https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
92 */
93 static int
94 getentropy(void *buf, size_t len)
95 {
96 if (len > 256) {
97 return (-1);
98 }
99
100 if (FAILED(BCryptGenRandom(NULL, buf, len, BCRYPT_USE_SYSTEM_PREFERRED_RNG))) {
101 return (-1);
102 }
103
104 return (0);
105 }
106 #endif /* LIBRESSL_VERSION_NUMBER */
107
108 static void
109 _rs_stir(void)
110 {
111 u_char rnd[KEYSZ + IVSZ];
112
113 #ifndef LIBRESSL_VERSION_NUMBER
114 if (RAND_bytes(rnd, sizeof(rnd)) <= 0) {
115 return;
116 }
117 #else
118 if (getentropy(rnd, sizeof(rnd)) == -1) {
119 return;
120 }
121 #endif
122
123 if (!rs_initialized) {
124 rs_initialized = 1;
125 _rs_init(rnd, sizeof(rnd));
126 } else
127 _rs_rekey(rnd, sizeof(rnd));
128 SecureZeroMemory(rnd, sizeof(rnd));
129
130 /* invalidate rs_buf */
131 rs_have = 0;
132 memset(rs_buf, 0, RSBUFSZ);
133
134 rs_count = 1600000;
135 }
136
137 static void
138 _rs_stir_if_needed(size_t len)
139 {
140 int pid = _getpid();
141
142 if (rs_count <= len || !rs_initialized || rs_stir_pid != pid) {
143 rs_stir_pid = pid;
144 _rs_stir();
145 } else
146 rs_count -= len;
147 }
148
149 static void
150 _rs_rekey(u_char *dat, size_t datlen)
151 {
152 #ifndef KEYSTREAM_ONLY
153 memset(rs_buf, 0,RSBUFSZ);
154 #endif
155 /* fill rs_buf with the keystream */
156 chacha_encrypt_bytes(&rs, rs_buf, rs_buf, RSBUFSZ);
157 /* mix in optional user provided data */
158 if (dat) {
159 size_t i, m;
160
161 m = MIN(datlen, KEYSZ + IVSZ);
162 for (i = 0; i < m; i++)
163 rs_buf[i] ^= dat[i];
164 }
165 /* immediately reinit for backtracking resistance */
166 _rs_init(rs_buf, KEYSZ + IVSZ);
167 memset(rs_buf, 0, KEYSZ + IVSZ);
168 rs_have = RSBUFSZ - KEYSZ - IVSZ;
169 }
170
171 static void
172 _rs_random_buf(void *_buf, size_t n)
173 {
174 u_char *buf = (u_char *)_buf;
175 size_t m;
176
177 _rs_stir_if_needed(n);
178 while (n > 0) {
179 if (rs_have > 0) {
180 m = MIN(n, rs_have);
181 memcpy(buf, rs_buf + RSBUFSZ - rs_have, m);
182 memset(rs_buf + RSBUFSZ - rs_have, 0, m);
183 buf += m;
184 n -= m;
185 rs_have -= m;
186 }
187 if (rs_have == 0)
188 _rs_rekey(NULL, 0);
189 }
190 }
191
192 static void
193 _rs_random_u32(uint32 *val)
194 {
195 _rs_stir_if_needed(sizeof(*val));
196 if (rs_have < sizeof(*val))
197 _rs_rekey(NULL, 0);
198 memcpy(val, rs_buf + RSBUFSZ - rs_have, sizeof(*val));
199 memset(rs_buf + RSBUFSZ - rs_have, 0, sizeof(*val));
200 rs_have -= sizeof(*val);
201 }
202
203 uint32
204 arc4random(void)
205 {
206 uint32 val;
207
208 _ARC4_LOCK();
209 _rs_random_u32(&val);
210 _ARC4_UNLOCK();
211 return val;
212 }
213
214 /*
215 * If we are providing arc4random, then we can provide a more efficient
216 * arc4random_buf().
217 */
218 void
219 arc4random_buf(void *buf, size_t n)
220 {
221 _ARC4_LOCK();
222 _rs_random_buf(buf, n);
223 _ARC4_UNLOCK();
224 }
225
226 #endif /* LIBRESSL_VERSION_NUMBER */

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26