diff options
Diffstat (limited to 'cipher.c')
-rw-r--r-- | cipher.c | 63 |
1 files changed, 43 insertions, 20 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: cipher.c,v 1.87 2013/01/26 06:11:05 djm Exp $ */ | 1 | /* $OpenBSD: cipher.c,v 1.89 2013/05/17 00:13:13 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -65,7 +65,9 @@ struct Cipher { | |||
65 | u_int discard_len; | 65 | u_int discard_len; |
66 | u_int cbc_mode; | 66 | u_int cbc_mode; |
67 | const EVP_CIPHER *(*evptype)(void); | 67 | const EVP_CIPHER *(*evptype)(void); |
68 | } ciphers[] = { | 68 | }; |
69 | |||
70 | static const struct Cipher ciphers[] = { | ||
69 | { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, | 71 | { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, |
70 | { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, | 72 | { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, |
71 | { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des }, | 73 | { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des }, |
@@ -98,6 +100,27 @@ struct Cipher { | |||
98 | 100 | ||
99 | /*--*/ | 101 | /*--*/ |
100 | 102 | ||
103 | /* Returns a comma-separated list of supported ciphers. */ | ||
104 | char * | ||
105 | cipher_alg_list(void) | ||
106 | { | ||
107 | char *ret = NULL; | ||
108 | size_t nlen, rlen = 0; | ||
109 | const Cipher *c; | ||
110 | |||
111 | for (c = ciphers; c->name != NULL; c++) { | ||
112 | if (c->number != SSH_CIPHER_SSH2) | ||
113 | continue; | ||
114 | if (ret != NULL) | ||
115 | ret[rlen++] = '\n'; | ||
116 | nlen = strlen(c->name); | ||
117 | ret = xrealloc(ret, 1, rlen + nlen + 2); | ||
118 | memcpy(ret + rlen, c->name, nlen + 1); | ||
119 | rlen += nlen; | ||
120 | } | ||
121 | return ret; | ||
122 | } | ||
123 | |||
101 | u_int | 124 | u_int |
102 | cipher_blocksize(const Cipher *c) | 125 | cipher_blocksize(const Cipher *c) |
103 | { | 126 | { |
@@ -146,20 +169,20 @@ cipher_mask_ssh1(int client) | |||
146 | return mask; | 169 | return mask; |
147 | } | 170 | } |
148 | 171 | ||
149 | Cipher * | 172 | const Cipher * |
150 | cipher_by_name(const char *name) | 173 | cipher_by_name(const char *name) |
151 | { | 174 | { |
152 | Cipher *c; | 175 | const Cipher *c; |
153 | for (c = ciphers; c->name != NULL; c++) | 176 | for (c = ciphers; c->name != NULL; c++) |
154 | if (strcmp(c->name, name) == 0) | 177 | if (strcmp(c->name, name) == 0) |
155 | return c; | 178 | return c; |
156 | return NULL; | 179 | return NULL; |
157 | } | 180 | } |
158 | 181 | ||
159 | Cipher * | 182 | const Cipher * |
160 | cipher_by_number(int id) | 183 | cipher_by_number(int id) |
161 | { | 184 | { |
162 | Cipher *c; | 185 | const Cipher *c; |
163 | for (c = ciphers; c->name != NULL; c++) | 186 | for (c = ciphers; c->name != NULL; c++) |
164 | if (c->number == id) | 187 | if (c->number == id) |
165 | return c; | 188 | return c; |
@@ -170,7 +193,7 @@ cipher_by_number(int id) | |||
170 | int | 193 | int |
171 | ciphers_valid(const char *names) | 194 | ciphers_valid(const char *names) |
172 | { | 195 | { |
173 | Cipher *c; | 196 | const Cipher *c; |
174 | char *cipher_list, *cp; | 197 | char *cipher_list, *cp; |
175 | char *p; | 198 | char *p; |
176 | 199 | ||
@@ -182,14 +205,14 @@ ciphers_valid(const char *names) | |||
182 | c = cipher_by_name(p); | 205 | c = cipher_by_name(p); |
183 | if (c == NULL || c->number != SSH_CIPHER_SSH2) { | 206 | if (c == NULL || c->number != SSH_CIPHER_SSH2) { |
184 | debug("bad cipher %s [%s]", p, names); | 207 | debug("bad cipher %s [%s]", p, names); |
185 | xfree(cipher_list); | 208 | free(cipher_list); |
186 | return 0; | 209 | return 0; |
187 | } else { | 210 | } else { |
188 | debug3("cipher ok: %s [%s]", p, names); | 211 | debug3("cipher ok: %s [%s]", p, names); |
189 | } | 212 | } |
190 | } | 213 | } |
191 | debug3("ciphers ok: [%s]", names); | 214 | debug3("ciphers ok: [%s]", names); |
192 | xfree(cipher_list); | 215 | free(cipher_list); |
193 | return 1; | 216 | return 1; |
194 | } | 217 | } |
195 | 218 | ||
@@ -201,7 +224,7 @@ ciphers_valid(const char *names) | |||
201 | int | 224 | int |
202 | cipher_number(const char *name) | 225 | cipher_number(const char *name) |
203 | { | 226 | { |
204 | Cipher *c; | 227 | const Cipher *c; |
205 | if (name == NULL) | 228 | if (name == NULL) |
206 | return -1; | 229 | return -1; |
207 | for (c = ciphers; c->name != NULL; c++) | 230 | for (c = ciphers; c->name != NULL; c++) |
@@ -213,12 +236,12 @@ cipher_number(const char *name) | |||
213 | char * | 236 | char * |
214 | cipher_name(int id) | 237 | cipher_name(int id) |
215 | { | 238 | { |
216 | Cipher *c = cipher_by_number(id); | 239 | const Cipher *c = cipher_by_number(id); |
217 | return (c==NULL) ? "<unknown>" : c->name; | 240 | return (c==NULL) ? "<unknown>" : c->name; |
218 | } | 241 | } |
219 | 242 | ||
220 | void | 243 | void |
221 | cipher_init(CipherContext *cc, Cipher *cipher, | 244 | cipher_init(CipherContext *cc, const Cipher *cipher, |
222 | const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, | 245 | const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, |
223 | int do_encrypt) | 246 | int do_encrypt) |
224 | { | 247 | { |
@@ -291,8 +314,8 @@ cipher_init(CipherContext *cc, Cipher *cipher, | |||
291 | cipher->discard_len) == 0) | 314 | cipher->discard_len) == 0) |
292 | fatal("evp_crypt: EVP_Cipher failed during discard"); | 315 | fatal("evp_crypt: EVP_Cipher failed during discard"); |
293 | memset(discard, 0, cipher->discard_len); | 316 | memset(discard, 0, cipher->discard_len); |
294 | xfree(junk); | 317 | free(junk); |
295 | xfree(discard); | 318 | free(discard); |
296 | } | 319 | } |
297 | } | 320 | } |
298 | 321 | ||
@@ -364,7 +387,7 @@ cipher_cleanup(CipherContext *cc) | |||
364 | */ | 387 | */ |
365 | 388 | ||
366 | void | 389 | void |
367 | cipher_set_key_string(CipherContext *cc, Cipher *cipher, | 390 | cipher_set_key_string(CipherContext *cc, const Cipher *cipher, |
368 | const char *passphrase, int do_encrypt) | 391 | const char *passphrase, int do_encrypt) |
369 | { | 392 | { |
370 | MD5_CTX md; | 393 | MD5_CTX md; |
@@ -389,7 +412,7 @@ cipher_set_key_string(CipherContext *cc, Cipher *cipher, | |||
389 | int | 412 | int |
390 | cipher_get_keyiv_len(const CipherContext *cc) | 413 | cipher_get_keyiv_len(const CipherContext *cc) |
391 | { | 414 | { |
392 | Cipher *c = cc->cipher; | 415 | const Cipher *c = cc->cipher; |
393 | int ivlen; | 416 | int ivlen; |
394 | 417 | ||
395 | if (c->number == SSH_CIPHER_3DES) | 418 | if (c->number == SSH_CIPHER_3DES) |
@@ -402,7 +425,7 @@ cipher_get_keyiv_len(const CipherContext *cc) | |||
402 | void | 425 | void |
403 | cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) | 426 | cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) |
404 | { | 427 | { |
405 | Cipher *c = cc->cipher; | 428 | const Cipher *c = cc->cipher; |
406 | int evplen; | 429 | int evplen; |
407 | 430 | ||
408 | switch (c->number) { | 431 | switch (c->number) { |
@@ -438,7 +461,7 @@ cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) | |||
438 | void | 461 | void |
439 | cipher_set_keyiv(CipherContext *cc, u_char *iv) | 462 | cipher_set_keyiv(CipherContext *cc, u_char *iv) |
440 | { | 463 | { |
441 | Cipher *c = cc->cipher; | 464 | const Cipher *c = cc->cipher; |
442 | int evplen = 0; | 465 | int evplen = 0; |
443 | 466 | ||
444 | switch (c->number) { | 467 | switch (c->number) { |
@@ -471,7 +494,7 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv) | |||
471 | int | 494 | int |
472 | cipher_get_keycontext(const CipherContext *cc, u_char *dat) | 495 | cipher_get_keycontext(const CipherContext *cc, u_char *dat) |
473 | { | 496 | { |
474 | Cipher *c = cc->cipher; | 497 | const Cipher *c = cc->cipher; |
475 | int plen = 0; | 498 | int plen = 0; |
476 | 499 | ||
477 | if (c->evptype == EVP_rc4) { | 500 | if (c->evptype == EVP_rc4) { |
@@ -486,7 +509,7 @@ cipher_get_keycontext(const CipherContext *cc, u_char *dat) | |||
486 | void | 509 | void |
487 | cipher_set_keycontext(CipherContext *cc, u_char *dat) | 510 | cipher_set_keycontext(CipherContext *cc, u_char *dat) |
488 | { | 511 | { |
489 | Cipher *c = cc->cipher; | 512 | const Cipher *c = cc->cipher; |
490 | int plen; | 513 | int plen; |
491 | 514 | ||
492 | if (c->evptype == EVP_rc4) { | 515 | if (c->evptype == EVP_rc4) { |