diff options
author | Damien Miller <djm@mindrot.org> | 2014-07-02 15:28:02 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2014-07-02 15:28:02 +1000 |
commit | 8668706d0f52654fe64c0ca41a96113aeab8d2b8 (patch) | |
tree | 73e78e1ea3d39206e39870bbe0af17d6c430fb51 /cipher.c | |
parent | 2cd7929250cf9e9f658d70dcd452f529ba08c942 (diff) |
- djm@cvs.openbsd.org 2014/06/24 01:13:21
[Makefile.in auth-bsdauth.c auth-chall.c auth-options.c auth-rsa.c
[auth2-none.c auth2-pubkey.c authfile.c authfile.h cipher-3des1.c
[cipher-chachapoly.c cipher-chachapoly.h cipher.c cipher.h
[digest-libc.c digest-openssl.c digest.h dns.c entropy.c hmac.h
[hostfile.c key.c key.h krl.c monitor.c packet.c rsa.c rsa.h
[ssh-add.c ssh-agent.c ssh-dss.c ssh-ecdsa.c ssh-ed25519.c
[ssh-keygen.c ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c
[ssh-rsa.c sshbuf-misc.c sshbuf.h sshconnect.c sshconnect1.c
[sshconnect2.c sshd.c sshkey.c sshkey.h
[openbsd-compat/openssl-compat.c openbsd-compat/openssl-compat.h]
New key API: refactor key-related functions to be more library-like,
existing API is offered as a set of wrappers.
with and ok markus@
Thanks also to Ben Hawkes, David Tomaschik, Ivan Fratric, Matthew
Dempsky and Ron Bowes for a detailed review a few months ago.
NB. This commit also removes portable OpenSSH support for OpenSSL
<0.9.8e.
Diffstat (limited to 'cipher.c')
-rw-r--r-- | cipher.c | 363 |
1 files changed, 175 insertions, 188 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: cipher.c,v 1.98 2014/04/29 18:01:49 markus Exp $ */ | 1 | /* $OpenBSD: cipher.c,v 1.99 2014/06/24 01:13:21 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 |
@@ -43,23 +43,19 @@ | |||
43 | #include <stdarg.h> | 43 | #include <stdarg.h> |
44 | #include <stdio.h> | 44 | #include <stdio.h> |
45 | 45 | ||
46 | #include "xmalloc.h" | ||
47 | #include "log.h" | ||
48 | #include "misc.h" | ||
49 | #include "cipher.h" | 46 | #include "cipher.h" |
50 | #include "buffer.h" | 47 | #include "misc.h" |
48 | #include "sshbuf.h" | ||
49 | #include "ssherr.h" | ||
51 | #include "digest.h" | 50 | #include "digest.h" |
52 | 51 | ||
53 | /* compatibility with old or broken OpenSSL versions */ | ||
54 | #include "openbsd-compat/openssl-compat.h" | ||
55 | |||
56 | #ifdef WITH_SSH1 | 52 | #ifdef WITH_SSH1 |
57 | extern const EVP_CIPHER *evp_ssh1_bf(void); | 53 | extern const EVP_CIPHER *evp_ssh1_bf(void); |
58 | extern const EVP_CIPHER *evp_ssh1_3des(void); | 54 | extern const EVP_CIPHER *evp_ssh1_3des(void); |
59 | extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); | 55 | extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); |
60 | #endif | 56 | #endif |
61 | 57 | ||
62 | struct Cipher { | 58 | struct sshcipher { |
63 | char *name; | 59 | char *name; |
64 | int number; /* for ssh1 only */ | 60 | int number; /* for ssh1 only */ |
65 | u_int block_size; | 61 | u_int block_size; |
@@ -79,12 +75,12 @@ struct Cipher { | |||
79 | #endif | 75 | #endif |
80 | }; | 76 | }; |
81 | 77 | ||
82 | static const struct Cipher ciphers[] = { | 78 | static const struct sshcipher ciphers[] = { |
83 | #ifdef WITH_SSH1 | 79 | #ifdef WITH_SSH1 |
84 | { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, | 80 | { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, |
85 | { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des }, | 81 | { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des }, |
86 | { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf }, | 82 | { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf }, |
87 | #endif | 83 | #endif /* WITH_SSH1 */ |
88 | #ifdef WITH_OPENSSL | 84 | #ifdef WITH_OPENSSL |
89 | { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, | 85 | { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, |
90 | { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, | 86 | { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, |
@@ -103,12 +99,12 @@ static const struct Cipher ciphers[] = { | |||
103 | { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, | 99 | { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, |
104 | { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, | 100 | { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, |
105 | { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, | 101 | { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, |
106 | #ifdef OPENSSL_HAVE_EVPGCM | 102 | # ifdef OPENSSL_HAVE_EVPGCM |
107 | { "aes128-gcm@openssh.com", | 103 | { "aes128-gcm@openssh.com", |
108 | SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, | 104 | SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, |
109 | { "aes256-gcm@openssh.com", | 105 | { "aes256-gcm@openssh.com", |
110 | SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, | 106 | SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, |
111 | #endif | 107 | # endif /* OPENSSL_HAVE_EVPGCM */ |
112 | #else /* WITH_OPENSSL */ | 108 | #else /* WITH_OPENSSL */ |
113 | { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, CFLAG_AESCTR, NULL }, | 109 | { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, CFLAG_AESCTR, NULL }, |
114 | { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, CFLAG_AESCTR, NULL }, | 110 | { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, CFLAG_AESCTR, NULL }, |
@@ -117,18 +113,19 @@ static const struct Cipher ciphers[] = { | |||
117 | #endif /* WITH_OPENSSL */ | 113 | #endif /* WITH_OPENSSL */ |
118 | { "chacha20-poly1305@openssh.com", | 114 | { "chacha20-poly1305@openssh.com", |
119 | SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL }, | 115 | SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL }, |
116 | |||
120 | { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } | 117 | { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } |
121 | }; | 118 | }; |
122 | 119 | ||
123 | /*--*/ | 120 | /*--*/ |
124 | 121 | ||
125 | /* Returns a list of supported ciphers separated by the specified char. */ | 122 | /* Returns a comma-separated list of supported ciphers. */ |
126 | char * | 123 | char * |
127 | cipher_alg_list(char sep, int auth_only) | 124 | cipher_alg_list(char sep, int auth_only) |
128 | { | 125 | { |
129 | char *ret = NULL; | 126 | char *tmp, *ret = NULL; |
130 | size_t nlen, rlen = 0; | 127 | size_t nlen, rlen = 0; |
131 | const Cipher *c; | 128 | const struct sshcipher *c; |
132 | 129 | ||
133 | for (c = ciphers; c->name != NULL; c++) { | 130 | for (c = ciphers; c->name != NULL; c++) { |
134 | if (c->number != SSH_CIPHER_SSH2) | 131 | if (c->number != SSH_CIPHER_SSH2) |
@@ -138,7 +135,11 @@ cipher_alg_list(char sep, int auth_only) | |||
138 | if (ret != NULL) | 135 | if (ret != NULL) |
139 | ret[rlen++] = sep; | 136 | ret[rlen++] = sep; |
140 | nlen = strlen(c->name); | 137 | nlen = strlen(c->name); |
141 | ret = xrealloc(ret, 1, rlen + nlen + 2); | 138 | if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { |
139 | free(ret); | ||
140 | return NULL; | ||
141 | } | ||
142 | ret = tmp; | ||
142 | memcpy(ret + rlen, c->name, nlen + 1); | 143 | memcpy(ret + rlen, c->name, nlen + 1); |
143 | rlen += nlen; | 144 | rlen += nlen; |
144 | } | 145 | } |
@@ -146,19 +147,19 @@ cipher_alg_list(char sep, int auth_only) | |||
146 | } | 147 | } |
147 | 148 | ||
148 | u_int | 149 | u_int |
149 | cipher_blocksize(const Cipher *c) | 150 | cipher_blocksize(const struct sshcipher *c) |
150 | { | 151 | { |
151 | return (c->block_size); | 152 | return (c->block_size); |
152 | } | 153 | } |
153 | 154 | ||
154 | u_int | 155 | u_int |
155 | cipher_keylen(const Cipher *c) | 156 | cipher_keylen(const struct sshcipher *c) |
156 | { | 157 | { |
157 | return (c->key_len); | 158 | return (c->key_len); |
158 | } | 159 | } |
159 | 160 | ||
160 | u_int | 161 | u_int |
161 | cipher_seclen(const Cipher *c) | 162 | cipher_seclen(const struct sshcipher *c) |
162 | { | 163 | { |
163 | if (strcmp("3des-cbc", c->name) == 0) | 164 | if (strcmp("3des-cbc", c->name) == 0) |
164 | return 14; | 165 | return 14; |
@@ -166,13 +167,13 @@ cipher_seclen(const Cipher *c) | |||
166 | } | 167 | } |
167 | 168 | ||
168 | u_int | 169 | u_int |
169 | cipher_authlen(const Cipher *c) | 170 | cipher_authlen(const struct sshcipher *c) |
170 | { | 171 | { |
171 | return (c->auth_len); | 172 | return (c->auth_len); |
172 | } | 173 | } |
173 | 174 | ||
174 | u_int | 175 | u_int |
175 | cipher_ivlen(const Cipher *c) | 176 | cipher_ivlen(const struct sshcipher *c) |
176 | { | 177 | { |
177 | /* | 178 | /* |
178 | * Default is cipher block size, except for chacha20+poly1305 that | 179 | * Default is cipher block size, except for chacha20+poly1305 that |
@@ -183,13 +184,13 @@ cipher_ivlen(const Cipher *c) | |||
183 | } | 184 | } |
184 | 185 | ||
185 | u_int | 186 | u_int |
186 | cipher_get_number(const Cipher *c) | 187 | cipher_get_number(const struct sshcipher *c) |
187 | { | 188 | { |
188 | return (c->number); | 189 | return (c->number); |
189 | } | 190 | } |
190 | 191 | ||
191 | u_int | 192 | u_int |
192 | cipher_is_cbc(const Cipher *c) | 193 | cipher_is_cbc(const struct sshcipher *c) |
193 | { | 194 | { |
194 | return (c->flags & CFLAG_CBC) != 0; | 195 | return (c->flags & CFLAG_CBC) != 0; |
195 | } | 196 | } |
@@ -206,20 +207,20 @@ cipher_mask_ssh1(int client) | |||
206 | return mask; | 207 | return mask; |
207 | } | 208 | } |
208 | 209 | ||
209 | const Cipher * | 210 | const struct sshcipher * |
210 | cipher_by_name(const char *name) | 211 | cipher_by_name(const char *name) |
211 | { | 212 | { |
212 | const Cipher *c; | 213 | const struct sshcipher *c; |
213 | for (c = ciphers; c->name != NULL; c++) | 214 | for (c = ciphers; c->name != NULL; c++) |
214 | if (strcmp(c->name, name) == 0) | 215 | if (strcmp(c->name, name) == 0) |
215 | return c; | 216 | return c; |
216 | return NULL; | 217 | return NULL; |
217 | } | 218 | } |
218 | 219 | ||
219 | const Cipher * | 220 | const struct sshcipher * |
220 | cipher_by_number(int id) | 221 | cipher_by_number(int id) |
221 | { | 222 | { |
222 | const Cipher *c; | 223 | const struct sshcipher *c; |
223 | for (c = ciphers; c->name != NULL; c++) | 224 | for (c = ciphers; c->name != NULL; c++) |
224 | if (c->number == id) | 225 | if (c->number == id) |
225 | return c; | 226 | return c; |
@@ -230,23 +231,22 @@ cipher_by_number(int id) | |||
230 | int | 231 | int |
231 | ciphers_valid(const char *names) | 232 | ciphers_valid(const char *names) |
232 | { | 233 | { |
233 | const Cipher *c; | 234 | const struct sshcipher *c; |
234 | char *cipher_list, *cp; | 235 | char *cipher_list, *cp; |
235 | char *p; | 236 | char *p; |
236 | 237 | ||
237 | if (names == NULL || strcmp(names, "") == 0) | 238 | if (names == NULL || strcmp(names, "") == 0) |
238 | return 0; | 239 | return 0; |
239 | cipher_list = cp = xstrdup(names); | 240 | if ((cipher_list = cp = strdup(names)) == NULL) |
241 | return 0; | ||
240 | for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; | 242 | for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; |
241 | (p = strsep(&cp, CIPHER_SEP))) { | 243 | (p = strsep(&cp, CIPHER_SEP))) { |
242 | c = cipher_by_name(p); | 244 | c = cipher_by_name(p); |
243 | if (c == NULL || c->number != SSH_CIPHER_SSH2) { | 245 | if (c == NULL || c->number != SSH_CIPHER_SSH2) { |
244 | debug("bad cipher %s [%s]", p, names); | ||
245 | free(cipher_list); | 246 | free(cipher_list); |
246 | return 0; | 247 | return 0; |
247 | } | 248 | } |
248 | } | 249 | } |
249 | debug3("ciphers ok: [%s]", names); | ||
250 | free(cipher_list); | 250 | free(cipher_list); |
251 | return 1; | 251 | return 1; |
252 | } | 252 | } |
@@ -259,7 +259,7 @@ ciphers_valid(const char *names) | |||
259 | int | 259 | int |
260 | cipher_number(const char *name) | 260 | cipher_number(const char *name) |
261 | { | 261 | { |
262 | const Cipher *c; | 262 | const struct sshcipher *c; |
263 | if (name == NULL) | 263 | if (name == NULL) |
264 | return -1; | 264 | return -1; |
265 | for (c = ciphers; c->name != NULL; c++) | 265 | for (c = ciphers; c->name != NULL; c++) |
@@ -271,31 +271,33 @@ cipher_number(const char *name) | |||
271 | char * | 271 | char * |
272 | cipher_name(int id) | 272 | cipher_name(int id) |
273 | { | 273 | { |
274 | const Cipher *c = cipher_by_number(id); | 274 | const struct sshcipher *c = cipher_by_number(id); |
275 | return (c==NULL) ? "<unknown>" : c->name; | 275 | return (c==NULL) ? "<unknown>" : c->name; |
276 | } | 276 | } |
277 | 277 | ||
278 | void | 278 | const char * |
279 | cipher_init(CipherContext *cc, const Cipher *cipher, | 279 | cipher_warning_message(const struct sshcipher_ctx *cc) |
280 | { | ||
281 | if (cc == NULL || cc->cipher == NULL) | ||
282 | return NULL; | ||
283 | if (cc->cipher->number == SSH_CIPHER_DES) | ||
284 | return "use of DES is strongly discouraged due to " | ||
285 | "cryptographic weaknesses"; | ||
286 | return NULL; | ||
287 | } | ||
288 | |||
289 | int | ||
290 | cipher_init(struct sshcipher_ctx *cc, const struct sshcipher *cipher, | ||
280 | const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, | 291 | const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, |
281 | int do_encrypt) | 292 | int do_encrypt) |
282 | { | 293 | { |
283 | #ifdef WITH_OPENSSL | 294 | #ifdef WITH_OPENSSL |
284 | static int dowarn = 1; | 295 | int ret = SSH_ERR_INTERNAL_ERROR; |
285 | #ifdef SSH_OLD_EVP | ||
286 | EVP_CIPHER *type; | ||
287 | #else | ||
288 | const EVP_CIPHER *type; | 296 | const EVP_CIPHER *type; |
289 | int klen; | 297 | int klen; |
290 | #endif | ||
291 | u_char *junk, *discard; | 298 | u_char *junk, *discard; |
292 | 299 | ||
293 | if (cipher->number == SSH_CIPHER_DES) { | 300 | if (cipher->number == SSH_CIPHER_DES) { |
294 | if (dowarn) { | ||
295 | error("Warning: use of DES is strongly discouraged " | ||
296 | "due to cryptographic weaknesses"); | ||
297 | dowarn = 0; | ||
298 | } | ||
299 | if (keylen > 8) | 301 | if (keylen > 8) |
300 | keylen = 8; | 302 | keylen = 8; |
301 | } | 303 | } |
@@ -303,71 +305,70 @@ cipher_init(CipherContext *cc, const Cipher *cipher, | |||
303 | cc->plaintext = (cipher->number == SSH_CIPHER_NONE); | 305 | cc->plaintext = (cipher->number == SSH_CIPHER_NONE); |
304 | cc->encrypt = do_encrypt; | 306 | cc->encrypt = do_encrypt; |
305 | 307 | ||
306 | if (keylen < cipher->key_len) | 308 | if (keylen < cipher->key_len || |
307 | fatal("cipher_init: key length %d is insufficient for %s.", | 309 | (iv != NULL && ivlen < cipher_ivlen(cipher))) |
308 | keylen, cipher->name); | 310 | return SSH_ERR_INVALID_ARGUMENT; |
309 | if (iv != NULL && ivlen < cipher_ivlen(cipher)) | ||
310 | fatal("cipher_init: iv length %d is insufficient for %s.", | ||
311 | ivlen, cipher->name); | ||
312 | cc->cipher = cipher; | ||
313 | 311 | ||
312 | cc->cipher = cipher; | ||
314 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { | 313 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { |
315 | chachapoly_init(&cc->cp_ctx, key, keylen); | 314 | return chachapoly_init(&cc->cp_ctx, key, keylen); |
316 | return; | ||
317 | } | 315 | } |
318 | #ifndef WITH_OPENSSL | 316 | #ifndef WITH_OPENSSL |
319 | if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { | 317 | if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { |
320 | aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen); | 318 | aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen); |
321 | aesctr_ivsetup(&cc->ac_ctx, iv); | 319 | aesctr_ivsetup(&cc->ac_ctx, iv); |
322 | return; | 320 | return 0; |
323 | } | 321 | } |
324 | if ((cc->cipher->flags & CFLAG_NONE) != 0) | 322 | if ((cc->cipher->flags & CFLAG_NONE) != 0) |
325 | return; | 323 | return 0; |
326 | fatal("unsupported cipher"); | 324 | return SSH_ERR_INVALID_ARGUMENT; |
327 | #else | 325 | #else |
328 | type = (*cipher->evptype)(); | 326 | type = (*cipher->evptype)(); |
329 | EVP_CIPHER_CTX_init(&cc->evp); | 327 | EVP_CIPHER_CTX_init(&cc->evp); |
330 | #ifdef SSH_OLD_EVP | ||
331 | if (type->key_len > 0 && type->key_len != keylen) { | ||
332 | debug("cipher_init: set keylen (%d -> %d)", | ||
333 | type->key_len, keylen); | ||
334 | type->key_len = keylen; | ||
335 | } | ||
336 | EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv, | ||
337 | (do_encrypt == CIPHER_ENCRYPT)); | ||
338 | #else | ||
339 | if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, | 328 | if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, |
340 | (do_encrypt == CIPHER_ENCRYPT)) == 0) | 329 | (do_encrypt == CIPHER_ENCRYPT)) == 0) { |
341 | fatal("cipher_init: EVP_CipherInit failed for %s", | 330 | ret = SSH_ERR_LIBCRYPTO_ERROR; |
342 | cipher->name); | 331 | goto bad; |
332 | } | ||
343 | if (cipher_authlen(cipher) && | 333 | if (cipher_authlen(cipher) && |
344 | !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, | 334 | !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, |
345 | -1, (u_char *)iv)) | 335 | -1, (u_char *)iv)) { |
346 | fatal("cipher_init: EVP_CTRL_GCM_SET_IV_FIXED failed for %s", | 336 | ret = SSH_ERR_LIBCRYPTO_ERROR; |
347 | cipher->name); | 337 | goto bad; |
338 | } | ||
348 | klen = EVP_CIPHER_CTX_key_length(&cc->evp); | 339 | klen = EVP_CIPHER_CTX_key_length(&cc->evp); |
349 | if (klen > 0 && keylen != (u_int)klen) { | 340 | if (klen > 0 && keylen != (u_int)klen) { |
350 | debug2("cipher_init: set keylen (%d -> %d)", klen, keylen); | 341 | if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) { |
351 | if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) | 342 | ret = SSH_ERR_LIBCRYPTO_ERROR; |
352 | fatal("cipher_init: set keylen failed (%d -> %d)", | 343 | goto bad; |
353 | klen, keylen); | 344 | } |
345 | } | ||
346 | if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) { | ||
347 | ret = SSH_ERR_LIBCRYPTO_ERROR; | ||
348 | goto bad; | ||
354 | } | 349 | } |
355 | if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) | ||
356 | fatal("cipher_init: EVP_CipherInit: set key failed for %s", | ||
357 | cipher->name); | ||
358 | #endif | ||
359 | 350 | ||
360 | if (cipher->discard_len > 0) { | 351 | if (cipher->discard_len > 0) { |
361 | junk = xmalloc(cipher->discard_len); | 352 | if ((junk = malloc(cipher->discard_len)) == NULL || |
362 | discard = xmalloc(cipher->discard_len); | 353 | (discard = malloc(cipher->discard_len)) == NULL) { |
363 | if (EVP_Cipher(&cc->evp, discard, junk, | 354 | if (junk != NULL) |
364 | cipher->discard_len) == 0) | 355 | free(junk); |
365 | fatal("evp_crypt: EVP_Cipher failed during discard"); | 356 | ret = SSH_ERR_ALLOC_FAIL; |
357 | goto bad; | ||
358 | } | ||
359 | ret = EVP_Cipher(&cc->evp, discard, junk, cipher->discard_len); | ||
366 | explicit_bzero(discard, cipher->discard_len); | 360 | explicit_bzero(discard, cipher->discard_len); |
367 | free(junk); | 361 | free(junk); |
368 | free(discard); | 362 | free(discard); |
363 | if (ret != 1) { | ||
364 | ret = SSH_ERR_LIBCRYPTO_ERROR; | ||
365 | bad: | ||
366 | EVP_CIPHER_CTX_cleanup(&cc->evp); | ||
367 | return ret; | ||
368 | } | ||
369 | } | 369 | } |
370 | #endif | 370 | #endif |
371 | return 0; | ||
371 | } | 372 | } |
372 | 373 | ||
373 | /* | 374 | /* |
@@ -379,16 +380,15 @@ cipher_init(CipherContext *cc, const Cipher *cipher, | |||
379 | * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag. | 380 | * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag. |
380 | * This tag is written on encryption and verified on decryption. | 381 | * This tag is written on encryption and verified on decryption. |
381 | * Both 'aadlen' and 'authlen' can be set to 0. | 382 | * Both 'aadlen' and 'authlen' can be set to 0. |
382 | * cipher_crypt() returns 0 on success and -1 if the decryption integrity | ||
383 | * check fails. | ||
384 | */ | 383 | */ |
385 | int | 384 | int |
386 | cipher_crypt(CipherContext *cc, u_int seqnr, u_char *dest, const u_char *src, | 385 | cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest, |
387 | u_int len, u_int aadlen, u_int authlen) | 386 | const u_char *src, u_int len, u_int aadlen, u_int authlen) |
388 | { | 387 | { |
389 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) | 388 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { |
390 | return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, len, | 389 | return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, |
391 | aadlen, authlen, cc->encrypt); | 390 | len, aadlen, authlen, cc->encrypt); |
391 | } | ||
392 | #ifndef WITH_OPENSSL | 392 | #ifndef WITH_OPENSSL |
393 | if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { | 393 | if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { |
394 | if (aadlen) | 394 | if (aadlen) |
@@ -401,46 +401,43 @@ cipher_crypt(CipherContext *cc, u_int seqnr, u_char *dest, const u_char *src, | |||
401 | memcpy(dest, src, aadlen + len); | 401 | memcpy(dest, src, aadlen + len); |
402 | return 0; | 402 | return 0; |
403 | } | 403 | } |
404 | fatal("unsupported cipher"); | 404 | return SSH_ERR_INVALID_ARGUMENT; |
405 | #else | 405 | #else |
406 | if (authlen) { | 406 | if (authlen) { |
407 | u_char lastiv[1]; | 407 | u_char lastiv[1]; |
408 | 408 | ||
409 | if (authlen != cipher_authlen(cc->cipher)) | 409 | if (authlen != cipher_authlen(cc->cipher)) |
410 | fatal("%s: authlen mismatch %d", __func__, authlen); | 410 | return SSH_ERR_INVALID_ARGUMENT; |
411 | /* increment IV */ | 411 | /* increment IV */ |
412 | if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, | 412 | if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, |
413 | 1, lastiv)) | 413 | 1, lastiv)) |
414 | fatal("%s: EVP_CTRL_GCM_IV_GEN", __func__); | 414 | return SSH_ERR_LIBCRYPTO_ERROR; |
415 | /* set tag on decyption */ | 415 | /* set tag on decyption */ |
416 | if (!cc->encrypt && | 416 | if (!cc->encrypt && |
417 | !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG, | 417 | !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG, |
418 | authlen, (u_char *)src + aadlen + len)) | 418 | authlen, (u_char *)src + aadlen + len)) |
419 | fatal("%s: EVP_CTRL_GCM_SET_TAG", __func__); | 419 | return SSH_ERR_LIBCRYPTO_ERROR; |
420 | } | 420 | } |
421 | if (aadlen) { | 421 | if (aadlen) { |
422 | if (authlen && | 422 | if (authlen && |
423 | EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0) | 423 | EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0) |
424 | fatal("%s: EVP_Cipher(aad) failed", __func__); | 424 | return SSH_ERR_LIBCRYPTO_ERROR; |
425 | memcpy(dest, src, aadlen); | 425 | memcpy(dest, src, aadlen); |
426 | } | 426 | } |
427 | if (len % cc->cipher->block_size) | 427 | if (len % cc->cipher->block_size) |
428 | fatal("%s: bad plaintext length %d", __func__, len); | 428 | return SSH_ERR_INVALID_ARGUMENT; |
429 | if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen, | 429 | if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen, |
430 | len) < 0) | 430 | len) < 0) |
431 | fatal("%s: EVP_Cipher failed", __func__); | 431 | return SSH_ERR_LIBCRYPTO_ERROR; |
432 | if (authlen) { | 432 | if (authlen) { |
433 | /* compute tag (on encrypt) or verify tag (on decrypt) */ | 433 | /* compute tag (on encrypt) or verify tag (on decrypt) */ |
434 | if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) { | 434 | if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) |
435 | if (cc->encrypt) | 435 | return cc->encrypt ? |
436 | fatal("%s: EVP_Cipher(final) failed", __func__); | 436 | SSH_ERR_LIBCRYPTO_ERROR : SSH_ERR_MAC_INVALID; |
437 | else | ||
438 | return -1; | ||
439 | } | ||
440 | if (cc->encrypt && | 437 | if (cc->encrypt && |
441 | !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG, | 438 | !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG, |
442 | authlen, dest + aadlen + len)) | 439 | authlen, dest + aadlen + len)) |
443 | fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__); | 440 | return SSH_ERR_LIBCRYPTO_ERROR; |
444 | } | 441 | } |
445 | return 0; | 442 | return 0; |
446 | #endif | 443 | #endif |
@@ -448,61 +445,65 @@ cipher_crypt(CipherContext *cc, u_int seqnr, u_char *dest, const u_char *src, | |||
448 | 445 | ||
449 | /* Extract the packet length, including any decryption necessary beforehand */ | 446 | /* Extract the packet length, including any decryption necessary beforehand */ |
450 | int | 447 | int |
451 | cipher_get_length(CipherContext *cc, u_int *plenp, u_int seqnr, | 448 | cipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr, |
452 | const u_char *cp, u_int len) | 449 | const u_char *cp, u_int len) |
453 | { | 450 | { |
454 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) | 451 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) |
455 | return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr, | 452 | return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr, |
456 | cp, len); | 453 | cp, len); |
457 | if (len < 4) | 454 | if (len < 4) |
458 | return -1; | 455 | return SSH_ERR_MESSAGE_INCOMPLETE; |
459 | *plenp = get_u32(cp); | 456 | *plenp = get_u32(cp); |
460 | return 0; | 457 | return 0; |
461 | } | 458 | } |
462 | 459 | ||
463 | void | 460 | int |
464 | cipher_cleanup(CipherContext *cc) | 461 | cipher_cleanup(struct sshcipher_ctx *cc) |
465 | { | 462 | { |
463 | if (cc == NULL || cc->cipher == NULL) | ||
464 | return 0; | ||
466 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) | 465 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) |
467 | explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); | 466 | explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); |
468 | else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) | 467 | else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) |
469 | explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx)); | 468 | explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx)); |
470 | #ifdef WITH_OPENSSL | 469 | #ifdef WITH_OPENSSL |
471 | else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) | 470 | else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) |
472 | error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); | 471 | return SSH_ERR_LIBCRYPTO_ERROR; |
473 | #endif | 472 | #endif |
473 | return 0; | ||
474 | } | 474 | } |
475 | 475 | ||
476 | /* | 476 | /* |
477 | * Selects the cipher, and keys if by computing the MD5 checksum of the | 477 | * Selects the cipher, and keys if by computing the MD5 checksum of the |
478 | * passphrase and using the resulting 16 bytes as the key. | 478 | * passphrase and using the resulting 16 bytes as the key. |
479 | */ | 479 | */ |
480 | 480 | int | |
481 | void | 481 | cipher_set_key_string(struct sshcipher_ctx *cc, const struct sshcipher *cipher, |
482 | cipher_set_key_string(CipherContext *cc, const Cipher *cipher, | ||
483 | const char *passphrase, int do_encrypt) | 482 | const char *passphrase, int do_encrypt) |
484 | { | 483 | { |
485 | u_char digest[16]; | 484 | u_char digest[16]; |
485 | int r = SSH_ERR_INTERNAL_ERROR; | ||
486 | 486 | ||
487 | if (ssh_digest_memory(SSH_DIGEST_MD5, passphrase, strlen(passphrase), | 487 | if ((r = ssh_digest_memory(SSH_DIGEST_MD5, |
488 | digest, sizeof(digest)) < 0) | 488 | passphrase, strlen(passphrase), |
489 | fatal("%s: md5 failed", __func__); | 489 | digest, sizeof(digest))) != 0) |
490 | 490 | goto out; | |
491 | cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt); | ||
492 | 491 | ||
492 | r = cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt); | ||
493 | out: | ||
493 | explicit_bzero(digest, sizeof(digest)); | 494 | explicit_bzero(digest, sizeof(digest)); |
495 | return r; | ||
494 | } | 496 | } |
495 | 497 | ||
496 | /* | 498 | /* |
497 | * Exports an IV from the CipherContext required to export the key | 499 | * Exports an IV from the sshcipher_ctx required to export the key |
498 | * state back from the unprivileged child to the privileged parent | 500 | * state back from the unprivileged child to the privileged parent |
499 | * process. | 501 | * process. |
500 | */ | 502 | */ |
501 | |||
502 | int | 503 | int |
503 | cipher_get_keyiv_len(const CipherContext *cc) | 504 | cipher_get_keyiv_len(const struct sshcipher_ctx *cc) |
504 | { | 505 | { |
505 | const Cipher *c = cc->cipher; | 506 | const struct sshcipher *c = cc->cipher; |
506 | int ivlen = 0; | 507 | int ivlen = 0; |
507 | 508 | ||
508 | if (c->number == SSH_CIPHER_3DES) | 509 | if (c->number == SSH_CIPHER_3DES) |
@@ -512,25 +513,25 @@ cipher_get_keyiv_len(const CipherContext *cc) | |||
512 | #ifdef WITH_OPENSSL | 513 | #ifdef WITH_OPENSSL |
513 | else | 514 | else |
514 | ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); | 515 | ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); |
515 | #endif | 516 | #endif /* WITH_OPENSSL */ |
516 | return (ivlen); | 517 | return (ivlen); |
517 | } | 518 | } |
518 | 519 | ||
519 | void | 520 | int |
520 | cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) | 521 | cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len) |
521 | { | 522 | { |
522 | const Cipher *c = cc->cipher; | 523 | const struct sshcipher *c = cc->cipher; |
523 | #ifdef WITH_OPENSSL | 524 | #ifdef WITH_OPENSSL |
524 | int evplen; | 525 | int evplen; |
525 | #endif | 526 | #endif |
526 | 527 | ||
527 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { | 528 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { |
528 | if (len != 0) | 529 | if (len != 0) |
529 | fatal("%s: wrong iv length %d != %d", __func__, len, 0); | 530 | return SSH_ERR_INVALID_ARGUMENT; |
530 | return; | 531 | return 0; |
531 | } | 532 | } |
532 | if ((cc->cipher->flags & CFLAG_NONE) != 0) | 533 | if ((cc->cipher->flags & CFLAG_NONE) != 0) |
533 | return; | 534 | return 0; |
534 | 535 | ||
535 | switch (c->number) { | 536 | switch (c->number) { |
536 | #ifdef WITH_OPENSSL | 537 | #ifdef WITH_OPENSSL |
@@ -538,51 +539,42 @@ cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) | |||
538 | case SSH_CIPHER_DES: | 539 | case SSH_CIPHER_DES: |
539 | case SSH_CIPHER_BLOWFISH: | 540 | case SSH_CIPHER_BLOWFISH: |
540 | evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); | 541 | evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); |
541 | if (evplen <= 0) | 542 | if (evplen == 0) |
542 | return; | 543 | return 0; |
544 | else if (evplen < 0) | ||
545 | return SSH_ERR_LIBCRYPTO_ERROR; | ||
543 | if ((u_int)evplen != len) | 546 | if ((u_int)evplen != len) |
544 | fatal("%s: wrong iv length %d != %d", __func__, | 547 | return SSH_ERR_INVALID_ARGUMENT; |
545 | evplen, len); | ||
546 | #ifdef USE_BUILTIN_RIJNDAEL | ||
547 | if (c->evptype == evp_rijndael) | ||
548 | ssh_rijndael_iv(&cc->evp, 0, iv, len); | ||
549 | else | ||
550 | #endif /* USE_BUILTIN_RIJNDAEL */ | ||
551 | #ifndef OPENSSL_HAVE_EVPCTR | ||
552 | if (c->evptype == evp_aes_128_ctr) | ||
553 | ssh_aes_ctr_iv(&cc->evp, 0, iv, len); | ||
554 | else | ||
555 | #endif /* OPENSSL_HAVE_EVPCTR */ | ||
556 | if (cipher_authlen(c)) { | 548 | if (cipher_authlen(c)) { |
557 | if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, | 549 | if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, |
558 | len, iv)) | 550 | len, iv)) |
559 | fatal("%s: EVP_CTRL_GCM_IV_GEN", __func__); | 551 | return SSH_ERR_LIBCRYPTO_ERROR; |
560 | } else | 552 | } else |
561 | memcpy(iv, cc->evp.iv, len); | 553 | memcpy(iv, cc->evp.iv, len); |
562 | break; | 554 | break; |
563 | #endif /* WITH_OPENSSL */ | 555 | #endif |
564 | #ifdef WITH_SSH1 | 556 | #ifdef WITH_SSH1 |
565 | case SSH_CIPHER_3DES: | 557 | case SSH_CIPHER_3DES: |
566 | ssh1_3des_iv(&cc->evp, 0, iv, 24); | 558 | return ssh1_3des_iv(&cc->evp, 0, iv, 24); |
567 | break; | 559 | #endif |
568 | #endif /* WITH_SSH1 */ | ||
569 | default: | 560 | default: |
570 | fatal("%s: bad cipher %d", __func__, c->number); | 561 | return SSH_ERR_INVALID_ARGUMENT; |
571 | } | 562 | } |
563 | return 0; | ||
572 | } | 564 | } |
573 | 565 | ||
574 | void | 566 | int |
575 | cipher_set_keyiv(CipherContext *cc, u_char *iv) | 567 | cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv) |
576 | { | 568 | { |
577 | const Cipher *c = cc->cipher; | 569 | const struct sshcipher *c = cc->cipher; |
578 | #ifdef WITH_OPENSSL | 570 | #ifdef WITH_OPENSSL |
579 | int evplen = 0; | 571 | int evplen = 0; |
580 | #endif | 572 | #endif |
581 | 573 | ||
582 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) | 574 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) |
583 | return; | 575 | return 0; |
584 | if ((cc->cipher->flags & CFLAG_NONE) != 0) | 576 | if ((cc->cipher->flags & CFLAG_NONE) != 0) |
585 | return; | 577 | return 0; |
586 | 578 | ||
587 | switch (c->number) { | 579 | switch (c->number) { |
588 | #ifdef WITH_OPENSSL | 580 | #ifdef WITH_OPENSSL |
@@ -590,42 +582,37 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv) | |||
590 | case SSH_CIPHER_DES: | 582 | case SSH_CIPHER_DES: |
591 | case SSH_CIPHER_BLOWFISH: | 583 | case SSH_CIPHER_BLOWFISH: |
592 | evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); | 584 | evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); |
593 | if (evplen == 0) | 585 | if (evplen <= 0) |
594 | return; | 586 | return SSH_ERR_LIBCRYPTO_ERROR; |
595 | #ifdef USE_BUILTIN_RIJNDAEL | ||
596 | if (c->evptype == evp_rijndael) | ||
597 | ssh_rijndael_iv(&cc->evp, 1, iv, evplen); | ||
598 | else | ||
599 | #endif /* USE_BUILTIN_RIJNDAEL */ | ||
600 | #ifndef OPENSSL_HAVE_EVPCTR | ||
601 | if (c->evptype == evp_aes_128_ctr) | ||
602 | ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen); | ||
603 | else | ||
604 | #endif /* OPENSSL_HAVE_EVPCTR */ | ||
605 | if (cipher_authlen(c)) { | 587 | if (cipher_authlen(c)) { |
588 | /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */ | ||
606 | if (!EVP_CIPHER_CTX_ctrl(&cc->evp, | 589 | if (!EVP_CIPHER_CTX_ctrl(&cc->evp, |
607 | EVP_CTRL_GCM_SET_IV_FIXED, -1, iv)) | 590 | EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) |
608 | fatal("%s: EVP_CTRL_GCM_SET_IV_FIXED failed", | 591 | return SSH_ERR_LIBCRYPTO_ERROR; |
609 | __func__); | 592 | } else |
610 | } else | 593 | memcpy(cc->evp.iv, iv, evplen); |
611 | memcpy(cc->evp.iv, iv, evplen); | ||
612 | break; | 594 | break; |
613 | #endif /* WITH_OPENSSL */ | 595 | #endif |
614 | #ifdef WITH_SSH1 | 596 | #ifdef WITH_SSH1 |
615 | case SSH_CIPHER_3DES: | 597 | case SSH_CIPHER_3DES: |
616 | ssh1_3des_iv(&cc->evp, 1, iv, 24); | 598 | return ssh1_3des_iv(&cc->evp, 1, (u_char *)iv, 24); |
617 | break; | 599 | #endif |
618 | #endif /* WITH_SSH1 */ | ||
619 | default: | 600 | default: |
620 | fatal("%s: bad cipher %d", __func__, c->number); | 601 | return SSH_ERR_INVALID_ARGUMENT; |
621 | } | 602 | } |
603 | return 0; | ||
622 | } | 604 | } |
623 | 605 | ||
606 | #ifdef WITH_OPENSSL | ||
607 | #define EVP_X_STATE(evp) (evp).cipher_data | ||
608 | #define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size | ||
609 | #endif | ||
610 | |||
624 | int | 611 | int |
625 | cipher_get_keycontext(const CipherContext *cc, u_char *dat) | 612 | cipher_get_keycontext(const struct sshcipher_ctx *cc, u_char *dat) |
626 | { | 613 | { |
627 | #ifdef WITH_OPENSSL | 614 | #ifdef WITH_OPENSSL |
628 | const Cipher *c = cc->cipher; | 615 | const struct sshcipher *c = cc->cipher; |
629 | int plen = 0; | 616 | int plen = 0; |
630 | 617 | ||
631 | if (c->evptype == EVP_rc4) { | 618 | if (c->evptype == EVP_rc4) { |
@@ -636,15 +623,15 @@ cipher_get_keycontext(const CipherContext *cc, u_char *dat) | |||
636 | } | 623 | } |
637 | return (plen); | 624 | return (plen); |
638 | #else | 625 | #else |
639 | return (0); | 626 | return 0; |
640 | #endif | 627 | #endif |
641 | } | 628 | } |
642 | 629 | ||
643 | void | 630 | void |
644 | cipher_set_keycontext(CipherContext *cc, u_char *dat) | 631 | cipher_set_keycontext(struct sshcipher_ctx *cc, const u_char *dat) |
645 | { | 632 | { |
646 | #ifdef WITH_OPENSSL | 633 | #ifdef WITH_OPENSSL |
647 | const Cipher *c = cc->cipher; | 634 | const struct sshcipher *c = cc->cipher; |
648 | int plen; | 635 | int plen; |
649 | 636 | ||
650 | if (c->evptype == EVP_rc4) { | 637 | if (c->evptype == EVP_rc4) { |