4 * Copyright (c) 2002,2003 Matt Johnston
5 * Copyright (c) 2004 by Mihnea Stoenescu
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
30 /* This file (algo.c) organises the ciphers which can be used, and is used to
31 * decide which ciphers/hashes/compression/signing to use during key exchange*/
33 static int void_cipher(const unsigned char* in
, unsigned char* out
,
34 unsigned long len
, void *cipher_state
) {
36 memmove(out
, in
, len
);
41 static int void_start(int cipher
, const unsigned char *IV
,
42 const unsigned char *key
,
43 int keylen
, int num_rounds
, void *cipher_state
) {
47 /* Mappings for ciphers, parameters are
48 {&cipher_desc, keysize, blocksize} */
50 /* Remember to add new ciphers/hashes to regciphers/reghashes too */
52 #ifdef DROPBEAR_AES256
53 static const struct dropbear_cipher dropbear_aes256
=
56 #ifdef DROPBEAR_AES128
57 static const struct dropbear_cipher dropbear_aes128
=
60 #ifdef DROPBEAR_BLOWFISH
61 static const struct dropbear_cipher dropbear_blowfish
=
62 {&blowfish_desc
, 16, 8};
64 #ifdef DROPBEAR_TWOFISH256
65 static const struct dropbear_cipher dropbear_twofish256
=
66 {&twofish_desc
, 32, 16};
68 #ifdef DROPBEAR_TWOFISH128
69 static const struct dropbear_cipher dropbear_twofish128
=
70 {&twofish_desc
, 16, 16};
73 static const struct dropbear_cipher dropbear_3des
=
77 /* used to indicate no encryption, as defined in rfc2410 */
78 const struct dropbear_cipher dropbear_nocipher
=
81 /* A few void* s are required to silence warnings
82 * about the symmetric_CBC vs symmetric_CTR cipher_state pointer */
83 const struct dropbear_cipher_mode dropbear_mode_cbc
=
84 {(void*)cbc_start
, (void*)cbc_encrypt
, (void*)cbc_decrypt
};
85 const struct dropbear_cipher_mode dropbear_mode_none
=
86 {void_start
, void_cipher
, void_cipher
};
87 #ifdef DROPBEAR_ENABLE_CTR_MODE
88 /* a wrapper to make ctr_start and cbc_start look the same */
89 static int dropbear_big_endian_ctr_start(int cipher
,
90 const unsigned char *IV
,
91 const unsigned char *key
, int keylen
,
92 int num_rounds
, symmetric_CTR
*ctr
) {
93 return ctr_start(cipher
, IV
, key
, keylen
, num_rounds
, CTR_COUNTER_BIG_ENDIAN
, ctr
);
95 const struct dropbear_cipher_mode dropbear_mode_ctr
=
96 {(void*)dropbear_big_endian_ctr_start
, (void*)ctr_encrypt
, (void*)ctr_decrypt
};
99 /* Mapping of ssh hashes to libtomcrypt hashes, including keysize etc.
100 {&hash_desc, keysize, hashsize} */
102 #ifdef DROPBEAR_SHA1_HMAC
103 static const struct dropbear_hash dropbear_sha1
=
104 {&sha1_desc
, 20, 20};
106 #ifdef DROPBEAR_SHA1_96_HMAC
107 static const struct dropbear_hash dropbear_sha1_96
=
108 {&sha1_desc
, 20, 12};
110 #ifdef DROPBEAR_SHA2_256_HMAC
111 static const struct dropbear_hash dropbear_sha2_256
=
112 {&sha256_desc
, 32, 32};
114 #ifdef DROPBEAR_SHA2_512_HMAC
115 static const struct dropbear_hash dropbear_sha2_512
=
116 {&sha512_desc
, 64, 64};
118 #ifdef DROPBEAR_MD5_HMAC
119 static const struct dropbear_hash dropbear_md5
=
123 const struct dropbear_hash dropbear_nohash
=
124 {NULL
, 16, 0}; /* used initially */
127 /* The following map ssh names to internal values.
128 * The ordering here is important for the client - the first mode
129 * that is also supported by the server will get used. */
131 algo_type sshciphers
[] = {
132 #ifdef DROPBEAR_ENABLE_CTR_MODE
133 #ifdef DROPBEAR_AES128
134 {"aes128-ctr", 0, &dropbear_aes128
, 1, &dropbear_mode_ctr
},
137 {"3des-ctr", 0, &dropbear_3des
, 1, &dropbear_mode_ctr
},
139 #ifdef DROPBEAR_AES256
140 {"aes256-ctr", 0, &dropbear_aes256
, 1, &dropbear_mode_ctr
},
142 #endif /* DROPBEAR_ENABLE_CTR_MODE */
144 /* CBC modes are always enabled */
145 #ifdef DROPBEAR_AES128
146 {"aes128-cbc", 0, &dropbear_aes128
, 1, &dropbear_mode_cbc
},
149 {"3des-cbc", 0, &dropbear_3des
, 1, &dropbear_mode_cbc
},
151 #ifdef DROPBEAR_AES256
152 {"aes256-cbc", 0, &dropbear_aes256
, 1, &dropbear_mode_cbc
},
154 #ifdef DROPBEAR_TWOFISH256
155 {"twofish256-cbc", 0, &dropbear_twofish256
, 1, &dropbear_mode_cbc
},
156 {"twofish-cbc", 0, &dropbear_twofish256
, 1, &dropbear_mode_cbc
},
158 #ifdef DROPBEAR_TWOFISH128
159 {"twofish128-cbc", 0, &dropbear_twofish128
, 1, &dropbear_mode_cbc
},
161 #ifdef DROPBEAR_BLOWFISH
162 {"blowfish-cbc", 0, &dropbear_blowfish
, 1, &dropbear_mode_cbc
},
164 #ifdef DROPBEAR_NONE_CIPHER
165 {"none", 0, (void*)&dropbear_nocipher
, 1, &dropbear_mode_none
},
167 {NULL
, 0, NULL
, 0, NULL
}
170 algo_type sshhashes
[] = {
171 #ifdef DROPBEAR_SHA2_256_HMAC
172 {"hmac-sha2-256", 0, &dropbear_sha2_256
, 1, NULL
},
174 #ifdef DROPBEAR_SHA2_512_HMAC
175 {"hmac-sha2-512", 0, &dropbear_sha2_512
, 1, NULL
},
177 #ifdef DROPBEAR_SHA1_96_HMAC
178 {"hmac-sha1-96", 0, &dropbear_sha1_96
, 1, NULL
},
180 #ifdef DROPBEAR_SHA1_HMAC
181 {"hmac-sha1", 0, &dropbear_sha1
, 1, NULL
},
183 #ifdef DROPBEAR_MD5_HMAC
184 {"hmac-md5", 0, (void*)&dropbear_md5
, 1, NULL
},
186 #ifdef DROPBEAR_NONE_INTEGRITY
187 {"none", 0, (void*)&dropbear_nohash
, 1, NULL
},
189 {NULL
, 0, NULL
, 0, NULL
}
193 algo_type ssh_compress
[] = {
194 {"zlib", DROPBEAR_COMP_ZLIB
, NULL
, 1, NULL
},
195 {"zlib@openssh.com", DROPBEAR_COMP_ZLIB_DELAY
, NULL
, 1, NULL
},
196 {"none", DROPBEAR_COMP_NONE
, NULL
, 1, NULL
},
197 {NULL
, 0, NULL
, 0, NULL
}
201 algo_type ssh_nocompress
[] = {
202 {"none", DROPBEAR_COMP_NONE
, NULL
, 1, NULL
},
203 {NULL
, 0, NULL
, 0, NULL
}
206 algo_type sshhostkey
[] = {
208 {"ssh-rsa", DROPBEAR_SIGNKEY_RSA
, NULL
, 1, NULL
},
211 {"ssh-dss", DROPBEAR_SIGNKEY_DSS
, NULL
, 1, NULL
},
213 {NULL
, 0, NULL
, 0, NULL
}
216 algo_type sshkex
[] = {
217 {"diffie-hellman-group1-sha1", DROPBEAR_KEX_DH_GROUP1
, NULL
, 1, NULL
},
218 {"diffie-hellman-group14-sha1", DROPBEAR_KEX_DH_GROUP14
, NULL
, 1, NULL
},
220 {KEXGUESS2_ALGO_NAME
, KEXGUESS2_ALGO_ID
, NULL
, 1, NULL
},
222 {NULL
, 0, NULL
, 0, NULL
}
226 /* Register the compiled in ciphers.
227 * This should be run before using any of the ciphers/hashes */
230 const struct ltc_cipher_descriptor
*regciphers
[] = {
234 #ifdef DROPBEAR_BLOWFISH
237 #ifdef DROPBEAR_TWOFISH
246 const struct ltc_hash_descriptor
*reghashes
[] = {
247 /* we need sha1 for hostkey stuff regardless */
249 #ifdef DROPBEAR_MD5_HMAC
252 #ifdef DROPBEAR_SHA2_256_HMAC
255 #ifdef DROPBEAR_SHA2_512_HMAC
262 for (i
= 0; regciphers
[i
] != NULL
; i
++) {
263 if (register_cipher(regciphers
[i
]) == -1) {
264 dropbear_exit("Error registering crypto");
268 for (i
= 0; reghashes
[i
] != NULL
; i
++) {
269 if (register_hash(reghashes
[i
]) == -1) {
270 dropbear_exit("Error registering crypto");
275 /* algolen specifies the length of algo, algos is our local list to match
277 * Returns DROPBEAR_SUCCESS if we have a match for algo, DROPBEAR_FAILURE
279 int have_algo(char* algo
, size_t algolen
, algo_type algos
[]) {
283 for (i
= 0; algos
[i
].name
!= NULL
; i
++) {
284 if (strlen(algos
[i
].name
) == algolen
285 && (strncmp(algos
[i
].name
, algo
, algolen
) == 0)) {
286 return DROPBEAR_SUCCESS
;
290 return DROPBEAR_FAILURE
;
293 /* Output a comma separated list of algorithms to a buffer */
294 void buf_put_algolist(buffer
* buf
, algo_type localalgos
[]) {
297 unsigned int donefirst
= 0;
298 buffer
*algolist
= NULL
;
300 algolist
= buf_new(160);
301 for (i
= 0; localalgos
[i
].name
!= NULL
; i
++) {
302 if (localalgos
[i
].usable
) {
304 buf_putbyte(algolist
, ',');
306 len
= strlen(localalgos
[i
].name
);
307 buf_putbytes(algolist
, localalgos
[i
].name
, len
);
310 buf_putstring(buf
, algolist
->data
, algolist
->len
);
314 /* match the first algorithm in the comma-separated list in buf which is
315 * also in localalgos[], or return NULL on failure.
316 * (*goodguess) is set to 1 if the preferred client/server algos match,
317 * 0 otherwise. This is used for checking if the kexalgo/hostkeyalgos are
318 * guessed correctly */
319 algo_type
* buf_match_algo(buffer
* buf
, algo_type localalgos
[],
320 enum kexguess2_used
*kexguess2
, int *goodguess
)
323 unsigned char * algolist
= NULL
;
324 const unsigned char *remotenames
[MAX_PROPOSED_ALGO
], *localnames
[MAX_PROPOSED_ALGO
];
326 unsigned int remotecount
, localcount
, clicount
, servcount
, i
, j
;
327 algo_type
* ret
= NULL
;
328 const unsigned char **clinames
, **servnames
;
334 /* get the comma-separated list from the buffer ie "algo1,algo2,algo3" */
335 algolist
= buf_getstring(buf
, &len
);
336 TRACE(("buf_match_algo: %s", algolist
))
337 if (len
> MAX_PROPOSED_ALGO
*(MAX_NAME_LEN
+1)) {
341 /* remotenames will contain a list of the strings parsed out */
342 /* We will have at least one string (even if it's just "") */
343 remotenames
[0] = algolist
;
345 for (i
= 0; i
< len
; i
++) {
346 if (algolist
[i
] == '\0') {
347 /* someone is trying something strange */
350 if (algolist
[i
] == ',') {
352 remotenames
[remotecount
] = &algolist
[i
+1];
355 if (remotecount
>= MAX_PROPOSED_ALGO
) {
359 if (kexguess2
&& *kexguess2
== KEXGUESS2_LOOK
) {
360 for (i
= 0; i
< remotecount
; i
++)
362 if (strcmp(remotenames
[i
], KEXGUESS2_ALGO_NAME
) == 0) {
363 *kexguess2
= KEXGUESS2_YES
;
367 if (*kexguess2
== KEXGUESS2_LOOK
) {
368 *kexguess2
= KEXGUESS2_NO
;
372 for (i
= 0; localalgos
[i
].name
!= NULL
; i
++) {
373 if (localalgos
[i
].usable
) {
374 localnames
[i
] = localalgos
[i
].name
;
376 localnames
[i
] = NULL
;
381 if (IS_DROPBEAR_SERVER
) {
382 clinames
= remotenames
;
383 clicount
= remotecount
;
384 servnames
= localnames
;
385 servcount
= localcount
;
387 clinames
= localnames
;
388 clicount
= localcount
;
389 servnames
= remotenames
;
390 servcount
= remotecount
;
393 /* iterate and find the first match */
394 for (i
= 0; i
< clicount
; i
++) {
395 for (j
= 0; j
< servcount
; j
++) {
396 if (!(servnames
[j
] && clinames
[i
])) {
397 // unusable algos are NULL
400 if (strcmp(servnames
[j
], clinames
[i
]) == 0) {
401 /* set if it was a good guess */
402 if (goodguess
&& kexguess2
) {
403 if (*kexguess2
== KEXGUESS2_YES
) {
409 if (i
== 0 && j
== 0) {
414 /* set the algo to return */
415 if (IS_DROPBEAR_SERVER
) {
416 ret
= &localalgos
[j
];
418 ret
= &localalgos
[i
];
430 #ifdef DROPBEAR_NONE_CIPHER
433 set_algo_usable(algo_type algos
[], const char * algo_name
, int usable
)
436 for (a
= algos
; a
->name
!= NULL
; a
++)
438 if (strcmp(a
->name
, algo_name
) == 0)
447 get_algo_usable(algo_type algos
[], const char * algo_name
)
450 for (a
= algos
; a
->name
!= NULL
; a
++)
452 if (strcmp(a
->name
, algo_name
) == 0)
460 #endif // DROPBEAR_NONE_CIPHER
462 #ifdef ENABLE_USER_ALGO_LIST
465 algolist_string(algo_type algos
[])
468 buffer
*b
= buf_new(200);
469 buf_put_algolist(b
, algos
);
470 buf_setpos(b
, b
->len
);
471 buf_putbyte(b
, '\0');
473 ret_list
= m_strdup(buf_getptr(b
, b
->len
- b
->pos
));
479 check_algo(const char* algo_name
, algo_type
*algos
)
482 for (a
= algos
; a
->name
!= NULL
; a
++)
484 if (strcmp(a
->name
, algo_name
) == 0)
494 try_add_algo(const char *algo_name
, algo_type
*algos
,
495 const char *algo_desc
, algo_type
* new_algos
, int *num_ret
)
497 algo_type
*match_algo
= check_algo(algo_name
, algos
);
500 dropbear_log(LOG_WARNING
, "This Dropbear program does not support '%s' %s algorithm", algo_name
, algo_desc
);
504 new_algos
[*num_ret
] = *match_algo
;
508 /* Checks a user provided comma-separated algorithm list for available
509 * options. Any that are not acceptable are removed in-place. Returns the
510 * number of valid algorithms. */
512 check_user_algos(const char* user_algo_list
, algo_type
* algos
,
513 const char *algo_desc
)
515 algo_type new_algos
[MAX_PROPOSED_ALGO
];
516 /* this has two passes. first we sweep through the given list of
517 * algorithms and mark them as usable=2 in the algo_type[] array... */
519 char *work_list
= m_strdup(user_algo_list
);
520 char *last_name
= work_list
;
522 for (c
= work_list
; *c
; c
++)
527 try_add_algo(last_name
, algos
, algo_desc
, new_algos
, &num_ret
);
532 try_add_algo(last_name
, algos
, algo_desc
, new_algos
, &num_ret
);
535 new_algos
[num_ret
].name
= NULL
;
537 /* Copy one more as a blank delimiter */
538 memcpy(algos
, new_algos
, sizeof(*new_algos
) * (num_ret
+1));
541 #endif // ENABLE_USER_ALGO_LIST