Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / dropbear / common-algo.c
blobe57f37cdc4977fa13a3c60ff8ca8cf7210f61a44
1 /*
2 * Dropbear SSH
3 *
4 * Copyright (c) 2002,2003 Matt Johnston
5 * Copyright (c) 2004 by Mihnea Stoenescu
6 * All rights reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE. */
26 #include "includes.h"
27 #include "algo.h"
28 #include "session.h"
29 #include "dbutil.h"
30 #include "kex.h"
31 #include "ltc_prng.h"
32 #include "ecc.h"
34 /* This file (algo.c) organises the ciphers which can be used, and is used to
35 * decide which ciphers/hashes/compression/signing to use during key exchange*/
37 static int void_cipher(const unsigned char* in, unsigned char* out,
38 unsigned long len, void* UNUSED(cipher_state)) {
39 if (in != out) {
40 memmove(out, in, len);
42 return CRYPT_OK;
45 static int void_start(int UNUSED(cipher), const unsigned char* UNUSED(IV),
46 const unsigned char* UNUSED(key),
47 int UNUSED(keylen), int UNUSED(num_rounds), void* UNUSED(cipher_state)) {
48 return CRYPT_OK;
51 /* Mappings for ciphers, parameters are
52 {&cipher_desc, keysize, blocksize} */
54 /* Remember to add new ciphers/hashes to regciphers/reghashes too */
56 #ifdef DROPBEAR_AES256
57 static const struct dropbear_cipher dropbear_aes256 =
58 {&aes_desc, 32, 16};
59 #endif
60 #ifdef DROPBEAR_AES128
61 static const struct dropbear_cipher dropbear_aes128 =
62 {&aes_desc, 16, 16};
63 #endif
64 #ifdef DROPBEAR_BLOWFISH
65 static const struct dropbear_cipher dropbear_blowfish =
66 {&blowfish_desc, 16, 8};
67 #endif
68 #ifdef DROPBEAR_TWOFISH256
69 static const struct dropbear_cipher dropbear_twofish256 =
70 {&twofish_desc, 32, 16};
71 #endif
72 #ifdef DROPBEAR_TWOFISH128
73 static const struct dropbear_cipher dropbear_twofish128 =
74 {&twofish_desc, 16, 16};
75 #endif
76 #ifdef DROPBEAR_3DES
77 static const struct dropbear_cipher dropbear_3des =
78 {&des3_desc, 24, 8};
79 #endif
81 /* used to indicate no encryption, as defined in rfc2410 */
82 const struct dropbear_cipher dropbear_nocipher =
83 {NULL, 16, 8};
85 /* A few void* s are required to silence warnings
86 * about the symmetric_CBC vs symmetric_CTR cipher_state pointer */
87 const struct dropbear_cipher_mode dropbear_mode_cbc =
88 {(void*)cbc_start, (void*)cbc_encrypt, (void*)cbc_decrypt};
89 const struct dropbear_cipher_mode dropbear_mode_none =
90 {void_start, void_cipher, void_cipher};
91 #ifdef DROPBEAR_ENABLE_CTR_MODE
92 /* a wrapper to make ctr_start and cbc_start look the same */
93 static int dropbear_big_endian_ctr_start(int cipher,
94 const unsigned char *IV,
95 const unsigned char *key, int keylen,
96 int num_rounds, symmetric_CTR *ctr) {
97 return ctr_start(cipher, IV, key, keylen, num_rounds, CTR_COUNTER_BIG_ENDIAN, ctr);
99 const struct dropbear_cipher_mode dropbear_mode_ctr =
100 {(void*)dropbear_big_endian_ctr_start, (void*)ctr_encrypt, (void*)ctr_decrypt};
101 #endif
103 /* Mapping of ssh hashes to libtomcrypt hashes, including keysize etc.
104 {&hash_desc, keysize, hashsize} */
106 #ifdef DROPBEAR_SHA1_HMAC
107 static const struct dropbear_hash dropbear_sha1 =
108 {&sha1_desc, 20, 20};
109 #endif
110 #ifdef DROPBEAR_SHA1_96_HMAC
111 static const struct dropbear_hash dropbear_sha1_96 =
112 {&sha1_desc, 20, 12};
113 #endif
114 #ifdef DROPBEAR_SHA2_256_HMAC
115 static const struct dropbear_hash dropbear_sha2_256 =
116 {&sha256_desc, 32, 32};
117 #endif
118 #ifdef DROPBEAR_SHA2_512_HMAC
119 static const struct dropbear_hash dropbear_sha2_512 =
120 {&sha512_desc, 64, 64};
121 #endif
122 #ifdef DROPBEAR_MD5_HMAC
123 static const struct dropbear_hash dropbear_md5 =
124 {&md5_desc, 16, 16};
125 #endif
127 const struct dropbear_hash dropbear_nohash =
128 {NULL, 16, 0}; /* used initially */
131 /* The following map ssh names to internal values.
132 * The ordering here is important for the client - the first mode
133 * that is also supported by the server will get used. */
135 algo_type sshciphers[] = {
136 #ifdef DROPBEAR_ENABLE_CTR_MODE
137 #ifdef DROPBEAR_AES128
138 {"aes128-ctr", 0, &dropbear_aes128, 1, &dropbear_mode_ctr},
139 #endif
140 #ifdef DROPBEAR_3DES
141 {"3des-ctr", 0, &dropbear_3des, 1, &dropbear_mode_ctr},
142 #endif
143 #ifdef DROPBEAR_AES256
144 {"aes256-ctr", 0, &dropbear_aes256, 1, &dropbear_mode_ctr},
145 #endif
146 #endif /* DROPBEAR_ENABLE_CTR_MODE */
148 /* CBC modes are always enabled */
149 #ifdef DROPBEAR_AES128
150 {"aes128-cbc", 0, &dropbear_aes128, 1, &dropbear_mode_cbc},
151 #endif
152 #ifdef DROPBEAR_3DES
153 {"3des-cbc", 0, &dropbear_3des, 1, &dropbear_mode_cbc},
154 #endif
155 #ifdef DROPBEAR_AES256
156 {"aes256-cbc", 0, &dropbear_aes256, 1, &dropbear_mode_cbc},
157 #endif
158 #ifdef DROPBEAR_TWOFISH256
159 {"twofish256-cbc", 0, &dropbear_twofish256, 1, &dropbear_mode_cbc},
160 {"twofish-cbc", 0, &dropbear_twofish256, 1, &dropbear_mode_cbc},
161 #endif
162 #ifdef DROPBEAR_TWOFISH128
163 {"twofish128-cbc", 0, &dropbear_twofish128, 1, &dropbear_mode_cbc},
164 #endif
165 #ifdef DROPBEAR_BLOWFISH
166 {"blowfish-cbc", 0, &dropbear_blowfish, 1, &dropbear_mode_cbc},
167 #endif
168 #ifdef DROPBEAR_NONE_CIPHER
169 {"none", 0, (void*)&dropbear_nocipher, 1, &dropbear_mode_none},
170 #endif
171 {NULL, 0, NULL, 0, NULL}
174 algo_type sshhashes[] = {
175 #ifdef DROPBEAR_SHA2_256_HMAC
176 {"hmac-sha2-256", 0, &dropbear_sha2_256, 1, NULL},
177 #endif
178 #ifdef DROPBEAR_SHA2_512_HMAC
179 {"hmac-sha2-512", 0, &dropbear_sha2_512, 1, NULL},
180 #endif
181 #ifdef DROPBEAR_SHA1_96_HMAC
182 {"hmac-sha1-96", 0, &dropbear_sha1_96, 1, NULL},
183 #endif
184 #ifdef DROPBEAR_SHA1_HMAC
185 {"hmac-sha1", 0, &dropbear_sha1, 1, NULL},
186 #endif
187 #ifdef DROPBEAR_MD5_HMAC
188 {"hmac-md5", 0, (void*)&dropbear_md5, 1, NULL},
189 #endif
190 #ifdef DROPBEAR_NONE_INTEGRITY
191 {"none", 0, (void*)&dropbear_nohash, 1, NULL},
192 #endif
193 {NULL, 0, NULL, 0, NULL}
196 #ifndef DISABLE_ZLIB
197 algo_type ssh_compress[] = {
198 {"zlib", DROPBEAR_COMP_ZLIB, NULL, 1, NULL},
199 {"zlib@openssh.com", DROPBEAR_COMP_ZLIB_DELAY, NULL, 1, NULL},
200 {"none", DROPBEAR_COMP_NONE, NULL, 1, NULL},
201 {NULL, 0, NULL, 0, NULL}
203 #endif
205 algo_type ssh_nocompress[] = {
206 {"none", DROPBEAR_COMP_NONE, NULL, 1, NULL},
207 {NULL, 0, NULL, 0, NULL}
210 algo_type sshhostkey[] = {
211 #ifdef DROPBEAR_ECDSA
212 #ifdef DROPBEAR_ECC_256
213 {"ecdsa-sha2-nistp256", DROPBEAR_SIGNKEY_ECDSA_NISTP256, NULL, 1, NULL},
214 #endif
215 #ifdef DROPBEAR_ECC_384
216 {"ecdsa-sha2-nistp384", DROPBEAR_SIGNKEY_ECDSA_NISTP384, NULL, 1, NULL},
217 #endif
218 #ifdef DROPBEAR_ECC_521
219 {"ecdsa-sha2-nistp521", DROPBEAR_SIGNKEY_ECDSA_NISTP521, NULL, 1, NULL},
220 #endif
221 #endif
222 #ifdef DROPBEAR_RSA
223 {"ssh-rsa", DROPBEAR_SIGNKEY_RSA, NULL, 1, NULL},
224 #endif
225 #ifdef DROPBEAR_DSS
226 {"ssh-dss", DROPBEAR_SIGNKEY_DSS, NULL, 1, NULL},
227 #endif
228 {NULL, 0, NULL, 0, NULL}
231 static const struct dropbear_kex kex_dh_group1 = {DROPBEAR_KEX_NORMAL_DH, dh_p_1, DH_P_1_LEN, NULL, &sha1_desc };
232 static const struct dropbear_kex kex_dh_group14 = {DROPBEAR_KEX_NORMAL_DH, dh_p_14, DH_P_14_LEN, NULL, &sha1_desc };
234 /* These can't be const since dropbear_ecc_fill_dp() fills out
235 ecc_curve at runtime */
236 #ifdef DROPBEAR_ECDH
237 #ifdef DROPBEAR_ECC_256
238 static struct dropbear_kex kex_ecdh_nistp256 = {DROPBEAR_KEX_ECDH, NULL, 0, &ecc_curve_nistp256, &sha256_desc };
239 #endif
240 #ifdef DROPBEAR_ECC_384
241 static struct dropbear_kex kex_ecdh_nistp384 = {DROPBEAR_KEX_ECDH, NULL, 0, &ecc_curve_nistp384, &sha384_desc };
242 #endif
243 #ifdef DROPBEAR_ECC_521
244 static struct dropbear_kex kex_ecdh_nistp521 = {DROPBEAR_KEX_ECDH, NULL, 0, &ecc_curve_nistp521, &sha512_desc };
245 #endif
246 #endif /* DROPBEAR_ECDH */
248 #ifdef DROPBEAR_CURVE25519
249 /* Referred to directly */
250 static const struct dropbear_kex kex_curve25519 = {DROPBEAR_KEX_CURVE25519, NULL, 0, NULL, &sha256_desc };
251 #endif
253 algo_type sshkex[] = {
254 #ifdef DROPBEAR_CURVE25519
255 {"curve25519-sha256@libssh.org", 0, &kex_curve25519, 1, NULL},
256 #endif
257 #ifdef DROPBEAR_ECDH
258 #ifdef DROPBEAR_ECC_521
259 {"ecdh-sha2-nistp521", 0, &kex_ecdh_nistp521, 1, NULL},
260 #endif
261 #ifdef DROPBEAR_ECC_384
262 {"ecdh-sha2-nistp384", 0, &kex_ecdh_nistp384, 1, NULL},
263 #endif
264 #ifdef DROPBEAR_ECC_256
265 {"ecdh-sha2-nistp256", 0, &kex_ecdh_nistp256, 1, NULL},
266 #endif
267 #endif
268 {"diffie-hellman-group1-sha1", 0, &kex_dh_group1, 1, NULL},
269 {"diffie-hellman-group14-sha1", 0, &kex_dh_group14, 1, NULL},
270 #ifdef USE_KEXGUESS2
271 {KEXGUESS2_ALGO_NAME, KEXGUESS2_ALGO_ID, NULL, 1, NULL},
272 #endif
273 {NULL, 0, NULL, 0, NULL}
276 /* algolen specifies the length of algo, algos is our local list to match
277 * against.
278 * Returns DROPBEAR_SUCCESS if we have a match for algo, DROPBEAR_FAILURE
279 * otherwise */
280 int have_algo(char* algo, size_t algolen, algo_type algos[]) {
282 int i;
284 for (i = 0; algos[i].name != NULL; i++) {
285 if (strlen(algos[i].name) == algolen
286 && (strncmp(algos[i].name, algo, algolen) == 0)) {
287 return DROPBEAR_SUCCESS;
291 return DROPBEAR_FAILURE;
294 /* Output a comma separated list of algorithms to a buffer */
295 void buf_put_algolist(buffer * buf, algo_type localalgos[]) {
297 unsigned int i, len;
298 unsigned int donefirst = 0;
299 buffer *algolist = NULL;
301 algolist = buf_new(200);
302 for (i = 0; localalgos[i].name != NULL; i++) {
303 if (localalgos[i].usable) {
304 if (donefirst)
305 buf_putbyte(algolist, ',');
306 donefirst = 1;
307 len = strlen(localalgos[i].name);
308 buf_putbytes(algolist, localalgos[i].name, len);
311 buf_putstring(buf, algolist->data, algolist->len);
312 buf_free(algolist);
315 /* match the first algorithm in the comma-separated list in buf which is
316 * also in localalgos[], or return NULL on failure.
317 * (*goodguess) is set to 1 if the preferred client/server algos match,
318 * 0 otherwise. This is used for checking if the kexalgo/hostkeyalgos are
319 * guessed correctly */
320 algo_type * buf_match_algo(buffer* buf, algo_type localalgos[],
321 enum kexguess2_used *kexguess2, int *goodguess)
324 unsigned char * algolist = NULL;
325 const unsigned char *remotenames[MAX_PROPOSED_ALGO], *localnames[MAX_PROPOSED_ALGO];
326 unsigned int len;
327 unsigned int remotecount, localcount, clicount, servcount, i, j;
328 algo_type * ret = NULL;
329 const unsigned char **clinames, **servnames;
331 if (goodguess) {
332 *goodguess = 0;
335 /* get the comma-separated list from the buffer ie "algo1,algo2,algo3" */
336 algolist = buf_getstring(buf, &len);
337 TRACE(("buf_match_algo: %s", algolist))
338 if (len > MAX_PROPOSED_ALGO*(MAX_NAME_LEN+1)) {
339 goto out;
342 /* remotenames will contain a list of the strings parsed out */
343 /* We will have at least one string (even if it's just "") */
344 remotenames[0] = algolist;
345 remotecount = 1;
346 for (i = 0; i < len; i++) {
347 if (algolist[i] == '\0') {
348 /* someone is trying something strange */
349 goto out;
351 if (algolist[i] == ',') {
352 algolist[i] = '\0';
353 remotenames[remotecount] = &algolist[i+1];
354 remotecount++;
356 if (remotecount >= MAX_PROPOSED_ALGO) {
357 break;
360 if (kexguess2 && *kexguess2 == KEXGUESS2_LOOK) {
361 for (i = 0; i < remotecount; i++)
363 if (strcmp(remotenames[i], KEXGUESS2_ALGO_NAME) == 0) {
364 *kexguess2 = KEXGUESS2_YES;
365 break;
368 if (*kexguess2 == KEXGUESS2_LOOK) {
369 *kexguess2 = KEXGUESS2_NO;
373 for (i = 0; localalgos[i].name != NULL; i++) {
374 if (localalgos[i].usable) {
375 localnames[i] = localalgos[i].name;
376 } else {
377 localnames[i] = NULL;
380 localcount = i;
382 if (IS_DROPBEAR_SERVER) {
383 clinames = remotenames;
384 clicount = remotecount;
385 servnames = localnames;
386 servcount = localcount;
387 } else {
388 clinames = localnames;
389 clicount = localcount;
390 servnames = remotenames;
391 servcount = remotecount;
394 /* iterate and find the first match */
395 for (i = 0; i < clicount; i++) {
396 for (j = 0; j < servcount; j++) {
397 if (!(servnames[j] && clinames[i])) {
398 /* unusable algos are NULL */
399 continue;
401 if (strcmp(servnames[j], clinames[i]) == 0) {
402 /* set if it was a good guess */
403 if (goodguess && kexguess2) {
404 if (*kexguess2 == KEXGUESS2_YES) {
405 if (i == 0) {
406 *goodguess = 1;
409 } else {
410 if (i == 0 && j == 0) {
411 *goodguess = 1;
415 /* set the algo to return */
416 if (IS_DROPBEAR_SERVER) {
417 ret = &localalgos[j];
418 } else {
419 ret = &localalgos[i];
421 goto out;
426 out:
427 m_free(algolist);
428 return ret;
431 #ifdef DROPBEAR_NONE_CIPHER
433 void
434 set_algo_usable(algo_type algos[], const char * algo_name, int usable)
436 algo_type *a;
437 for (a = algos; a->name != NULL; a++)
439 if (strcmp(a->name, algo_name) == 0)
441 a->usable = usable;
442 return;
448 get_algo_usable(algo_type algos[], const char * algo_name)
450 algo_type *a;
451 for (a = algos; a->name != NULL; a++)
453 if (strcmp(a->name, algo_name) == 0)
455 return a->usable;
458 return 0;
461 #endif /* DROPBEAR_NONE_CIPHER */
463 #ifdef ENABLE_USER_ALGO_LIST
465 char *
466 algolist_string(algo_type algos[])
468 char *ret_list;
469 buffer *b = buf_new(200);
470 buf_put_algolist(b, algos);
471 buf_setpos(b, b->len);
472 buf_putbyte(b, '\0');
473 buf_setpos(b, 4);
474 ret_list = m_strdup(buf_getptr(b, b->len - b->pos));
475 buf_free(b);
476 return ret_list;
479 static algo_type*
480 check_algo(const char* algo_name, algo_type *algos)
482 algo_type *a;
483 for (a = algos; a->name != NULL; a++)
485 if (strcmp(a->name, algo_name) == 0)
487 return a;
491 return NULL;
494 static void
495 try_add_algo(const char *algo_name, algo_type *algos,
496 const char *algo_desc, algo_type * new_algos, int *num_ret)
498 algo_type *match_algo = check_algo(algo_name, algos);
499 if (!match_algo)
501 dropbear_log(LOG_WARNING, "This Dropbear program does not support '%s' %s algorithm", algo_name, algo_desc);
502 return;
505 new_algos[*num_ret] = *match_algo;
506 (*num_ret)++;
509 /* Checks a user provided comma-separated algorithm list for available
510 * options. Any that are not acceptable are removed in-place. Returns the
511 * number of valid algorithms. */
513 check_user_algos(const char* user_algo_list, algo_type * algos,
514 const char *algo_desc)
516 algo_type new_algos[MAX_PROPOSED_ALGO];
517 /* this has two passes. first we sweep through the given list of
518 * algorithms and mark them as usable=2 in the algo_type[] array... */
519 int num_ret = 0;
520 char *work_list = m_strdup(user_algo_list);
521 char *last_name = work_list;
522 char *c;
523 for (c = work_list; *c; c++)
525 if (*c == ',')
527 *c = '\0';
528 try_add_algo(last_name, algos, algo_desc, new_algos, &num_ret);
529 c++;
530 last_name = c;
533 try_add_algo(last_name, algos, algo_desc, new_algos, &num_ret);
534 m_free(work_list);
536 new_algos[num_ret].name = NULL;
538 /* Copy one more as a blank delimiter */
539 memcpy(algos, new_algos, sizeof(*new_algos) * (num_ret+1));
540 return num_ret;
542 #endif /* ENABLE_USER_ALGO_LIST */