Develop and Download Open Source Software

Browse Subversion Repository

Contents of /branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9250 - (show annotations) (download) (as text)
Sun May 16 14:26:47 2021 UTC (2 years, 9 months ago) by nmaya
File MIME type: text/x-csrc
File size: 20362 byte(s)
OpenSSH からの移植時に間違えた条件判定を修正

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

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