Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9255 - (hide 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 nmaya 9210 /*
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 nmaya 9255 #include "codeconv.h"
39    
40 nmaya 9210 // 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 nmaya 9255 {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 nmaya 9210 };
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 nmaya 9255 if (cipher->iv_len != 0 || cipher->id == SSH2_CIPHER_CHACHAPOLY) {
126 nmaya 9210 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 nmaya 9255 case SSH2_CIPHER_CHACHAPOLY:
247     return "chacha20-poly1305@openssh.com(SSH2)";
248 nmaya 9210
249     default:
250     return "Unknown";
251     }
252     }
253    
254     // ���X�g�{�b�N�X�\����
255 nmaya 9255 wchar_t *get_listbox_cipher_nameW(int cipher_id, PTInstVar pvar)
256 nmaya 9210 {
257 nmaya 9255 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 nmaya 9210
293 nmaya 9255 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 nmaya 9210 }
299 nmaya 9255 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 nmaya 9210 }
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 nmaya 9255 SSH2_CIPHER_CHACHAPOLY,
319 nmaya 9210 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 nmaya 9255 case SSH2_CIPHER_CHACHAPOLY:
468     c_str = "chacha20-poly1305@openssh.com,";
469     break;
470 nmaya 9210 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 nmaya 9255 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 nmaya 9210 {
493 nmaya 9255 struct sshcipher_ctx *cc = NULL;
494     int ret = SSH_ERR_INTERNAL_ERROR;
495     const EVP_CIPHER *type;
496 nmaya 9210 int klen;
497     unsigned char *junk = NULL, *discard = NULL;
498     char tmp[80];
499    
500 nmaya 9255 *ccp = NULL;
501     if ((cc = calloc(sizeof(*cc), 1)) == NULL) {
502 nmaya 9210 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 nmaya 9255 return SSH_ERR_ALLOC_FAIL;
506 nmaya 9210 }
507 nmaya 9255
508     if (keylen < cipher->key_len) {
509 nmaya 9210 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 nmaya 9255 ret = SSH_ERR_INVALID_ARGUMENT;
513     goto out;
514 nmaya 9210 }
515 nmaya 9255 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 nmaya 9210 if (klen > 0 && keylen != (u_int)klen) {
559 nmaya 9255 if (EVP_CIPHER_CTX_set_key_length(cc->evp, keylen) == 0) {
560 nmaya 9210 UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
561 nmaya 9255 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 8);
562 nmaya 9210 notify_fatal_error(pvar, tmp, TRUE);
563 nmaya 9255 ret = SSH_ERR_LIBCRYPTO_ERROR;
564     goto out;
565 nmaya 9210 }
566     }
567 nmaya 9255 if (EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0) {
568 nmaya 9210 UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
569 nmaya 9255 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 9);
570 nmaya 9210 notify_fatal_error(pvar, tmp, TRUE);
571 nmaya 9255 ret = SSH_ERR_LIBCRYPTO_ERROR;
572     goto out;
573 nmaya 9210 }
574    
575 nmaya 9255 if (cipher->discard_len > 0) {
576     junk = malloc(cipher->discard_len);
577     discard = malloc(cipher->discard_len);
578 nmaya 9210 if (junk == NULL || discard == NULL ||
579 nmaya 9255 EVP_Cipher(cc->evp, discard, junk, cipher->discard_len) == 0) {
580 nmaya 9210 UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
581 nmaya 9255 _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 10);
582 nmaya 9210 notify_fatal_error(pvar, tmp, TRUE);
583     }
584     else {
585 nmaya 9255 SecureZeroMemory(discard, cipher->discard_len);
586 nmaya 9210 }
587     free(junk);
588     free(discard);
589     }
590 nmaya 9255 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 nmaya 9210 }
604    
605     //
606     // SSH2�p�A���S���Y�����j��
607     ///
608 nmaya 9255 void cipher_free_SSH2(struct sshcipher_ctx *cc)
609 nmaya 9210 {
610 nmaya 9255 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 nmaya 9210 }

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