Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10648 - (show annotations) (download) (as text)
Tue Mar 28 14:12:32 2023 UTC (12 months, 2 weeks ago) by nmaya
File MIME type: text/x-csrc
File size: 21844 byte(s)
EVP_CIPHER 構造体を用いる場合と、EVP_CIPHER_meth_new() 関数を用いる場合の条件分岐を整理

LibreSSL 3.5.0-3.7.0 は EVP_CIPHER 構造体も EVP_CIPHER_meth_new() 関数も使えない

ticket #45656, #43469, wiki:暗号ライブラリ
1 /*
2 * Copyright (c) 1998-2001, Robert O'Callahan
3 * (C) 2004- TeraTerm Project
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "ttxssh.h"
31 #include "ssh.h"
32 #include "ssherr.h"
33 #include "cipher.h"
34 #include "kex.h"
35
36 #include <openssl/evp.h>
37
38 #include "codeconv.h"
39
40 #include "cipher-3des1.h"
41 #include "cipher-ctr.h"
42
43 static const struct ssh2cipher ssh2_ciphers[] = {
44 {SSH2_CIPHER_3DES_CBC, "3des-cbc", 8, 24, 0, 0, 0, EVP_des_ede3_cbc}, // RFC4253
45 {SSH2_CIPHER_AES128_CBC, "aes128-cbc", 16, 16, 0, 0, 0, EVP_aes_128_cbc}, // RFC4253
46 {SSH2_CIPHER_AES192_CBC, "aes192-cbc", 16, 24, 0, 0, 0, EVP_aes_192_cbc}, // RFC4253
47 {SSH2_CIPHER_AES256_CBC, "aes256-cbc", 16, 32, 0, 0, 0, EVP_aes_256_cbc}, // RFC4253
48 {SSH2_CIPHER_BLOWFISH_CBC, "blowfish-cbc", 8, 16, 0, 0, 0, EVP_bf_cbc}, // RFC4253
49 {SSH2_CIPHER_AES128_CTR, "aes128-ctr", 16, 16, 0, 0, 0, EVP_aes_128_ctr}, // RFC4344
50 {SSH2_CIPHER_AES192_CTR, "aes192-ctr", 16, 24, 0, 0, 0, EVP_aes_192_ctr}, // RFC4344
51 {SSH2_CIPHER_AES256_CTR, "aes256-ctr", 16, 32, 0, 0, 0, EVP_aes_256_ctr}, // RFC4344
52 {SSH2_CIPHER_ARCFOUR, "arcfour", 8, 16, 0, 0, 0, EVP_rc4}, // RFC4253
53 {SSH2_CIPHER_ARCFOUR128, "arcfour128", 8, 16, 1536, 0, 0, EVP_rc4}, // RFC4345
54 {SSH2_CIPHER_ARCFOUR256, "arcfour256", 8, 32, 1536, 0, 0, EVP_rc4}, // RFC4345
55 {SSH2_CIPHER_CAST128_CBC, "cast128-cbc", 8, 16, 0, 0, 0, EVP_cast5_cbc}, // RFC4253
56 {SSH2_CIPHER_3DES_CTR, "3des-ctr", 8, 24, 0, 0, 0, evp_des3_ctr}, // RFC4344
57 {SSH2_CIPHER_BLOWFISH_CTR, "blowfish-ctr", 8, 32, 0, 0, 0, evp_bf_ctr}, // RFC4344
58 {SSH2_CIPHER_CAST128_CTR, "cast128-ctr", 8, 16, 0, 0, 0, evp_cast5_ctr}, // RFC4344
59 {SSH2_CIPHER_CAMELLIA128_CBC, "camellia128-cbc", 16, 16, 0, 0, 0, EVP_camellia_128_cbc}, // draft-kanno-secsh-camellia-02
60 {SSH2_CIPHER_CAMELLIA192_CBC, "camellia192-cbc", 16, 24, 0, 0, 0, EVP_camellia_192_cbc}, // draft-kanno-secsh-camellia-02
61 {SSH2_CIPHER_CAMELLIA256_CBC, "camellia256-cbc", 16, 32, 0, 0, 0, EVP_camellia_256_cbc}, // draft-kanno-secsh-camellia-02
62 #ifndef LIBRESSL_VERSION_NUMBER
63 {SSH2_CIPHER_CAMELLIA128_CTR, "camellia128-ctr", 16, 16, 0, 0, 0, EVP_camellia_128_ctr}, // draft-kanno-secsh-camellia-02
64 {SSH2_CIPHER_CAMELLIA192_CTR, "camellia192-ctr", 16, 24, 0, 0, 0, EVP_camellia_192_ctr}, // draft-kanno-secsh-camellia-02
65 {SSH2_CIPHER_CAMELLIA256_CTR, "camellia256-ctr", 16, 32, 0, 0, 0, EVP_camellia_256_ctr}, // draft-kanno-secsh-camellia-02
66 #else
67 {SSH2_CIPHER_CAMELLIA128_CTR, "camellia128-ctr", 16, 16, 0, 0, 0, evp_camellia_128_ctr}, // draft-kanno-secsh-camellia-02
68 {SSH2_CIPHER_CAMELLIA192_CTR, "camellia192-ctr", 16, 24, 0, 0, 0, evp_camellia_128_ctr}, // draft-kanno-secsh-camellia-02
69 {SSH2_CIPHER_CAMELLIA256_CTR, "camellia256-ctr", 16, 32, 0, 0, 0, evp_camellia_128_ctr}, // draft-kanno-secsh-camellia-02
70 #endif
71 #ifdef WITH_CAMELLIA_PRIVATE
72 {SSH2_CIPHER_CAMELLIA128_CBC, "camellia128-cbc@openssh.org", 16, 16, 0, 0, 0, EVP_camellia_128_cbc},
73 {SSH2_CIPHER_CAMELLIA192_CBC, "camellia192-cbc@openssh.org", 16, 24, 0, 0, 0, EVP_camellia_192_cbc},
74 {SSH2_CIPHER_CAMELLIA256_CBC, "camellia256-cbc@openssh.org", 16, 32, 0, 0, 0, EVP_camellia_256_cbc},
75 {SSH2_CIPHER_CAMELLIA128_CTR, "camellia128-ctr@openssh.org", 16, 16, 0, 0, 0, evp_camellia_128_ctr},
76 {SSH2_CIPHER_CAMELLIA192_CTR, "camellia192-ctr@openssh.org", 16, 24, 0, 0, 0, evp_camellia_128_ctr},
77 {SSH2_CIPHER_CAMELLIA256_CTR, "camellia256-ctr@openssh.org", 16, 32, 0, 0, 0, evp_camellia_128_ctr},
78 #endif // WITH_CAMELLIA_PRIVATE
79 {SSH2_CIPHER_AES128_GCM, "aes128-gcm@openssh.com", 16, 16, 0, 12, 16, EVP_aes_128_gcm}, // not RFC5647, PROTOCOL of OpenSSH
80 {SSH2_CIPHER_AES256_GCM, "aes256-gcm@openssh.com", 16, 32, 0, 12, 16, EVP_aes_256_gcm}, // not RFC5647, PROTOCOL of OpenSSH
81 {SSH2_CIPHER_CHACHAPOLY, "chacha20-poly1305@openssh.com", 8, 64, 0, 0, 16, EVP_enc_null},
82 {SSH_CIPHER_NONE, "none", 8, 0, 0, 0, 0, EVP_enc_null}, // for no passphrase key file
83 {SSH_CIPHER_3DES, "3des", 8, 16, 0, 0, 0, evp_ssh1_3des}, // for RSA1 key file
84 };
85
86
87 int get_cipher_id(const struct ssh2cipher *cipher)
88 {
89 if (cipher) {
90 return cipher->id;
91 }
92 else {
93 return 0;
94 }
95 }
96
97 u_int get_cipher_block_size(const struct ssh2cipher *cipher)
98 {
99 u_int blocksize = 0;
100
101 if (cipher) {
102 blocksize = cipher->block_size;
103 }
104
105 return max(blocksize, 8);
106 }
107
108 u_int get_cipher_key_len(const struct ssh2cipher *cipher)
109 {
110 if (cipher) {
111 return cipher->key_len;
112 }
113 else {
114 return 0;
115 }
116 }
117
118 u_int get_cipher_discard_len(const struct ssh2cipher *cipher)
119 {
120 if (cipher) {
121 return cipher->discard_len;
122 }
123 else {
124 return 0;
125 }
126 }
127
128 u_int get_cipher_iv_len(const struct ssh2cipher *cipher)
129 {
130 if (cipher) {
131 if (cipher->iv_len != 0 || cipher->id == SSH2_CIPHER_CHACHAPOLY) {
132 return cipher->iv_len;
133 }
134 else {
135 return cipher->block_size;
136 }
137 }
138 else {
139 return 8; // block_size
140 }
141 }
142
143 u_int get_cipher_auth_len(const struct ssh2cipher *cipher)
144 {
145 if (cipher) {
146 return cipher->auth_len;
147 }
148 else {
149 return 0;
150 }
151 }
152
153 const EVP_CIPHER *get_cipher_EVP_CIPHER(const struct ssh2cipher *cipher)
154 {
155 if (cipher) {
156 return cipher->func();
157 }
158 else {
159 return EVP_enc_null();
160 }
161 }
162
163 char *get_cipher_string(const struct ssh2cipher *cipher)
164 {
165 if (cipher) {
166 return cipher->name;
167 }
168 else {
169 return "unknown";
170 }
171 }
172
173 // �����A���S���Y�����������������B
174 const struct ssh2cipher *get_cipher_by_name(char *name)
175 {
176 const struct ssh2cipher *ptr = ssh2_ciphers;
177
178 if (name == NULL || name[0] == '\0')
179 return NULL;
180
181 while (ptr->name != NULL) {
182 if (strcmp(ptr->name, name) == 0) {
183 return ptr;
184 }
185 ptr++;
186 }
187
188 // not found.
189 return NULL;
190 }
191
192 // �\����
193 char *get_cipher_name(int cipher_id)
194 {
195 switch (cipher_id) {
196 case SSH_CIPHER_NONE:
197 return "None";
198 case SSH_CIPHER_3DES:
199 return "3DES (168 key bits)";
200 case SSH_CIPHER_DES:
201 return "DES (56 key bits)";
202 case SSH_CIPHER_BLOWFISH:
203 return "Blowfish (256 key bits)";
204
205 // SSH2
206 case SSH2_CIPHER_3DES_CBC:
207 return "3des-cbc";
208 case SSH2_CIPHER_AES128_CBC:
209 return "aes128-cbc";
210 case SSH2_CIPHER_AES192_CBC:
211 return "aes192-cbc";
212 case SSH2_CIPHER_AES256_CBC:
213 return "aes256-cbc";
214 case SSH2_CIPHER_BLOWFISH_CBC:
215 return "blowfish-cbc";
216 case SSH2_CIPHER_AES128_CTR:
217 return "aes128-ctr";
218 case SSH2_CIPHER_AES192_CTR:
219 return "aes192-ctr";
220 case SSH2_CIPHER_AES256_CTR:
221 return "aes256-ctr";
222 case SSH2_CIPHER_ARCFOUR:
223 return "arcfour";
224 case SSH2_CIPHER_ARCFOUR128:
225 return "arcfour128";
226 case SSH2_CIPHER_ARCFOUR256:
227 return "arcfour256";
228 case SSH2_CIPHER_CAST128_CBC:
229 return "cast-128-cbc";
230 case SSH2_CIPHER_3DES_CTR:
231 return "3des-ctr";
232 case SSH2_CIPHER_BLOWFISH_CTR:
233 return "blowfish-ctr";
234 case SSH2_CIPHER_CAST128_CTR:
235 return "cast-128-ctr";
236 case SSH2_CIPHER_CAMELLIA128_CBC:
237 return "camellia128-cbc";
238 case SSH2_CIPHER_CAMELLIA192_CBC:
239 return "camellia192-cbc";
240 case SSH2_CIPHER_CAMELLIA256_CBC:
241 return "camellia256-cbc";
242 case SSH2_CIPHER_CAMELLIA128_CTR:
243 return "camellia128-ctr";
244 case SSH2_CIPHER_CAMELLIA192_CTR:
245 return "camellia192-ctr";
246 case SSH2_CIPHER_CAMELLIA256_CTR:
247 return "camellia256-ctr";
248 case SSH2_CIPHER_AES128_GCM:
249 return "aes128-gcm@openssh.com";
250 case SSH2_CIPHER_AES256_GCM:
251 return "aes256-gcm@openssh.com";
252 case SSH2_CIPHER_CHACHAPOLY:
253 return "chacha20-poly1305@openssh.com(SSH2)";
254
255 default:
256 return "Unknown";
257 }
258 }
259
260 // ���X�g�{�b�N�X�\����
261 wchar_t *get_listbox_cipher_nameW(int cipher_id, PTInstVar pvar)
262 {
263 typedef struct {
264 int no;
265 const char *nameA;
266 } list_t;
267 static const list_t list[] = {
268 { SSH_CIPHER_3DES, "3DES(SSH1)" },
269 { SSH_CIPHER_DES, "DES(SSH1)" },
270 { SSH_CIPHER_BLOWFISH, "Blowfish(SSH1)" },
271 { SSH2_CIPHER_AES128_CBC, "aes128-cbc(SSH2)" },
272 { SSH2_CIPHER_AES192_CBC, "aes192-cbc(SSH2)" },
273 { SSH2_CIPHER_AES256_CBC, "aes256-cbc(SSH2)" },
274 { SSH2_CIPHER_3DES_CBC, "3des-cbc(SSH2)" },
275 { SSH2_CIPHER_BLOWFISH_CBC, "blowfish-cbc(SSH2)" },
276 { SSH2_CIPHER_AES128_CTR, "aes128-ctr(SSH2)" },
277 { SSH2_CIPHER_AES192_CTR, "aes192-ctr(SSH2)" },
278 { SSH2_CIPHER_AES256_CTR, "aes256-ctr(SSH2)" },
279 { SSH2_CIPHER_ARCFOUR, "arcfour(SSH2)" },
280 { SSH2_CIPHER_ARCFOUR128, "arcfour128(SSH2)" },
281 { SSH2_CIPHER_ARCFOUR256, "arcfour256(SSH2)" },
282 { SSH2_CIPHER_CAST128_CBC, "cast128-cbc(SSH2)" },
283 { SSH2_CIPHER_3DES_CTR, "3des-ctr(SSH2)" },
284 { SSH2_CIPHER_BLOWFISH_CTR, "blowfish-ctr(SSH2)" },
285 { SSH2_CIPHER_CAST128_CTR, "cast128-ctr(SSH2)" },
286 { SSH2_CIPHER_CAMELLIA128_CBC, "camellia128-cbc(SSH2)" },
287 { SSH2_CIPHER_CAMELLIA192_CBC, "camellia192-cbc(SSH2)" },
288 { SSH2_CIPHER_CAMELLIA256_CBC, "camellia256-cbc(SSH2)" },
289 { SSH2_CIPHER_CAMELLIA128_CTR, "camellia128-ctr(SSH2)" },
290 { SSH2_CIPHER_CAMELLIA192_CTR, "camellia192-ctr(SSH2)" },
291 { SSH2_CIPHER_CAMELLIA256_CTR, "camellia256-ctr(SSH2)" },
292 { SSH2_CIPHER_AES128_GCM, "aes128-gcm@openssh.com(SSH2)" },
293 { SSH2_CIPHER_AES256_GCM, "aes256-gcm@openssh.com(SSH2)" },
294 { SSH2_CIPHER_CHACHAPOLY, "chacha20-poly1305@openssh.com(SSH2)" },
295 };
296 int i;
297 const list_t *p = list;
298
299 if (cipher_id == SSH_CIPHER_NONE) {
300 wchar_t uimsg[MAX_UIMSG];
301 UTIL_get_lang_msgW("DLG_SSHSETUP_CIPHER_BORDER", pvar,
302 L"<ciphers below this line are disabled>", uimsg);
303 return _wcsdup(uimsg);
304 }
305 for (i = 0; i < _countof(list); p++,i++) {
306 if (p->no == cipher_id) {
307 return ToWcharA(p->nameA);
308 }
309 }
310 return NULL;
311 }
312
313 /*
314 * Remove unsupported cipher or duplicated cipher.
315 * Add unspecified ciphers at the end of list.
316 */
317 void normalize_cipher_order(char *buf)
318 {
319 /* SSH_CIPHER_NONE means that all ciphers below that one are disabled.
320 We *never* allow no encryption. */
321 static char default_strings[] = {
322 SSH2_CIPHER_AES256_GCM,
323 #if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER <= 0x3040300fL || LIBRESSL_VERSION_NUMBER >= 0x3070100fL
324 SSH2_CIPHER_CAMELLIA256_CTR,
325 #endif
326 SSH2_CIPHER_CHACHAPOLY,
327 SSH2_CIPHER_AES256_CTR,
328 SSH2_CIPHER_CAMELLIA256_CBC,
329 SSH2_CIPHER_AES256_CBC,
330 #if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER <= 0x3040300fL || LIBRESSL_VERSION_NUMBER >= 0x3070100fL
331 SSH2_CIPHER_CAMELLIA192_CTR,
332 #endif
333 SSH2_CIPHER_AES192_CTR,
334 SSH2_CIPHER_CAMELLIA192_CBC,
335 SSH2_CIPHER_AES192_CBC,
336 SSH2_CIPHER_AES128_GCM,
337 #if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER <= 0x3040300fL || LIBRESSL_VERSION_NUMBER >= 0x3070100fL
338 SSH2_CIPHER_CAMELLIA128_CTR,
339 #endif
340 SSH2_CIPHER_AES128_CTR,
341 SSH2_CIPHER_CAMELLIA128_CBC,
342 SSH2_CIPHER_AES128_CBC,
343 #if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER <= 0x3040300fL || LIBRESSL_VERSION_NUMBER >= 0x3070100fL
344 SSH2_CIPHER_3DES_CTR,
345 #endif
346 SSH2_CIPHER_3DES_CBC,
347 #if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER <= 0x3040300fL || LIBRESSL_VERSION_NUMBER >= 0x3070100fL
348 SSH2_CIPHER_BLOWFISH_CTR,
349 #endif
350 SSH2_CIPHER_BLOWFISH_CBC,
351 #if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER <= 0x3040300fL || LIBRESSL_VERSION_NUMBER >= 0x3070100fL
352 SSH2_CIPHER_CAST128_CTR,
353 #endif
354 SSH2_CIPHER_CAST128_CBC,
355 SSH_CIPHER_3DES,
356 SSH_CIPHER_NONE,
357 SSH2_CIPHER_ARCFOUR256,
358 SSH2_CIPHER_ARCFOUR128,
359 SSH2_CIPHER_ARCFOUR,
360 SSH_CIPHER_BLOWFISH,
361 SSH_CIPHER_DES,
362 #if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER > 0x3040300fL && LIBRESSL_VERSION_NUMBER < 0x3070100fL
363 0, 0, 0, // Dummy for SSH2_CIPHER_CAMELLIA256_CTR, SSH2_CIPHER_CAMELLIA192_CTR, SSH2_CIPHER_CAMELLIA128_CTR
364 0, 0, 0, // Dummy for SSH2_CIPHER_3DES_CTR, SSH2_CIPHER_BLOWFISH_CTR, SSH2_CIPHER_CAST128_CTR
365 #endif
366 0, 0, 0 // Dummy for SSH_CIPHER_IDEA, SSH_CIPHER_TSS, SSH_CIPHER_RC4
367 };
368
369 normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
370 }
371
372 const struct ssh2cipher *choose_SSH2_cipher_algorithm(char *server_proposal, char *my_proposal)
373 {
374 char str_cipher[32];
375 const struct ssh2cipher *ptr = ssh2_ciphers;
376
377 choose_SSH2_proposal(server_proposal, my_proposal, str_cipher, sizeof(str_cipher));
378 return get_cipher_by_name(str_cipher);
379 }
380
381 void SSH2_update_cipher_myproposal(PTInstVar pvar)
382 {
383 static char buf[512]; // TODO: malloc()��������
384 int cipher;
385 int len, i;
386 char *c_str;
387
388 // ���M�������������������������A�O�������B(2006.6.26 maya)
389 if (pvar->socket != INVALID_SOCKET) {
390 return;
391 }
392
393 // �����A���S���Y���D���������������Amyproposal[]�������������B(2004.11.6 yutaka)
394 buf[0] = '\0';
395 for (i = 0 ; pvar->settings.CipherOrder[i] != 0 ; i++) {
396 cipher = pvar->settings.CipherOrder[i] - '0';
397 if (cipher == 0) // disabled line
398 break;
399 switch (cipher) {
400 case SSH2_CIPHER_3DES_CBC:
401 c_str = "3des-cbc,";
402 break;
403 case SSH2_CIPHER_3DES_CTR:
404 c_str = "3des-ctr,";
405 break;
406 case SSH2_CIPHER_BLOWFISH_CBC:
407 c_str = "blowfish-cbc,";
408 break;
409 case SSH2_CIPHER_BLOWFISH_CTR:
410 c_str = "blowfish-ctr,";
411 break;
412 case SSH2_CIPHER_AES128_CBC:
413 c_str = "aes128-cbc,";
414 break;
415 case SSH2_CIPHER_AES192_CBC:
416 c_str = "aes192-cbc,";
417 break;
418 case SSH2_CIPHER_AES256_CBC:
419 c_str = "aes256-cbc,";
420 break;
421 case SSH2_CIPHER_AES128_CTR:
422 c_str = "aes128-ctr,";
423 break;
424 case SSH2_CIPHER_AES192_CTR:
425 c_str = "aes192-ctr,";
426 break;
427 case SSH2_CIPHER_AES256_CTR:
428 c_str = "aes256-ctr,";
429 break;
430 case SSH2_CIPHER_ARCFOUR:
431 c_str = "arcfour,";
432 break;
433 case SSH2_CIPHER_ARCFOUR128:
434 c_str = "arcfour128,";
435 break;
436 case SSH2_CIPHER_ARCFOUR256:
437 c_str = "arcfour256,";
438 break;
439 case SSH2_CIPHER_CAST128_CBC:
440 c_str = "cast128-cbc,";
441 break;
442 case SSH2_CIPHER_CAST128_CTR:
443 c_str = "cast128-ctr,";
444 break;
445 #ifdef WITH_CAMELLIA_PRIVATE
446 case SSH2_CIPHER_CAMELLIA128_CBC:
447 c_str = "camellia128-cbc,camellia128-cbc@openssh.org,";
448 break;
449 case SSH2_CIPHER_CAMELLIA192_CBC:
450 c_str = "camellia192-cbc,camellia192-cbc@openssh.org,";
451 break;
452 case SSH2_CIPHER_CAMELLIA256_CBC:
453 c_str = "camellia256-cbc,camellia256-cbc@openssh.org,";
454 break;
455 case SSH2_CIPHER_CAMELLIA128_CTR:
456 c_str = "camellia128-ctr,camellia128-ctr@openssh.org,";
457 break;
458 case SSH2_CIPHER_CAMELLIA192_CTR:
459 c_str = "camellia192-ctr,camellia192-ctr@openssh.org,";
460 break;
461 case SSH2_CIPHER_CAMELLIA256_CTR:
462 c_str = "camellia256-ctr,camellia256-ctr@openssh.org,";
463 break;
464 #endif // WITH_CAMELLIA_PRIVATE
465 case SSH2_CIPHER_CAMELLIA128_CBC:
466 c_str = "camellia128-cbc,";
467 break;
468 case SSH2_CIPHER_CAMELLIA192_CBC:
469 c_str = "camellia192-cbc,";
470 break;
471 case SSH2_CIPHER_CAMELLIA256_CBC:
472 c_str = "camellia256-cbc,";
473 break;
474 case SSH2_CIPHER_CAMELLIA128_CTR:
475 c_str = "camellia128-ctr,";
476 break;
477 case SSH2_CIPHER_CAMELLIA192_CTR:
478 c_str = "camellia192-ctr,";
479 break;
480 case SSH2_CIPHER_CAMELLIA256_CTR:
481 c_str = "camellia256-ctr,";
482 break;
483 case SSH2_CIPHER_AES128_GCM:
484 c_str = "aes128-gcm@openssh.com,";
485 break;
486 case SSH2_CIPHER_AES256_GCM:
487 c_str = "aes256-gcm@openssh.com,";
488 break;
489 case SSH2_CIPHER_CHACHAPOLY:
490 c_str = "chacha20-poly1305@openssh.com,";
491 break;
492 default:
493 continue;
494 }
495 strncat_s(buf, sizeof(buf), c_str, _TRUNCATE);
496 }
497 len = strlen(buf);
498 if (len > 0)
499 buf[len - 1] = '\0'; // get rid of comma
500 myproposal[PROPOSAL_ENC_ALGS_CTOS] = buf; // Client To Server
501 myproposal[PROPOSAL_ENC_ALGS_STOC] = buf; // Server To Client
502 }
503
504
505 //
506 // SSH2�p�A���S���Y����������
507 //
508 int cipher_init_SSH2(
509 struct sshcipher_ctx **ccp, const struct ssh2cipher *cipher,
510 const u_char *key, u_int keylen,
511 const u_char *iv, u_int ivlen,
512 int do_encrypt,
513 PTInstVar pvar)
514 {
515 struct sshcipher_ctx *cc = NULL;
516 int ret = SSH_ERR_INTERNAL_ERROR;
517 const EVP_CIPHER *type;
518 int klen;
519 unsigned char *junk = NULL, *discard = NULL;
520 char tmp[80];
521
522 *ccp = NULL;
523 if ((cc = calloc(sizeof(*cc), 1)) == NULL) {
524 UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
525 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->UIMsg, 1);
526 notify_fatal_error(pvar, tmp, TRUE);
527 return SSH_ERR_ALLOC_FAIL;
528 }
529
530 if (keylen < cipher->key_len) {
531 UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
532 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->UIMsg, 2);
533 notify_fatal_error(pvar, tmp, TRUE);
534 ret = SSH_ERR_INVALID_ARGUMENT;
535 goto out;
536 }
537 if (iv != NULL && ivlen < get_cipher_iv_len(cipher)) {
538 UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
539 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->UIMsg, 3);
540 notify_fatal_error(pvar, tmp, TRUE);
541 ret = SSH_ERR_INVALID_ARGUMENT;
542 goto out;
543 }
544
545 cc->cipher = cipher;
546 if (cipher->id == SSH2_CIPHER_CHACHAPOLY) {
547 cc->cp_ctx = chachapoly_new(key, keylen);
548 ret = cc->cp_ctx != NULL ? 0 : SSH_ERR_INVALID_ARGUMENT;
549 if (ret == SSH_ERR_INVALID_ARGUMENT) {
550 UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
551 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->UIMsg, 4);
552 notify_fatal_error(pvar, tmp, TRUE);
553 }
554 goto out;
555 }
556 type = (*cipher->func)();
557 if ((cc->evp = EVP_CIPHER_CTX_new()) == NULL) {
558 UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
559 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->UIMsg, 5);
560 notify_fatal_error(pvar, tmp, TRUE);
561 ret = SSH_ERR_ALLOC_FAIL;
562 goto out;
563 }
564 if (EVP_CipherInit(cc->evp, type, NULL, (u_char *)iv, (do_encrypt == CIPHER_ENCRYPT)) == 0) {
565 UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
566 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->UIMsg, 6);
567 notify_fatal_error(pvar, tmp, TRUE);
568 ret = SSH_ERR_LIBCRYPTO_ERROR;
569 goto out;
570 }
571 if (get_cipher_auth_len(cipher) &&
572 !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, -1, (u_char *)iv)) {
573 UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
574 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->UIMsg, 7);
575 notify_fatal_error(pvar, tmp, TRUE);
576 ret = SSH_ERR_LIBCRYPTO_ERROR;
577 goto out;
578 }
579 klen = EVP_CIPHER_CTX_key_length(cc->evp);
580 if (klen > 0 && keylen != (u_int)klen) {
581 if (EVP_CIPHER_CTX_set_key_length(cc->evp, keylen) == 0) {
582 UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
583 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->UIMsg, 8);
584 notify_fatal_error(pvar, tmp, TRUE);
585 ret = SSH_ERR_LIBCRYPTO_ERROR;
586 goto out;
587 }
588 }
589 if (EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0) {
590 UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
591 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->UIMsg, 9);
592 notify_fatal_error(pvar, tmp, TRUE);
593 ret = SSH_ERR_LIBCRYPTO_ERROR;
594 goto out;
595 }
596
597 if (cipher->discard_len > 0) {
598 junk = malloc(cipher->discard_len);
599 discard = malloc(cipher->discard_len);
600 if (junk == NULL || discard == NULL ||
601 EVP_Cipher(cc->evp, discard, junk, cipher->discard_len) == 0) {
602 UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
603 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->UIMsg, 10);
604 notify_fatal_error(pvar, tmp, TRUE);
605 }
606 else {
607 SecureZeroMemory(discard, cipher->discard_len);
608 }
609 free(junk);
610 free(discard);
611 }
612 ret = 0;
613
614 out:
615 if (ret == 0) {
616 *ccp = cc;
617 }
618 else {
619 if (cc != NULL) {
620 EVP_CIPHER_CTX_free(cc->evp);
621 SecureZeroMemory(cc, sizeof(*cc));
622 }
623 }
624 return ret;
625 }
626
627 //
628 // SSH2�p�A���S���Y�����j��
629 ///
630 void cipher_free_SSH2(struct sshcipher_ctx *cc)
631 {
632 if (cc == NULL)
633 return;
634 if (cc->cipher->id == SSH2_CIPHER_CHACHAPOLY) {
635 chachapoly_free(cc->cp_ctx);
636 cc->cp_ctx = NULL;
637 }
638 EVP_CIPHER_CTX_free(cc->evp);
639 cc->evp = NULL;
640 SecureZeroMemory(cc, sizeof(*cc));
641 }

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