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
29 /* This file (algo.c) organises the ciphers which can be used, and is used to
30 * decide which ciphers/hashes/compression/signing to use during key exchange*/
32 static int void_cipher(const unsigned char* in
, unsigned char* out
,
33 unsigned long len
, void *cipher_state
) {
35 memmove(out
, in
, len
);
40 static int void_start(int cipher
, const unsigned char *IV
,
41 const unsigned char *key
,
42 int keylen
, int num_rounds
, void *cipher_state
) {
46 /* Mappings for ciphers, parameters are
47 {&cipher_desc, keysize, blocksize} */
48 /* NOTE: if keysize > 2*SHA1_HASH_SIZE, code such as hashkeys()
51 #ifdef DROPBEAR_AES256
52 static const struct dropbear_cipher dropbear_aes256
=
55 #ifdef DROPBEAR_AES128
56 static const struct dropbear_cipher dropbear_aes128
=
59 #ifdef DROPBEAR_BLOWFISH
60 static const struct dropbear_cipher dropbear_blowfish
=
61 {&blowfish_desc
, 16, 8};
63 #ifdef DROPBEAR_TWOFISH256
64 static const struct dropbear_cipher dropbear_twofish256
=
65 {&twofish_desc
, 32, 16};
67 #ifdef DROPBEAR_TWOFISH128
68 static const struct dropbear_cipher dropbear_twofish128
=
69 {&twofish_desc
, 16, 16};
72 static const struct dropbear_cipher dropbear_3des
=
76 /* used to indicate no encryption, as defined in rfc2410 */
77 const struct dropbear_cipher dropbear_nocipher
=
80 /* A few void* s are required to silence warnings
81 * about the symmetric_CBC vs symmetric_CTR cipher_state pointer */
82 const struct dropbear_cipher_mode dropbear_mode_cbc
=
83 {(void*)cbc_start
, (void*)cbc_encrypt
, (void*)cbc_decrypt
};
84 const struct dropbear_cipher_mode dropbear_mode_none
=
85 {void_start
, void_cipher
, void_cipher
};
86 #ifdef DROPBEAR_ENABLE_CTR_MODE
87 /* a wrapper to make ctr_start and cbc_start look the same */
88 static int dropbear_big_endian_ctr_start(int cipher
,
89 const unsigned char *IV
,
90 const unsigned char *key
, int keylen
,
91 int num_rounds
, symmetric_CTR
*ctr
) {
92 return ctr_start(cipher
, IV
, key
, keylen
, num_rounds
, CTR_COUNTER_BIG_ENDIAN
, ctr
);
94 const struct dropbear_cipher_mode dropbear_mode_ctr
=
95 {(void*)dropbear_big_endian_ctr_start
, (void*)ctr_encrypt
, (void*)ctr_decrypt
};
98 /* Mapping of ssh hashes to libtomcrypt hashes, including keysize etc.
99 {&hash_desc, keysize, hashsize} */
101 #ifdef DROPBEAR_SHA1_HMAC
102 static const struct dropbear_hash dropbear_sha1
=
103 {&sha1_desc
, 20, 20};
105 #ifdef DROPBEAR_SHA1_96_HMAC
106 static const struct dropbear_hash dropbear_sha1_96
=
107 {&sha1_desc
, 20, 12};
109 #ifdef DROPBEAR_MD5_HMAC
110 static const struct dropbear_hash dropbear_md5
=
114 const struct dropbear_hash dropbear_nohash
=
115 {NULL
, 16, 0}; /* used initially */
118 /* The following map ssh names to internal values.
119 * The ordering here is important for the client - the first mode
120 * that is also supported by the server will get used. */
122 algo_type sshciphers
[] = {
123 #ifdef DROPBEAR_ENABLE_CTR_MODE
124 #ifdef DROPBEAR_AES128
125 {"aes128-ctr", 0, &dropbear_aes128
, 1, &dropbear_mode_ctr
},
128 {"3des-ctr", 0, &dropbear_3des
, 1, &dropbear_mode_ctr
},
130 #ifdef DROPBEAR_AES256
131 {"aes256-ctr", 0, &dropbear_aes256
, 1, &dropbear_mode_ctr
},
133 #endif /* DROPBEAR_ENABLE_CTR_MODE */
135 /* CBC modes are always enabled */
136 #ifdef DROPBEAR_AES128
137 {"aes128-cbc", 0, &dropbear_aes128
, 1, &dropbear_mode_cbc
},
140 {"3des-cbc", 0, &dropbear_3des
, 1, &dropbear_mode_cbc
},
142 #ifdef DROPBEAR_AES256
143 {"aes256-cbc", 0, &dropbear_aes256
, 1, &dropbear_mode_cbc
},
145 #ifdef DROPBEAR_TWOFISH256
146 {"twofish256-cbc", 0, &dropbear_twofish256
, 1, &dropbear_mode_cbc
},
147 {"twofish-cbc", 0, &dropbear_twofish256
, 1, &dropbear_mode_cbc
},
149 #ifdef DROPBEAR_TWOFISH128
150 {"twofish128-cbc", 0, &dropbear_twofish128
, 1, &dropbear_mode_cbc
},
152 #ifdef DROPBEAR_BLOWFISH
153 {"blowfish-cbc", 0, &dropbear_blowfish
, 1, &dropbear_mode_cbc
},
155 {NULL
, 0, NULL
, 0, NULL
}
158 algo_type sshhashes
[] = {
159 #ifdef DROPBEAR_SHA1_96_HMAC
160 {"hmac-sha1-96", 0, &dropbear_sha1_96
, 1, NULL
},
162 #ifdef DROPBEAR_SHA1_HMAC
163 {"hmac-sha1", 0, &dropbear_sha1
, 1, NULL
},
165 #ifdef DROPBEAR_MD5_HMAC
166 {"hmac-md5", 0, &dropbear_md5
, 1, NULL
},
168 {NULL
, 0, NULL
, 0, NULL
}
172 algo_type ssh_compress
[] = {
173 {"zlib", DROPBEAR_COMP_ZLIB
, NULL
, 1, NULL
},
174 {"zlib@openssh.com", DROPBEAR_COMP_ZLIB_DELAY
, NULL
, 1, NULL
},
175 {"none", DROPBEAR_COMP_NONE
, NULL
, 1, NULL
},
176 {NULL
, 0, NULL
, 0, NULL
}
180 algo_type ssh_nocompress
[] = {
181 {"none", DROPBEAR_COMP_NONE
, NULL
, 1, NULL
},
182 {NULL
, 0, NULL
, 0, NULL
}
185 algo_type sshhostkey
[] = {
187 {"ssh-rsa", DROPBEAR_SIGNKEY_RSA
, NULL
, 1, NULL
},
190 {"ssh-dss", DROPBEAR_SIGNKEY_DSS
, NULL
, 1, NULL
},
192 {NULL
, 0, NULL
, 0, NULL
}
195 algo_type sshkex
[] = {
196 {"diffie-hellman-group1-sha1", DROPBEAR_KEX_DH_GROUP1
, NULL
, 1, NULL
},
197 {NULL
, 0, NULL
, 0, NULL
}
201 /* Register the compiled in ciphers.
202 * This should be run before using any of the ciphers/hashes */
205 const struct ltc_cipher_descriptor
*regciphers
[] = {
209 #ifdef DROPBEAR_BLOWFISH
212 #ifdef DROPBEAR_TWOFISH
221 const struct ltc_hash_descriptor
*reghashes
[] = {
222 /* we need sha1 for hostkey stuff regardless */
224 #ifdef DROPBEAR_MD5_HMAC
231 for (i
= 0; regciphers
[i
] != NULL
; i
++) {
232 if (register_cipher(regciphers
[i
]) == -1) {
233 dropbear_exit("error registering crypto");
237 for (i
= 0; reghashes
[i
] != NULL
; i
++) {
238 if (register_hash(reghashes
[i
]) == -1) {
239 dropbear_exit("error registering crypto");
244 /* algolen specifies the length of algo, algos is our local list to match
246 * Returns DROPBEAR_SUCCESS if we have a match for algo, DROPBEAR_FAILURE
248 int have_algo(char* algo
, size_t algolen
, algo_type algos
[]) {
252 for (i
= 0; algos
[i
].name
!= NULL
; i
++) {
253 if (strlen(algos
[i
].name
) == algolen
254 && (strncmp(algos
[i
].name
, algo
, algolen
) == 0)) {
255 return DROPBEAR_SUCCESS
;
259 return DROPBEAR_FAILURE
;
264 /* Output a comma separated list of algorithms to a buffer */
265 void buf_put_algolist(buffer
* buf
, algo_type localalgos
[]) {
268 unsigned int donefirst
= 0;
269 buffer
*algolist
= NULL
;
271 algolist
= buf_new(160);
272 for (i
= 0; localalgos
[i
].name
!= NULL
; i
++) {
273 if (localalgos
[i
].usable
) {
275 buf_putbyte(algolist
, ',');
277 len
= strlen(localalgos
[i
].name
);
278 buf_putbytes(algolist
, localalgos
[i
].name
, len
);
281 buf_putstring(buf
, algolist
->data
, algolist
->len
);