Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/ttssh2/ttxssh/kex.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, 9 months ago) by nmaya
File MIME type: text/x-csrc
File size: 25520 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 * (C) 2011- TeraTerm Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "ttxssh.h"
30 #include "kex.h"
31
32
33 char *myproposal[PROPOSAL_MAX] = {
34 KEX_DEFAULT_KEX,
35 KEX_DEFAULT_PK_ALG,
36 KEX_DEFAULT_ENCRYPT,
37 KEX_DEFAULT_ENCRYPT,
38 KEX_DEFAULT_MAC,
39 KEX_DEFAULT_MAC,
40 KEX_DEFAULT_COMP,
41 KEX_DEFAULT_COMP,
42 KEX_DEFAULT_LANG,
43 KEX_DEFAULT_LANG,
44 };
45
46 struct ssh2_kex_algorithm_t {
47 kex_algorithm kextype;
48 char *name;
49 const EVP_MD *(*evp_md)(void);
50 };
51
52 static const struct ssh2_kex_algorithm_t ssh2_kex_algorithms[] = {
53 {KEX_DH_GRP1_SHA1, "diffie-hellman-group1-sha1", EVP_sha1}, // RFC4253
54 {KEX_DH_GRP14_SHA1, "diffie-hellman-group14-sha1", EVP_sha1}, // RFC4253
55 {KEX_DH_GEX_SHA1, "diffie-hellman-group-exchange-sha1", EVP_sha1}, // RFC4419
56 {KEX_DH_GEX_SHA256, "diffie-hellman-group-exchange-sha256", EVP_sha256}, // RFC4419
57 {KEX_ECDH_SHA2_256, "ecdh-sha2-nistp256", EVP_sha256}, // RFC5656
58 {KEX_ECDH_SHA2_384, "ecdh-sha2-nistp384", EVP_sha384}, // RFC5656
59 {KEX_ECDH_SHA2_521, "ecdh-sha2-nistp521", EVP_sha512}, // RFC5656
60 {KEX_DH_GRP14_SHA256, "diffie-hellman-group14-sha256", EVP_sha256}, // RFC8268
61 {KEX_DH_GRP16_SHA512, "diffie-hellman-group16-sha512", EVP_sha512}, // RFC8268
62 {KEX_DH_GRP18_SHA512, "diffie-hellman-group18-sha512", EVP_sha512}, // RFC8268
63 {KEX_DH_NONE , NULL, NULL},
64 };
65
66
67 extern SSHKeys current_keys[MODE_MAX];
68
69
70 char* get_kex_algorithm_name(kex_algorithm kextype)
71 {
72 const struct ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms;
73
74 while (ptr->name != NULL) {
75 if (kextype == ptr->kextype) {
76 return ptr->name;
77 }
78 ptr++;
79 }
80
81 // not found.
82 return "unknown";
83 }
84
85 const EVP_MD* get_kex_algorithm_EVP_MD(kex_algorithm kextype)
86 {
87 const struct ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms;
88
89 while (ptr->name != NULL) {
90 if (kextype == ptr->kextype) {
91 return ptr->evp_md();
92 }
93 ptr++;
94 }
95
96 // not found.
97 return EVP_md_null();
98 }
99
100 void normalize_kex_order(char *buf)
101 {
102 static char default_strings[] = {
103 KEX_ECDH_SHA2_256,
104 KEX_ECDH_SHA2_384,
105 KEX_ECDH_SHA2_521,
106 KEX_DH_GRP18_SHA512,
107 KEX_DH_GRP16_SHA512,
108 KEX_DH_GRP14_SHA256,
109 KEX_DH_GEX_SHA256,
110 KEX_DH_GEX_SHA1,
111 KEX_DH_GRP14_SHA1,
112 KEX_DH_GRP1_SHA1,
113 KEX_DH_NONE,
114 };
115
116 normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
117 }
118
119 kex_algorithm choose_SSH2_kex_algorithm(char *server_proposal, char *my_proposal)
120 {
121 kex_algorithm type = KEX_DH_UNKNOWN;
122 char str_kextype[40];
123 const struct ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms;
124
125 choose_SSH2_proposal(server_proposal, my_proposal, str_kextype, sizeof(str_kextype));
126
127 while (ptr->name != NULL) {
128 if (strcmp(ptr->name, str_kextype) == 0) {
129 type = ptr->kextype;
130 break;
131 }
132 ptr++;
133 }
134
135 return (type);
136 }
137
138 // KEX�A���S���Y���D���������������Amyproposal[]�������������B
139 // (2011.2.28 yutaka)
140 void SSH2_update_kex_myproposal(PTInstVar pvar)
141 {
142 static char buf[512]; // TODO: malloc()��������
143 int index;
144 int len, i;
145
146 // ���M�������������������������A�O�������B(2006.6.26 maya)
147 if (pvar->socket != INVALID_SOCKET) {
148 return;
149 }
150
151 buf[0] = '\0';
152 for (i = 0 ; pvar->settings.KexOrder[i] != 0 ; i++) {
153 index = pvar->settings.KexOrder[i] - '0';
154 if (index == KEX_DH_NONE) // disabled line
155 break;
156 strncat_s(buf, sizeof(buf), get_kex_algorithm_name(index), _TRUNCATE);
157 strncat_s(buf, sizeof(buf), ",", _TRUNCATE);
158 }
159 len = strlen(buf);
160 if (len > 0)
161 buf[len - 1] = '\0'; // get rid of comma
162 myproposal[PROPOSAL_KEX_ALGS] = buf;
163 }
164
165
166 static DH *dh_new_group_asc(const char *gen, const char *modulus)
167 {
168 DH *dh = NULL;
169 BIGNUM *p = NULL, *g = NULL;
170
171 if ((dh = DH_new()) == NULL) {
172 printf("dh_new_group_asc: DH_new");
173 goto error;
174 }
175
176 // P��G�����J�����������f�����g��������
177 if (BN_hex2bn(&p, modulus) == 0) {
178 printf("BN_hex2bn p");
179 goto error;
180 }
181
182 if (BN_hex2bn(&g, gen) == 0) {
183 printf("BN_hex2bn g");
184 goto error;
185 }
186
187 // BN_hex2bn()�����������|�C���^��DH�\�������Z�b�g�����B
188 DH_set0_pqg(dh, p, NULL, g);
189
190 return (dh);
191
192 error:
193 BN_free(g);
194 BN_free(p);
195 DH_free(dh);
196 return (NULL);
197 }
198
199
200 DH *dh_new_group1(void)
201 {
202 static char *gen = "2", *group1 =
203 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
204 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
205 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
206 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
207 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
208 "FFFFFFFF" "FFFFFFFF";
209
210 return (dh_new_group_asc(gen, group1));
211 }
212
213
214 DH *dh_new_group14(void)
215 {
216 static char *gen = "2", *group14 =
217 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
218 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
219 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
220 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
221 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
222 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
223 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
224 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
225 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
226 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
227 "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
228
229 return (dh_new_group_asc(gen, group14));
230 }
231
232 // ���g�p
233 DH *dh_new_group15(void)
234 {
235 static char *gen = "2", *group15 =
236 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
237 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
238 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
239 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
240 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
241 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
242 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
243 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
244 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
245 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
246 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
247 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
248 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
249 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
250 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
251 "43DB5BFC" "E0FD108E" "4B82D120" "A93AD2CA" "FFFFFFFF" "FFFFFFFF";
252 return (dh_new_group_asc(gen, group15));
253 }
254
255 DH *dh_new_group16(void)
256 {
257 static char *gen = "2", *group16 =
258 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
259 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
260 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
261 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
262 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
263 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
264 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
265 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
266 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
267 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
268 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
269 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
270 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
271 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
272 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
273 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
274 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
275 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
276 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
277 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
278 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199"
279 "FFFFFFFF" "FFFFFFFF";
280 return (dh_new_group_asc(gen, group16));
281 }
282
283 // ���g�p
284 DH *dh_new_group17(void)
285 {
286 static char *gen = "2", *group17 =
287 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" "29024E08"
288 "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" "EF9519B3" "CD3A431B"
289 "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" "E485B576" "625E7EC6" "F44C42E9"
290 "A637ED6B" "0BFF5CB6" "F406B7ED" "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6"
291 "49286651" "ECE45B3D" "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8"
292 "FD24CF5F" "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
293 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B" "E39E772C"
294 "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9" "DE2BCBF6" "95581718"
295 "3995497C" "EA956AE5" "15D22618" "98FA0510" "15728E5A" "8AAAC42D" "AD33170D"
296 "04507A33" "A85521AB" "DF1CBA64" "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D"
297 "B3970F85" "A6E1E4C7" "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226"
298 "1AD2EE6B" "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
299 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31" "43DB5BFC"
300 "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7" "88719A10" "BDBA5B26"
301 "99C32718" "6AF4E23C" "1A946834" "B6150BDA" "2583E9CA" "2AD44CE8" "DBBBC2DB"
302 "04DE8EF9" "2E8EFC14" "1FBECAA6" "287C5947" "4E6BC05D" "99B2964F" "A090C3A2"
303 "233BA186" "515BE7ED" "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127"
304 "D5B05AA9" "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
305 "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD" "F8FF9406"
306 "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831" "179727B0" "865A8918"
307 "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B" "DB7F1447" "E6CC254B" "33205151"
308 "2BD7AF42" "6FB8F401" "378CD2BF" "5983CA01" "C64B92EC" "F032EA15" "D1721D03"
309 "F482D7CE" "6E74FEF6" "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F"
310 "BEC7E8F3" "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
311 "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328" "06A1D58B"
312 "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C" "DA56C9EC" "2EF29632"
313 "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE" "12BF2D5B" "0B7474D6" "E694F91E"
314 "6DCC4024" "FFFFFFFF" "FFFFFFFF";
315 return (dh_new_group_asc(gen, group17));
316 }
317
318 DH *dh_new_group18(void)
319 {
320 static char *gen = "2", *group18 =
321 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
322 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
323 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
324 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
325 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
326 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
327 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
328 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
329 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
330 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
331 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
332 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
333 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
334 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
335 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
336 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
337 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
338 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
339 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
340 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
341 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
342 "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD"
343 "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831"
344 "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B"
345 "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF"
346 "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6"
347 "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3"
348 "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
349 "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328"
350 "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C"
351 "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE"
352 "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4"
353 "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300"
354 "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568"
355 "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9"
356 "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B"
357 "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A"
358 "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36"
359 "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1"
360 "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92"
361 "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47"
362 "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71"
363 "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF";
364 return (dh_new_group_asc(gen, group18));
365 }
366
367
368 // DH������������
369 void dh_gen_key(PTInstVar pvar, DH *dh, int we_need /* bytes */ )
370 {
371 int i;
372 BIGNUM *pub_key;
373 BIGNUM *priv_key;
374
375 priv_key = NULL;
376
377 // ����������������(X)������
378 for (i = 0 ; i < 10 ; i++) { // retry counter
379 if (priv_key != NULL) {
380 BN_clear_free(priv_key);
381 }
382 priv_key = BN_new();
383 DH_set0_key(dh, NULL, priv_key);
384 if (priv_key == NULL)
385 goto error;
386 if (BN_rand(priv_key, 2*(we_need*8), 0, 0) == 0)
387 goto error;
388 if (DH_generate_key(dh) == 0)
389 goto error;
390 DH_get0_key(dh, &pub_key, NULL);
391 if (dh_pub_is_valid(dh, pub_key))
392 break;
393 }
394 if (i >= 10) {
395 goto error;
396 }
397 return;
398
399 error:;
400 notify_fatal_error(pvar, "error occurred @ dh_gen_key()", TRUE);
401
402 }
403
404
405 int dh_estimate(int bits)
406 {
407 if (bits <= 112)
408 return 2048;
409 if (bits <= 128)
410 return 3072;
411 if (bits <= 192)
412 return 7680;
413 return 8192;
414 }
415
416
417 // shared secret ���v�Z���� (DH �����O���[�v�p)
418 unsigned char *kex_dh_hash(const EVP_MD *evp_md,
419 char *client_version_string,
420 char *server_version_string,
421 char *ckexinit, int ckexinitlen,
422 char *skexinit, int skexinitlen,
423 u_char *serverhostkeyblob, int sbloblen,
424 BIGNUM *client_dh_pub,
425 BIGNUM *server_dh_pub,
426 BIGNUM *shared_secret,
427 unsigned int *hashlen)
428 {
429 buffer_t *b;
430 static unsigned char digest[EVP_MAX_MD_SIZE];
431 EVP_MD_CTX *md = NULL;
432
433 md = EVP_MD_CTX_new();
434 if (md == NULL)
435 goto error;
436
437 b = buffer_init();
438 buffer_put_string(b, client_version_string, strlen(client_version_string));
439 buffer_put_string(b, server_version_string, strlen(server_version_string));
440
441 /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
442 buffer_put_int(b, ckexinitlen+1);
443 buffer_put_char(b, SSH2_MSG_KEXINIT);
444 buffer_append(b, ckexinit, ckexinitlen);
445 buffer_put_int(b, skexinitlen+1);
446 buffer_put_char(b, SSH2_MSG_KEXINIT);
447 buffer_append(b, skexinit, skexinitlen);
448
449 buffer_put_string(b, serverhostkeyblob, sbloblen);
450 buffer_put_bignum2(b, client_dh_pub);
451 buffer_put_bignum2(b, server_dh_pub);
452 buffer_put_bignum2(b, shared_secret);
453
454 // yutaka
455 //debug_print(38, buffer_ptr(b), buffer_len(b));
456
457 EVP_DigestInit(md, evp_md);
458 EVP_DigestUpdate(md, buffer_ptr(b), buffer_len(b));
459 EVP_DigestFinal(md, digest, NULL);
460
461 buffer_free(b);
462
463 //write_buffer_file(digest, EVP_MD_size(evp_md));
464
465 *hashlen = EVP_MD_size(evp_md);
466
467 error:
468 if (md)
469 EVP_MD_CTX_free(md);
470
471 return digest;
472 }
473
474
475 // shared secret ���v�Z���� (DH GEX�p)
476 unsigned char *kex_dh_gex_hash(const EVP_MD *evp_md,
477 char *client_version_string,
478 char *server_version_string,
479 char *ckexinit, int ckexinitlen,
480 char *skexinit, int skexinitlen,
481 u_char *serverhostkeyblob, int sbloblen,
482 int kexgex_min,
483 int kexgex_bits,
484 int kexgex_max,
485 BIGNUM *kexgex_p,
486 BIGNUM *kexgex_g,
487 BIGNUM *client_dh_pub,
488 BIGNUM *server_dh_pub,
489 BIGNUM *shared_secret,
490 unsigned int *hashlen)
491 {
492 buffer_t *b;
493 static unsigned char digest[EVP_MAX_MD_SIZE];
494 EVP_MD_CTX *md = NULL;
495
496 md = EVP_MD_CTX_new();
497 if (md == NULL)
498 goto error;
499
500 b = buffer_init();
501 buffer_put_string(b, client_version_string, strlen(client_version_string));
502 buffer_put_string(b, server_version_string, strlen(server_version_string));
503
504 /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
505 buffer_put_int(b, ckexinitlen+1);
506 buffer_put_char(b, SSH2_MSG_KEXINIT);
507 buffer_append(b, ckexinit, ckexinitlen);
508 buffer_put_int(b, skexinitlen+1);
509 buffer_put_char(b, SSH2_MSG_KEXINIT);
510 buffer_append(b, skexinit, skexinitlen);
511
512 buffer_put_string(b, serverhostkeyblob, sbloblen);
513
514 // DH group size���r�b�g�������Z����
515 buffer_put_int(b, kexgex_min);
516 buffer_put_int(b, kexgex_bits);
517 buffer_put_int(b, kexgex_max);
518
519 // DH�����f���������������Z����
520 buffer_put_bignum2(b, kexgex_p);
521 buffer_put_bignum2(b, kexgex_g);
522
523 buffer_put_bignum2(b, client_dh_pub);
524 buffer_put_bignum2(b, server_dh_pub);
525 buffer_put_bignum2(b, shared_secret);
526
527 // yutaka
528 //debug_print(38, buffer_ptr(b), buffer_len(b));
529
530 EVP_DigestInit(md, evp_md);
531 EVP_DigestUpdate(md, buffer_ptr(b), buffer_len(b));
532 EVP_DigestFinal(md, digest, NULL);
533
534 buffer_free(b);
535
536 //write_buffer_file(digest, EVP_MD_size(evp_md));
537
538 *hashlen = EVP_MD_size(evp_md);
539
540 error:
541 if (md)
542 EVP_MD_CTX_free(md);
543
544 return digest;
545 }
546
547
548 unsigned char *kex_ecdh_hash(const EVP_MD *evp_md,
549 const EC_GROUP *ec_group,
550 char *client_version_string,
551 char *server_version_string,
552 char *ckexinit, int ckexinitlen,
553 char *skexinit, int skexinitlen,
554 u_char *serverhostkeyblob, int sbloblen,
555 const EC_POINT *client_dh_pub,
556 const EC_POINT *server_dh_pub,
557 BIGNUM *shared_secret,
558 unsigned int *hashlen)
559 {
560 buffer_t *b;
561 static unsigned char digest[EVP_MAX_MD_SIZE];
562 EVP_MD_CTX *md = NULL;
563
564 md = EVP_MD_CTX_new();
565 if (md == NULL)
566 goto error;
567
568 b = buffer_init();
569 buffer_put_string(b, client_version_string, strlen(client_version_string));
570 buffer_put_string(b, server_version_string, strlen(server_version_string));
571
572 /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
573 buffer_put_int(b, ckexinitlen+1);
574 buffer_put_char(b, SSH2_MSG_KEXINIT);
575 buffer_append(b, ckexinit, ckexinitlen);
576 buffer_put_int(b, skexinitlen+1);
577 buffer_put_char(b, SSH2_MSG_KEXINIT);
578 buffer_append(b, skexinit, skexinitlen);
579
580 buffer_put_string(b, serverhostkeyblob, sbloblen);
581
582 buffer_put_ecpoint(b, ec_group, client_dh_pub);
583 buffer_put_ecpoint(b, ec_group, server_dh_pub);
584 buffer_put_bignum2(b, shared_secret);
585
586 // yutaka
587 //debug_print(38, buffer_ptr(b), buffer_len(b));
588
589 EVP_DigestInit(md, evp_md);
590 EVP_DigestUpdate(md, buffer_ptr(b), buffer_len(b));
591 EVP_DigestFinal(md, digest, NULL);
592
593 buffer_free(b);
594
595 //write_buffer_file(digest, EVP_MD_size(evp_md));
596
597 *hashlen = EVP_MD_size(evp_md);
598
599 error:
600 if (md)
601 EVP_MD_CTX_free(md);
602
603 return digest;
604 }
605
606
607 int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
608 {
609 int i;
610 int n = BN_num_bits(dh_pub);
611 int bits_set = 0;
612 const BIGNUM *p;
613
614 // OpenSSL 1.1.0���ABIGNUM�\������neg�����o�[�������A�N�Z�X�������������������A
615 // BN_is_negative�������u�������BOpenSSL 1.0.2�����}�N�����`���������������A
616 // OpenSSL 1.0.2�����A�����������������B
617 if (BN_is_negative(dh_pub)) {
618 //logit("invalid public DH value: negativ");
619 return 0;
620 }
621 for (i = 0; i <= n; i++)
622 if (BN_is_bit_set(dh_pub, i))
623 bits_set++;
624 //debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
625
626 /* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */
627 DH_get0_pqg(dh, &p, NULL, NULL);
628 if (bits_set > 1 && (BN_cmp(dh_pub, p) == -1))
629 return 1;
630 //logit("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p));
631 return 0;
632 }
633
634
635 static u_char *derive_key(int id, int need, u_char *hash, BIGNUM *shared_secret,
636 char *session_id, int session_id_len,
637 const EVP_MD *evp_md)
638 {
639 buffer_t *b;
640 EVP_MD_CTX *md = NULL;
641 char c = id;
642 int have;
643 int mdsz = EVP_MD_size(evp_md);
644 u_char *digest = malloc(roundup(need, mdsz));
645
646 md = EVP_MD_CTX_new();
647 if (md == NULL)
648 goto skip;
649
650 if (digest == NULL)
651 goto skip;
652
653 b = buffer_init();
654 if (b == NULL)
655 goto skip;
656
657 buffer_put_bignum2(b, shared_secret);
658
659 /* K1 = HASH(K || H || "A" || session_id) */
660 EVP_DigestInit(md, evp_md);
661 EVP_DigestUpdate(md, buffer_ptr(b), buffer_len(b));
662 EVP_DigestUpdate(md, hash, mdsz);
663 EVP_DigestUpdate(md, &c, 1);
664 EVP_DigestUpdate(md, session_id, session_id_len);
665 EVP_DigestFinal(md, digest, NULL);
666
667 /*
668 * expand key:
669 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
670 * Key = K1 || K2 || ... || Kn
671 */
672 for (have = mdsz; need > have; have += mdsz) {
673 EVP_DigestInit(md, evp_md);
674 EVP_DigestUpdate(md, buffer_ptr(b), buffer_len(b));
675 EVP_DigestUpdate(md, hash, mdsz);
676 EVP_DigestUpdate(md, digest, have);
677 EVP_DigestFinal(md, digest + have, NULL);
678 }
679 buffer_free(b);
680
681 skip:;
682 if (md)
683 EVP_MD_CTX_free(md);
684
685 return digest;
686 }
687
688
689 void kex_derive_keys(PTInstVar pvar, int need, u_char *hash, BIGNUM *shared_secret,
690 char *session_id, int session_id_len)
691 {
692 #define NKEYS 6
693 u_char *keys[NKEYS];
694 int i, mode, ctos;
695
696 for (i = 0; i < NKEYS; i++) {
697 keys[i] = derive_key('A'+i, need, hash, shared_secret, session_id, session_id_len,
698 get_kex_algorithm_EVP_MD(pvar->kex_type));
699 //debug_print(i, keys[i], need);
700 }
701
702 for (mode = 0; mode < MODE_MAX; mode++) {
703 if (mode == MODE_OUT)
704 ctos = 1;
705 else
706 ctos = 0;
707
708 #if 0
709 // free already allocated buffer (2004.12.27 yutaka)
710 // �L�[����������MAC corrupt���������������B(2005.1.5 yutaka)
711 if (current_keys[mode].enc.iv != NULL)
712 free(current_keys[mode].enc.iv);
713 if (current_keys[mode].enc.key != NULL)
714 free(current_keys[mode].enc.key);
715 if (current_keys[mode].mac.key != NULL)
716 free(current_keys[mode].mac.key);
717 #endif
718
719 // setting
720 current_keys[mode].enc.iv = keys[ctos ? 0 : 1];
721 current_keys[mode].enc.key = keys[ctos ? 2 : 3];
722 current_keys[mode].mac.key = keys[ctos ? 4 : 5];
723
724 //debug_print(20 + mode*3, current_keys[mode]->enc.iv, 8);
725 //debug_print(21 + mode*3, current_keys[mode]->enc.key, 24);
726 //debug_print(22 + mode*3, current_keys[mode]->mac.key, 24);
727 }
728 }

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