]> andersk Git - gssapi-openssh.git/blame - openssh/cipher.c
last appeared in 3.1p1
[gssapi-openssh.git] / openssh / cipher.c
CommitLineData
3c0ef626 1/*
2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved
5 *
6 * As far as I am concerned, the code I have written for this software
7 * can be used freely for any purpose. Any derived versions of this
8 * software must be clearly marked as such, and if the derived work is
9 * incompatible with the protocol description in the RFC file, it must be
10 * called by a name other than "ssh" or "Secure Shell".
11 *
12 *
13 * Copyright (c) 1999 Niels Provos. All rights reserved.
14 * Copyright (c) 1999, 2000 Markus Friedl. All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#include "includes.h"
700318f3 38RCSID("$OpenBSD: cipher.c,v 1.55 2002/04/03 09:26:11 markus Exp $");
3c0ef626 39
40#include "xmalloc.h"
41#include "log.h"
42#include "cipher.h"
43
44#include <openssl/md5.h>
e9a17296 45#include "rijndael.h"
46
700318f3 47#if OPENSSL_VERSION_NUMBER < 0x00906000L
48#define SSH_OLD_EVP
49#define EVP_CIPHER_CTX_get_app_data(e) ((e)->app_data)
50#endif
51
e9a17296 52static EVP_CIPHER *evp_ssh1_3des(void);
53static EVP_CIPHER *evp_ssh1_bf(void);
54static EVP_CIPHER *evp_rijndael(void);
55
56struct Cipher {
57 char *name;
58 int number; /* for ssh1 only */
59 u_int block_size;
60 u_int key_len;
61 EVP_CIPHER *(*evptype)(void);
62} ciphers[] = {
63 { "none", SSH_CIPHER_NONE, 8, 0, EVP_enc_null },
64 { "des", SSH_CIPHER_DES, 8, 8, EVP_des_cbc },
65 { "3des", SSH_CIPHER_3DES, 8, 16, evp_ssh1_3des },
66 { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, evp_ssh1_bf },
67
68 { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, EVP_des_ede3_cbc },
69 { "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, EVP_bf_cbc },
70 { "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, EVP_cast5_cbc },
71 { "arcfour", SSH_CIPHER_SSH2, 8, 16, EVP_rc4 },
72 { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, evp_rijndael },
73 { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, evp_rijndael },
74 { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, evp_rijndael },
700318f3 75 { "rijndael-cbc@lysator.liu.se",
76 SSH_CIPHER_SSH2, 16, 32, evp_rijndael },
e9a17296 77
78 { NULL, SSH_CIPHER_ILLEGAL, 0, 0, NULL }
79};
3c0ef626 80
e9a17296 81/*--*/
3c0ef626 82
700318f3 83u_int
e9a17296 84cipher_blocksize(Cipher *c)
3c0ef626 85{
e9a17296 86 return (c->block_size);
3c0ef626 87}
700318f3 88u_int
e9a17296 89cipher_keylen(Cipher *c)
3c0ef626 90{
e9a17296 91 return (c->key_len);
3c0ef626 92}
700318f3 93u_int
94cipher_get_number(Cipher *c)
95{
96 return (c->number);
97}
3c0ef626 98
3c0ef626 99u_int
100cipher_mask_ssh1(int client)
101{
102 u_int mask = 0;
e9a17296 103 mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */
3c0ef626 104 mask |= 1 << SSH_CIPHER_BLOWFISH;
105 if (client) {
106 mask |= 1 << SSH_CIPHER_DES;
107 }
108 return mask;
109}
110
111Cipher *
112cipher_by_name(const char *name)
113{
114 Cipher *c;
115 for (c = ciphers; c->name != NULL; c++)
116 if (strcasecmp(c->name, name) == 0)
117 return c;
118 return NULL;
119}
120
121Cipher *
122cipher_by_number(int id)
123{
124 Cipher *c;
125 for (c = ciphers; c->name != NULL; c++)
126 if (c->number == id)
127 return c;
128 return NULL;
129}
130
131#define CIPHER_SEP ","
132int
133ciphers_valid(const char *names)
134{
135 Cipher *c;
136 char *ciphers, *cp;
137 char *p;
138
139 if (names == NULL || strcmp(names, "") == 0)
140 return 0;
141 ciphers = cp = xstrdup(names);
142 for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
e9a17296 143 (p = strsep(&cp, CIPHER_SEP))) {
3c0ef626 144 c = cipher_by_name(p);
145 if (c == NULL || c->number != SSH_CIPHER_SSH2) {
146 debug("bad cipher %s [%s]", p, names);
147 xfree(ciphers);
148 return 0;
149 } else {
150 debug3("cipher ok: %s [%s]", p, names);
151 }
152 }
153 debug3("ciphers ok: [%s]", names);
154 xfree(ciphers);
155 return 1;
156}
157
158/*
159 * Parses the name of the cipher. Returns the number of the corresponding
160 * cipher, or -1 on error.
161 */
162
163int
164cipher_number(const char *name)
165{
166 Cipher *c;
167 if (name == NULL)
168 return -1;
169 c = cipher_by_name(name);
170 return (c==NULL) ? -1 : c->number;
171}
172
173char *
174cipher_name(int id)
175{
176 Cipher *c = cipher_by_number(id);
177 return (c==NULL) ? "<unknown>" : c->name;
178}
179
180void
181cipher_init(CipherContext *cc, Cipher *cipher,
e9a17296 182 const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
183 int encrypt)
3c0ef626 184{
e9a17296 185 static int dowarn = 1;
700318f3 186#ifdef SSH_OLD_EVP
187 EVP_CIPHER *type;
188#else
e9a17296 189 const EVP_CIPHER *type;
700318f3 190#endif
e9a17296 191 int klen;
192
193 if (cipher->number == SSH_CIPHER_DES) {
194 if (dowarn) {
195 error("Warning: use of DES is strongly discouraged "
196 "due to cryptographic weaknesses");
197 dowarn = 0;
198 }
199 if (keylen > 8)
200 keylen = 8;
201 }
202 cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
203
3c0ef626 204 if (keylen < cipher->key_len)
205 fatal("cipher_init: key length %d is insufficient for %s.",
206 keylen, cipher->name);
207 if (iv != NULL && ivlen < cipher->block_size)
208 fatal("cipher_init: iv length %d is insufficient for %s.",
209 ivlen, cipher->name);
210 cc->cipher = cipher;
e9a17296 211
212 type = (*cipher->evptype)();
213
214 EVP_CIPHER_CTX_init(&cc->evp);
700318f3 215#ifdef SSH_OLD_EVP
216 if (type->key_len > 0 && type->key_len != keylen) {
217 debug("cipher_init: set keylen (%d -> %d)",
218 type->key_len, keylen);
219 type->key_len = keylen;
220 }
221 EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv,
222 (encrypt == CIPHER_ENCRYPT));
223#else
e9a17296 224 if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
225 (encrypt == CIPHER_ENCRYPT)) == 0)
226 fatal("cipher_init: EVP_CipherInit failed for %s",
227 cipher->name);
228 klen = EVP_CIPHER_CTX_key_length(&cc->evp);
229 if (klen > 0 && keylen != klen) {
230 debug("cipher_init: set keylen (%d -> %d)", klen, keylen);
231 if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0)
232 fatal("cipher_init: set keylen failed (%d -> %d)",
233 klen, keylen);
234 }
235 if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0)
236 fatal("cipher_init: EVP_CipherInit: set key failed for %s",
237 cipher->name);
700318f3 238#endif
3c0ef626 239}
240
241void
e9a17296 242cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
3c0ef626 243{
244 if (len % cc->cipher->block_size)
245 fatal("cipher_encrypt: bad plaintext length %d", len);
700318f3 246#ifdef SSH_OLD_EVP
247 EVP_Cipher(&cc->evp, dest, (u_char *)src, len);
248#else
e9a17296 249 if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0)
250 fatal("evp_crypt: EVP_Cipher failed");
700318f3 251#endif
3c0ef626 252}
253
254void
e9a17296 255cipher_cleanup(CipherContext *cc)
3c0ef626 256{
700318f3 257#ifdef SSH_OLD_EVP
258 EVP_CIPHER_CTX_cleanup(&cc->evp);
259#else
e9a17296 260 if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
261 error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
700318f3 262#endif
3c0ef626 263}
264
265/*
266 * Selects the cipher, and keys if by computing the MD5 checksum of the
267 * passphrase and using the resulting 16 bytes as the key.
268 */
269
270void
271cipher_set_key_string(CipherContext *cc, Cipher *cipher,
e9a17296 272 const char *passphrase, int encrypt)
3c0ef626 273{
274 MD5_CTX md;
275 u_char digest[16];
276
277 MD5_Init(&md);
278 MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase));
279 MD5_Final(digest, &md);
280
e9a17296 281 cipher_init(cc, cipher, digest, 16, NULL, 0, encrypt);
3c0ef626 282
283 memset(digest, 0, sizeof(digest));
284 memset(&md, 0, sizeof(md));
285}
e9a17296 286
287/* Implementations for other non-EVP ciphers */
288
289/*
290 * This is used by SSH1:
291 *
292 * What kind of triple DES are these 2 routines?
293 *
294 * Why is there a redundant initialization vector?
295 *
296 * If only iv3 was used, then, this would till effect have been
297 * outer-cbc. However, there is also a private iv1 == iv2 which
298 * perhaps makes differential analysis easier. On the other hand, the
299 * private iv1 probably makes the CRC-32 attack ineffective. This is a
300 * result of that there is no longer any known iv1 to use when
301 * choosing the X block.
302 */
303struct ssh1_3des_ctx
304{
305 EVP_CIPHER_CTX k1, k2, k3;
306};
307static int
308ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
309 int enc)
310{
311 struct ssh1_3des_ctx *c;
312 u_char *k1, *k2, *k3;
313
314 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
315 c = xmalloc(sizeof(*c));
316 EVP_CIPHER_CTX_set_app_data(ctx, c);
317 }
318 if (key == NULL)
319 return (1);
320 if (enc == -1)
321 enc = ctx->encrypt;
322 k1 = k2 = k3 = (u_char *) key;
323 k2 += 8;
324 if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) {
325 if (enc)
326 k3 += 16;
327 else
328 k1 += 16;
329 }
330 EVP_CIPHER_CTX_init(&c->k1);
331 EVP_CIPHER_CTX_init(&c->k2);
332 EVP_CIPHER_CTX_init(&c->k3);
700318f3 333#ifdef SSH_OLD_EVP
334 EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc);
335 EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc);
336 EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc);
337#else
e9a17296 338 if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
339 EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
340 EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
341 memset(c, 0, sizeof(*c));
342 xfree(c);
343 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
344 return (0);
345 }
700318f3 346#endif
e9a17296 347 return (1);
348}
349static int
350ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len)
351{
352 struct ssh1_3des_ctx *c;
353
354 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
355 error("ssh1_3des_cbc: no context");
356 return (0);
357 }
700318f3 358#ifdef SSH_OLD_EVP
359 EVP_Cipher(&c->k1, dest, (u_char *)src, len);
360 EVP_Cipher(&c->k2, dest, dest, len);
361 EVP_Cipher(&c->k3, dest, dest, len);
362#else
e9a17296 363 if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 ||
364 EVP_Cipher(&c->k2, dest, dest, len) == 0 ||
365 EVP_Cipher(&c->k3, dest, dest, len) == 0)
366 return (0);
700318f3 367#endif
e9a17296 368 return (1);
369}
370static int
371ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
372{
373 struct ssh1_3des_ctx *c;
374
375 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
376 memset(c, 0, sizeof(*c));
377 xfree(c);
378 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
379 }
380 return (1);
381}
382static EVP_CIPHER *
383evp_ssh1_3des(void)
384{
385 static EVP_CIPHER ssh1_3des;
386
387 memset(&ssh1_3des, 0, sizeof(EVP_CIPHER));
388 ssh1_3des.nid = NID_undef;
389 ssh1_3des.block_size = 8;
390 ssh1_3des.iv_len = 0;
391 ssh1_3des.key_len = 16;
392 ssh1_3des.init = ssh1_3des_init;
393 ssh1_3des.cleanup = ssh1_3des_cleanup;
394 ssh1_3des.do_cipher = ssh1_3des_cbc;
700318f3 395#ifndef SSH_OLD_EVP
e9a17296 396 ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH;
700318f3 397#endif
e9a17296 398 return (&ssh1_3des);
399}
400
401/*
402 * SSH1 uses a variation on Blowfish, all bytes must be swapped before
403 * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
404 */
405static void
406swap_bytes(const u_char *src, u_char *dst, int n)
407{
408 u_char c[4];
409
410 /* Process 4 bytes every lap. */
411 for (n = n / 4; n > 0; n--) {
412 c[3] = *src++;
413 c[2] = *src++;
414 c[1] = *src++;
415 c[0] = *src++;
416
417 *dst++ = c[0];
418 *dst++ = c[1];
419 *dst++ = c[2];
420 *dst++ = c[3];
421 }
422}
423static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *, const u_char *, u_int) = NULL;
424static int
425bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in, u_int len)
426{
427 int ret;
428
429 swap_bytes(in, out, len);
430 ret = (*orig_bf)(ctx, out, out, len);
431 swap_bytes(out, out, len);
432 return (ret);
433}
434static EVP_CIPHER *
435evp_ssh1_bf(void)
436{
437 static EVP_CIPHER ssh1_bf;
438
439 memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER));
440 orig_bf = ssh1_bf.do_cipher;
441 ssh1_bf.nid = NID_undef;
442 ssh1_bf.do_cipher = bf_ssh1_cipher;
443 ssh1_bf.key_len = 32;
444 return (&ssh1_bf);
445}
446
447/* RIJNDAEL */
448#define RIJNDAEL_BLOCKSIZE 16
449struct ssh_rijndael_ctx
450{
451 rijndael_ctx r_ctx;
452 u_char r_iv[RIJNDAEL_BLOCKSIZE];
453};
454
455static int
456ssh_rijndael_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
457 int enc)
458{
459 struct ssh_rijndael_ctx *c;
460
461 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
462 c = xmalloc(sizeof(*c));
463 EVP_CIPHER_CTX_set_app_data(ctx, c);
464 }
465 if (key != NULL) {
466 if (enc == -1)
467 enc = ctx->encrypt;
468 rijndael_set_key(&c->r_ctx, (u_char *)key,
469 8*EVP_CIPHER_CTX_key_length(ctx), enc);
470 }
471 if (iv != NULL)
472 memcpy(c->r_iv, iv, RIJNDAEL_BLOCKSIZE);
473 return (1);
474}
475static int
476ssh_rijndael_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
477 u_int len)
478{
479 struct ssh_rijndael_ctx *c;
480 u_char buf[RIJNDAEL_BLOCKSIZE];
481 u_char *cprev, *cnow, *plain, *ivp;
482 int i, j, blocks = len / RIJNDAEL_BLOCKSIZE;
483
484 if (len == 0)
485 return (1);
486 if (len % RIJNDAEL_BLOCKSIZE)
487 fatal("ssh_rijndael_cbc: bad len %d", len);
488 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
489 error("ssh_rijndael_cbc: no context");
490 return (0);
491 }
492 if (ctx->encrypt) {
493 cnow = dest;
494 plain = (u_char *)src;
495 cprev = c->r_iv;
496 for (i = 0; i < blocks; i++, plain+=RIJNDAEL_BLOCKSIZE,
497 cnow+=RIJNDAEL_BLOCKSIZE) {
498 for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
499 buf[j] = plain[j] ^ cprev[j];
500 rijndael_encrypt(&c->r_ctx, buf, cnow);
501 cprev = cnow;
502 }
503 memcpy(c->r_iv, cprev, RIJNDAEL_BLOCKSIZE);
504 } else {
505 cnow = (u_char *) (src+len-RIJNDAEL_BLOCKSIZE);
506 plain = dest+len-RIJNDAEL_BLOCKSIZE;
507
508 memcpy(buf, cnow, RIJNDAEL_BLOCKSIZE);
509 for (i = blocks; i > 0; i--, cnow-=RIJNDAEL_BLOCKSIZE,
510 plain-=RIJNDAEL_BLOCKSIZE) {
511 rijndael_decrypt(&c->r_ctx, cnow, plain);
512 ivp = (i == 1) ? c->r_iv : cnow-RIJNDAEL_BLOCKSIZE;
513 for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
514 plain[j] ^= ivp[j];
515 }
516 memcpy(c->r_iv, buf, RIJNDAEL_BLOCKSIZE);
517 }
518 return (1);
519}
520static int
521ssh_rijndael_cleanup(EVP_CIPHER_CTX *ctx)
522{
523 struct ssh_rijndael_ctx *c;
524
525 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
526 memset(c, 0, sizeof(*c));
527 xfree(c);
528 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
529 }
530 return (1);
531}
532static EVP_CIPHER *
533evp_rijndael(void)
534{
535 static EVP_CIPHER rijndal_cbc;
536
537 memset(&rijndal_cbc, 0, sizeof(EVP_CIPHER));
538 rijndal_cbc.nid = NID_undef;
539 rijndal_cbc.block_size = RIJNDAEL_BLOCKSIZE;
540 rijndal_cbc.iv_len = RIJNDAEL_BLOCKSIZE;
541 rijndal_cbc.key_len = 16;
542 rijndal_cbc.init = ssh_rijndael_init;
543 rijndal_cbc.cleanup = ssh_rijndael_cleanup;
544 rijndal_cbc.do_cipher = ssh_rijndael_cbc;
700318f3 545#ifndef SSH_OLD_EVP
e9a17296 546 rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
547 EVP_CIPH_ALWAYS_CALL_INIT;
700318f3 548#endif
e9a17296 549 return (&rijndal_cbc);
550}
700318f3 551
552/*
553 * Exports an IV from the CipherContext required to export the key
554 * state back from the unprivileged child to the privileged parent
555 * process.
556 */
557
558int
559cipher_get_keyiv_len(CipherContext *cc)
560{
561 Cipher *c = cc->cipher;
562 int ivlen;
563
564 if (c->number == SSH_CIPHER_3DES)
565 ivlen = 24;
566 else
567 ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp);
568 return (ivlen);
569}
570
571void
572cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
573{
574 Cipher *c = cc->cipher;
575 u_char *civ = NULL;
576 int evplen;
577
578 switch (c->number) {
579 case SSH_CIPHER_SSH2:
580 case SSH_CIPHER_DES:
581 case SSH_CIPHER_BLOWFISH:
582 evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
583 if (evplen == 0)
584 return;
585 if (evplen != len)
586 fatal("%s: wrong iv length %d != %d", __FUNCTION__,
587 evplen, len);
588
589 if (c->evptype == evp_rijndael) {
590 struct ssh_rijndael_ctx *aesc;
591
592 aesc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
593 if (aesc == NULL)
594 fatal("%s: no rijndael context", __FUNCTION__);
595 civ = aesc->r_iv;
596 } else {
597 civ = cc->evp.iv;
598 }
599 break;
600 case SSH_CIPHER_3DES: {
601 struct ssh1_3des_ctx *desc;
602 if (len != 24)
603 fatal("%s: bad 3des iv length: %d", __FUNCTION__, len);
604 desc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
605 if (desc == NULL)
606 fatal("%s: no 3des context", __FUNCTION__);
607 debug3("%s: Copying 3DES IV", __FUNCTION__);
608 memcpy(iv, desc->k1.iv, 8);
609 memcpy(iv + 8, desc->k2.iv, 8);
610 memcpy(iv + 16, desc->k3.iv, 8);
611 return;
612 }
613 default:
614 fatal("%s: bad cipher %d", __FUNCTION__, c->number);
615 }
616 memcpy(iv, civ, len);
617}
618
619void
620cipher_set_keyiv(CipherContext *cc, u_char *iv)
621{
622 Cipher *c = cc->cipher;
623 u_char *div = NULL;
624 int evplen = 0;
625
626 switch (c->number) {
627 case SSH_CIPHER_SSH2:
628 case SSH_CIPHER_DES:
629 case SSH_CIPHER_BLOWFISH:
630 evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
631 if (evplen == 0)
632 return;
633
634 if (c->evptype == evp_rijndael) {
635 struct ssh_rijndael_ctx *aesc;
636
637 aesc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
638 if (aesc == NULL)
639 fatal("%s: no rijndael context", __FUNCTION__);
640 div = aesc->r_iv;
641 }else {
642 div = cc->evp.iv;
643 }
644 break;
645 case SSH_CIPHER_3DES: {
646 struct ssh1_3des_ctx *desc;
647 desc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
648 if (desc == NULL)
649 fatal("%s: no 3des context", __FUNCTION__);
650 debug3("%s: Installed 3DES IV", __FUNCTION__);
651 memcpy(desc->k1.iv, iv, 8);
652 memcpy(desc->k2.iv, iv + 8, 8);
653 memcpy(desc->k3.iv, iv + 16, 8);
654 return;
655 }
656 default:
657 fatal("%s: bad cipher %d", __FUNCTION__, c->number);
658 }
659 memcpy(div, iv, evplen);
660}
661
662#if OPENSSL_VERSION_NUMBER < 0x00907000L
663#define EVP_X_STATE(evp) &(evp).c
664#define EVP_X_STATE_LEN(evp) sizeof((evp).c)
665#else
666#define EVP_X_STATE(evp) (evp).cipher_data
667#define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size
668#endif
669
670int
671cipher_get_keycontext(CipherContext *cc, u_char *dat)
672{
673 Cipher *c = cc->cipher;
674 int plen;
675
676 if (c->number == SSH_CIPHER_3DES) {
677 struct ssh1_3des_ctx *desc;
678 desc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
679 if (desc == NULL)
680 fatal("%s: no 3des context", __FUNCTION__);
681 plen = EVP_X_STATE_LEN(desc->k1);
682 if (dat == NULL)
683 return (3*plen);
684 memcpy(dat, EVP_X_STATE(desc->k1), plen);
685 memcpy(dat + plen, EVP_X_STATE(desc->k2), plen);
686 memcpy(dat + 2*plen, EVP_X_STATE(desc->k3), plen);
687 return (3*plen);
688 }
689
690 /* Generic EVP */
691 plen = EVP_X_STATE_LEN(cc->evp);
692 if (dat == NULL)
693 return (plen);
694
695 memcpy(dat, EVP_X_STATE(cc->evp), plen);
696 return (plen);
697}
698
699void
700cipher_set_keycontext(CipherContext *cc, u_char *dat)
701{
702 Cipher *c = cc->cipher;
703 int plen;
704
705 if (c->number == SSH_CIPHER_3DES) {
706 struct ssh1_3des_ctx *desc;
707 desc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
708 if (desc == NULL)
709 fatal("%s: no 3des context", __FUNCTION__);
710 plen = EVP_X_STATE_LEN(desc->k1);
711 memcpy(EVP_X_STATE(desc->k1), dat, plen);
712 memcpy(EVP_X_STATE(desc->k2), dat + plen, plen);
713 memcpy(EVP_X_STATE(desc->k3), dat + 2*plen, plen);
714 } else {
715 plen = EVP_X_STATE_LEN(cc->evp);
716 memcpy(EVP_X_STATE(cc->evp), dat, plen);
717 }
718}
This page took 0.150268 seconds and 5 git commands to generate.