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 9255 - (show annotations) (download) (as text)
Wed May 19 14:11:26 2021 UTC (2 years, 10 months ago) by nmaya
File MIME type: text/x-csrc
File size: 20353 byte(s)
SSH2 暗号化方式 chacha20-poly1305@openssh.com をサポート

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

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