LibreSSL に対応
- OpenSSL 1.1 に移行したときに OpenSSL の関数に置き換えた EVP_CIPHER_meth_ で始まる関数が LibreSSL にはないため、元に戻した。
- LibreSSL の RAND_bytes() の中で落ちるので、BCryptGenRandom() を使うようにした
@@ -10,7 +10,7 @@ | ||
10 | 10 | exit /b 1 |
11 | 11 | ) |
12 | 12 | |
13 | -CALL buildopenssl11.bat | |
13 | +CALL buildlibressl.bat | |
14 | 14 | if ERRORLEVEL 1 ( |
15 | 15 | echo "buildall.bat を終了します" |
16 | 16 | exit /b 1 |
@@ -0,0 +1,18 @@ | ||
1 | +rem LibreSSLのビルド | |
2 | + | |
3 | +cd libressl | |
4 | + | |
5 | + | |
6 | +cmake -G "Visual Studio 16 2019" -A Win32 | |
7 | +perl -e "open(IN,'CMakeCache.txt');while(<IN>){s|=/MD|=/MT|;print $_;}close(IN);" > CMakeCache.txt.tmp | |
8 | +move /y CMakeCache.txt.tmp CMakeCache.txt | |
9 | +rem 変更した CMakeCache.txt に基づいて生成されるように再度実行 | |
10 | +cmake -G "Visual Studio 16 2019" -A Win32 | |
11 | + | |
12 | +devenv /build Debug LibreSSL.sln /project crypto /projectconfig Debug | |
13 | + | |
14 | +devenv /build Release LibreSSL.sln /project crypto /projectconfig Release | |
15 | + | |
16 | + | |
17 | +cd .. | |
18 | +exit /b 0 |
@@ -22,8 +22,16 @@ | ||
22 | 22 | |
23 | 23 | /* |
24 | 24 | * ChaCha based random number generator for OpenBSD. |
25 | + * openssh-portable: openbsd-compat/arc4random.c | |
25 | 26 | */ |
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 | + | |
27 | 35 | #include <sys/types.h> |
28 | 36 | |
29 | 37 | #include <stdlib.h> |
@@ -35,8 +43,12 @@ | ||
35 | 43 | #include "arc4random.h" |
36 | 44 | #include "chacha.h" |
37 | 45 | |
46 | +#ifndef LIBRESSL_VERSION_NUMBER | |
38 | 47 | #include <openssl/rand.h> |
39 | 48 | #include <openssl/err.h> |
49 | +#else | |
50 | +#include <bcrypt.h> | |
51 | +#endif | |
40 | 52 | |
41 | 53 | /* OpenSSH isn't multithreaded */ |
42 | 54 | #define _ARC4_LOCK() |
@@ -64,14 +76,41 @@ | ||
64 | 76 | chacha_ivsetup(&rs, buf + KEYSZ, NULL); |
65 | 77 | } |
66 | 78 | |
79 | +#ifdef LIBRESSL_VERSION_NUMBER | |
80 | +/* | |
81 | + * On Windows, BCryptGenRandom with BCRYPT_USE_SYSTEM_PREFERRED_RNG is supposed | |
82 | + * to be a well-seeded, cryptographically strong random number generator. | |
83 | + * https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom | |
84 | + */ | |
85 | +static int | |
86 | +getentropy(void *buf, size_t len) | |
87 | +{ | |
88 | + if (len > 256) { | |
89 | + return (-1); | |
90 | + } | |
91 | + | |
92 | + if (FAILED(BCryptGenRandom(NULL, buf, len, BCRYPT_USE_SYSTEM_PREFERRED_RNG))) { | |
93 | + return (-1); | |
94 | + } | |
95 | + | |
96 | + return (0); | |
97 | +} | |
98 | +#endif /* LIBRESSL_VERSION_NUMBER */ | |
99 | + | |
67 | 100 | static void |
68 | 101 | _rs_stir(void) |
69 | 102 | { |
70 | 103 | u_char rnd[KEYSZ + IVSZ]; |
71 | 104 | |
105 | +#ifndef LIBRESSL_VERSION_NUMBER | |
72 | 106 | if (RAND_bytes(rnd, sizeof(rnd)) <= 0) { |
73 | 107 | return; |
74 | 108 | } |
109 | +#else | |
110 | + if (getentropy(rnd, sizeof(rnd)) <= 0) { | |
111 | + return; | |
112 | + } | |
113 | +#endif | |
75 | 114 | |
76 | 115 | if (!rs_initialized) { |
77 | 116 | rs_initialized = 1; |
@@ -52,7 +52,6 @@ | ||
52 | 52 | }; |
53 | 53 | |
54 | 54 | const EVP_CIPHER * evp_ssh1_3des(void); |
55 | -int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); | |
56 | 55 | |
57 | 56 | static int ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, int enc) |
58 | 57 | { |
@@ -124,49 +123,18 @@ | ||
124 | 123 | return 1; |
125 | 124 | } |
126 | 125 | |
127 | -// ssh1_3des_iv は未使用。 | |
128 | -int ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len) | |
129 | -{ | |
130 | - struct ssh1_3des_ctx *c; | |
131 | - | |
132 | - if (len != 24) { | |
133 | - //fatal("%s: bad 3des iv length: %d", __func__, len); | |
134 | - return SSH_ERR_INVALID_ARGUMENT; | |
135 | - } | |
136 | - | |
137 | - if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) { | |
138 | - //fatal("%s: no 3des context", __func__); | |
139 | - return SSH_ERR_INTERNAL_ERROR; | |
140 | - } | |
141 | - | |
142 | - if (doset) { | |
143 | - //debug3("%s: Installed 3DES IV", __func__); | |
144 | - memcpy(EVP_CIPHER_CTX_iv_noconst(c->k1), iv, 8); | |
145 | - memcpy(EVP_CIPHER_CTX_iv_noconst(c->k2), iv + 8, 8); | |
146 | - memcpy(EVP_CIPHER_CTX_iv_noconst(c->k3), iv + 16, 8); | |
147 | - } else { | |
148 | - //debug3("%s: Copying 3DES IV", __func__); | |
149 | - memcpy(iv, EVP_CIPHER_CTX_iv(c->k1), 8); | |
150 | - memcpy(iv + 8, EVP_CIPHER_CTX_iv(c->k2), 8); | |
151 | - memcpy(iv + 16, EVP_CIPHER_CTX_iv(c->k3), 8); | |
152 | - } | |
153 | - return 0; | |
154 | -} | |
155 | - | |
156 | 126 | const EVP_CIPHER *evp_ssh1_3des(void) |
157 | 127 | { |
158 | - static EVP_CIPHER *p = NULL; | |
128 | + static EVP_CIPHER ssh1_3des; | |
159 | 129 | |
160 | - if (p == NULL) { | |
161 | - p = EVP_CIPHER_meth_new(NID_undef, /*block_size*/8, /*key_len*/16); | |
162 | - /*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335で処置予定) ***/ | |
163 | - } | |
164 | - if (p) { | |
165 | - EVP_CIPHER_meth_set_iv_length(p, 0); | |
166 | - EVP_CIPHER_meth_set_init(p, ssh1_3des_init); | |
167 | - EVP_CIPHER_meth_set_cleanup(p, ssh1_3des_cleanup); | |
168 | - EVP_CIPHER_meth_set_do_cipher(p, ssh1_3des_cbc); | |
169 | - EVP_CIPHER_meth_set_flags(p, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH); | |
170 | - } | |
171 | - return (p); | |
130 | + memset(&ssh1_3des, 0, sizeof(EVP_CIPHER)); | |
131 | + ssh1_3des.nid = NID_undef; | |
132 | + ssh1_3des.block_size = 8; | |
133 | + ssh1_3des.iv_len = 0; | |
134 | + ssh1_3des.key_len = 16; | |
135 | + ssh1_3des.init = ssh1_3des_init; | |
136 | + ssh1_3des.cleanup = ssh1_3des_cleanup; | |
137 | + ssh1_3des.do_cipher = ssh1_3des_cbc; | |
138 | + ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH; | |
139 | + return (&ssh1_3des); | |
172 | 140 | } |
@@ -133,20 +133,20 @@ | ||
133 | 133 | const EVP_CIPHER * |
134 | 134 | evp_aes_128_ctr(void) |
135 | 135 | { |
136 | - static EVP_CIPHER *p = NULL; | |
136 | + static EVP_CIPHER aes_ctr; | |
137 | 137 | |
138 | - if (p == NULL) { | |
139 | - p = EVP_CIPHER_meth_new(NID_undef, /*block_size*/AES_BLOCK_SIZE, /*key_len*/16); | |
140 | - /*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335で処置予定) ***/ | |
141 | - } | |
142 | - if (p) { | |
143 | - EVP_CIPHER_meth_set_iv_length(p, AES_BLOCK_SIZE); | |
144 | - EVP_CIPHER_meth_set_init(p, ssh_aes_ctr_init); | |
145 | - EVP_CIPHER_meth_set_cleanup(p, ssh_aes_ctr_cleanup); | |
146 | - EVP_CIPHER_meth_set_do_cipher(p, ssh_aes_ctr); | |
147 | - EVP_CIPHER_meth_set_flags(p, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV); | |
148 | - } | |
149 | - return (p); | |
138 | + memset(&aes_ctr, 0, sizeof(EVP_CIPHER)); | |
139 | + aes_ctr.nid = NID_undef; | |
140 | + aes_ctr.block_size = AES_BLOCK_SIZE; | |
141 | + aes_ctr.iv_len = AES_BLOCK_SIZE; | |
142 | + aes_ctr.key_len = 16; | |
143 | + aes_ctr.init = ssh_aes_ctr_init; | |
144 | + aes_ctr.cleanup = ssh_aes_ctr_cleanup; | |
145 | + aes_ctr.do_cipher = ssh_aes_ctr; | |
146 | +#ifndef SSH_OLD_EVP | |
147 | + aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; | |
148 | +#endif | |
149 | + return (&aes_ctr); | |
150 | 150 | } |
151 | 151 | |
152 | 152 | //============================================================================ |
@@ -212,20 +212,20 @@ | ||
212 | 212 | const EVP_CIPHER * |
213 | 213 | evp_des3_ctr(void) |
214 | 214 | { |
215 | - static EVP_CIPHER *p = NULL; | |
215 | + static EVP_CIPHER des3_ctr; | |
216 | 216 | |
217 | - if (p == NULL) { | |
218 | - p = EVP_CIPHER_meth_new(NID_undef, /*block_size*/DES_BLOCK_SIZE, /*key_len*/24); | |
219 | - /*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335で処置予定) ***/ | |
220 | - } | |
221 | - if (p) { | |
222 | - EVP_CIPHER_meth_set_iv_length(p, DES_BLOCK_SIZE); | |
223 | - EVP_CIPHER_meth_set_init(p, ssh_des3_ctr_init); | |
224 | - EVP_CIPHER_meth_set_cleanup(p, ssh_des3_ctr_cleanup); | |
225 | - EVP_CIPHER_meth_set_do_cipher(p, ssh_des3_ctr); | |
226 | - EVP_CIPHER_meth_set_flags(p, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV); | |
227 | - } | |
228 | - return (p); | |
217 | + memset(&des3_ctr, 0, sizeof(EVP_CIPHER)); | |
218 | + des3_ctr.nid = NID_undef; | |
219 | + des3_ctr.block_size = DES_BLOCK_SIZE; | |
220 | + des3_ctr.iv_len = DES_BLOCK_SIZE; | |
221 | + des3_ctr.key_len = 24; | |
222 | + des3_ctr.init = ssh_des3_ctr_init; | |
223 | + des3_ctr.cleanup = ssh_des3_ctr_cleanup; | |
224 | + des3_ctr.do_cipher = ssh_des3_ctr; | |
225 | +#ifndef SSH_OLD_EVP | |
226 | + des3_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; | |
227 | +#endif | |
228 | + return (&des3_ctr); | |
229 | 229 | } |
230 | 230 | |
231 | 231 | //============================================================================ |
@@ -306,20 +306,20 @@ | ||
306 | 306 | const EVP_CIPHER * |
307 | 307 | evp_bf_ctr(void) |
308 | 308 | { |
309 | - static EVP_CIPHER *p = NULL; | |
309 | + static EVP_CIPHER blowfish_ctr; | |
310 | 310 | |
311 | - if (p == NULL) { | |
312 | - p = EVP_CIPHER_meth_new(NID_undef, /*block_size*/BF_BLOCK, /*key_len*/16); | |
313 | - /*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335で処置予定) ***/ | |
314 | - } | |
315 | - if (p) { | |
316 | - EVP_CIPHER_meth_set_iv_length(p, BF_BLOCK); | |
317 | - EVP_CIPHER_meth_set_init(p, ssh_bf_ctr_init); | |
318 | - EVP_CIPHER_meth_set_cleanup(p, ssh_bf_ctr_cleanup); | |
319 | - EVP_CIPHER_meth_set_do_cipher(p, ssh_bf_ctr); | |
320 | - EVP_CIPHER_meth_set_flags(p, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV); | |
321 | - } | |
322 | - return (p); | |
311 | + memset(&blowfish_ctr, 0, sizeof(EVP_CIPHER)); | |
312 | + blowfish_ctr.nid = NID_undef; | |
313 | + blowfish_ctr.block_size = BF_BLOCK; | |
314 | + blowfish_ctr.iv_len = BF_BLOCK; | |
315 | + blowfish_ctr.key_len = 16; | |
316 | + blowfish_ctr.init = ssh_bf_ctr_init; | |
317 | + blowfish_ctr.cleanup = ssh_bf_ctr_cleanup; | |
318 | + blowfish_ctr.do_cipher = ssh_bf_ctr; | |
319 | +#ifndef SSH_OLD_EVP | |
320 | + blowfish_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; | |
321 | +#endif | |
322 | + return (&blowfish_ctr); | |
323 | 323 | } |
324 | 324 | |
325 | 325 | //============================================================================ |
@@ -400,20 +400,20 @@ | ||
400 | 400 | const EVP_CIPHER * |
401 | 401 | evp_cast5_ctr(void) |
402 | 402 | { |
403 | - static EVP_CIPHER *p = NULL; | |
403 | + static EVP_CIPHER cast5_ctr; | |
404 | 404 | |
405 | - if (p == NULL) { | |
406 | - p = EVP_CIPHER_meth_new(NID_undef, /*block_size*/CAST_BLOCK, /*key_len*/16); | |
407 | - /*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335で処置予定) ***/ | |
408 | - } | |
409 | - if (p) { | |
410 | - EVP_CIPHER_meth_set_iv_length(p, CAST_BLOCK); | |
411 | - EVP_CIPHER_meth_set_init(p, ssh_cast5_ctr_init); | |
412 | - EVP_CIPHER_meth_set_cleanup(p, ssh_cast5_ctr_cleanup); | |
413 | - EVP_CIPHER_meth_set_do_cipher(p, ssh_cast5_ctr); | |
414 | - EVP_CIPHER_meth_set_flags(p, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV); | |
415 | - } | |
416 | - return (p); | |
405 | + memset(&cast5_ctr, 0, sizeof(EVP_CIPHER)); | |
406 | + cast5_ctr.nid = NID_undef; | |
407 | + cast5_ctr.block_size = CAST_BLOCK; | |
408 | + cast5_ctr.iv_len = CAST_BLOCK; | |
409 | + cast5_ctr.key_len = 16; | |
410 | + cast5_ctr.init = ssh_cast5_ctr_init; | |
411 | + cast5_ctr.cleanup = ssh_cast5_ctr_cleanup; | |
412 | + cast5_ctr.do_cipher = ssh_cast5_ctr; | |
413 | +#ifndef SSH_OLD_EVP | |
414 | + cast5_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; | |
415 | +#endif | |
416 | + return (&cast5_ctr); | |
417 | 417 | } |
418 | 418 | |
419 | 419 | //============================================================================ |
@@ -474,19 +474,18 @@ | ||
474 | 474 | const EVP_CIPHER * |
475 | 475 | evp_camellia_128_ctr(void) |
476 | 476 | { |
477 | + static EVP_CIPHER camellia_ctr; | |
477 | 478 | |
478 | - static EVP_CIPHER *p = NULL; | |
479 | - | |
480 | - if (p == NULL) { | |
481 | - p = EVP_CIPHER_meth_new(NID_undef, /*block_size*/CAMELLIA_BLOCK_SIZE, /*key_len*/16); | |
482 | - /*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335で処置予定) ***/ | |
483 | - } | |
484 | - if (p) { | |
485 | - EVP_CIPHER_meth_set_iv_length(p, CAMELLIA_BLOCK_SIZE); | |
486 | - EVP_CIPHER_meth_set_init(p, ssh_camellia_ctr_init); | |
487 | - EVP_CIPHER_meth_set_cleanup(p, ssh_camellia_ctr_cleanup); | |
488 | - EVP_CIPHER_meth_set_do_cipher(p, ssh_camellia_ctr); | |
489 | - EVP_CIPHER_meth_set_flags(p, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV); | |
490 | - } | |
491 | - return (p); | |
479 | + memset(&camellia_ctr, 0, sizeof(EVP_CIPHER)); | |
480 | + camellia_ctr.nid = NID_undef; | |
481 | + camellia_ctr.block_size = CAMELLIA_BLOCK_SIZE; | |
482 | + camellia_ctr.iv_len = CAMELLIA_BLOCK_SIZE; | |
483 | + camellia_ctr.key_len = 16; | |
484 | + camellia_ctr.init = ssh_camellia_ctr_init; | |
485 | + camellia_ctr.cleanup = ssh_camellia_ctr_cleanup; | |
486 | + camellia_ctr.do_cipher = ssh_camellia_ctr; | |
487 | +#ifndef SSH_OLD_EVP | |
488 | + camellia_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; | |
489 | +#endif | |
490 | + return (&camellia_ctr); | |
492 | 491 | } |