]> andersk Git - openssh.git/blame - cipher.c
- (djm) Add Markus' patch for compat wih OpenSSL < 0.9.6.
[openssh.git] / cipher.c
CommitLineData
8efc0c15 1/*
5260325f 2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
5260325f 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved
6ae2364d 5 *
bcbf86ec 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.
a96070d4 14 * Copyright (c) 1999, 2000 Markus Friedl. All rights reserved.
bcbf86ec 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.
6ae2364d 24 *
bcbf86ec 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.
5260325f 35 */
8efc0c15 36
37#include "includes.h"
70fc1609 38RCSID("$OpenBSD: cipher.c,v 1.52 2002/02/18 13:05:32 markus Exp $");
8efc0c15 39
a8be9f80 40#include "xmalloc.h"
42f11eb2 41#include "log.h"
42#include "cipher.h"
8efc0c15 43
44#include <openssl/md5.h>
70fc1609 45#include "rijndael.h"
46
a068d86f 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
70fc1609 52static EVP_CIPHER *evp_ssh1_3des(void);
53static EVP_CIPHER *evp_ssh1_bf(void);
54static EVP_CIPHER *evp_rijndael(void);
8efc0c15 55
3ee832e5 56struct Cipher {
57 char *name;
58 int number; /* for ssh1 only */
59 u_int block_size;
60 u_int key_len;
70fc1609 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 },
75
76 { NULL, SSH_CIPHER_ILLEGAL, 0, 0, NULL }
94ec8c6b 77};
78
79/*--*/
80
70fc1609 81u_int
3ee832e5 82cipher_blocksize(Cipher *c)
83{
84 return (c->block_size);
85}
70fc1609 86u_int
3ee832e5 87cipher_keylen(Cipher *c)
88{
89 return (c->key_len);
90}
91
1e3b8b07 92u_int
94ec8c6b 93cipher_mask_ssh1(int client)
8ce64345 94{
1e3b8b07 95 u_int mask = 0;
184eed6a 96 mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */
94ec8c6b 97 mask |= 1 << SSH_CIPHER_BLOWFISH;
98 if (client) {
99 mask |= 1 << SSH_CIPHER_DES;
100 }
5260325f 101 return mask;
8efc0c15 102}
94ec8c6b 103
104Cipher *
105cipher_by_name(const char *name)
8ce64345 106{
94ec8c6b 107 Cipher *c;
108 for (c = ciphers; c->name != NULL; c++)
109 if (strcasecmp(c->name, name) == 0)
110 return c;
111 return NULL;
8ce64345 112}
8efc0c15 113
94ec8c6b 114Cipher *
115cipher_by_number(int id)
8efc0c15 116{
94ec8c6b 117 Cipher *c;
118 for (c = ciphers; c->name != NULL; c++)
119 if (c->number == id)
120 return c;
121 return NULL;
8efc0c15 122}
123
a8be9f80 124#define CIPHER_SEP ","
125int
126ciphers_valid(const char *names)
127{
94ec8c6b 128 Cipher *c;
089fbbd2 129 char *ciphers, *cp;
a8be9f80 130 char *p;
a8be9f80 131
71276795 132 if (names == NULL || strcmp(names, "") == 0)
a8be9f80 133 return 0;
089fbbd2 134 ciphers = cp = xstrdup(names);
94ec8c6b 135 for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
184eed6a 136 (p = strsep(&cp, CIPHER_SEP))) {
94ec8c6b 137 c = cipher_by_name(p);
138 if (c == NULL || c->number != SSH_CIPHER_SSH2) {
139 debug("bad cipher %s [%s]", p, names);
a8be9f80 140 xfree(ciphers);
141 return 0;
94ec8c6b 142 } else {
33de75a3 143 debug3("cipher ok: %s [%s]", p, names);
a8be9f80 144 }
145 }
33de75a3 146 debug3("ciphers ok: [%s]", names);
a8be9f80 147 xfree(ciphers);
148 return 1;
149}
150
aa3378df 151/*
152 * Parses the name of the cipher. Returns the number of the corresponding
153 * cipher, or -1 on error.
154 */
8efc0c15 155
156int
157cipher_number(const char *name)
158{
94ec8c6b 159 Cipher *c;
71276795 160 if (name == NULL)
161 return -1;
94ec8c6b 162 c = cipher_by_name(name);
163 return (c==NULL) ? -1 : c->number;
164}
165
166char *
167cipher_name(int id)
168{
169 Cipher *c = cipher_by_number(id);
170 return (c==NULL) ? "<unknown>" : c->name;
171}
172
173void
70fc1609 174cipher_init(CipherContext *cc, Cipher *cipher,
175 const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
176 int encrypt)
94ec8c6b 177{
70fc1609 178 static int dowarn = 1;
a068d86f 179#ifdef SSH_OLD_EVP
180 EVP_CIPHER *type;
181#else
70fc1609 182 const EVP_CIPHER *type;
a068d86f 183#endif
70fc1609 184 int klen;
185
186 if (cipher->number == SSH_CIPHER_DES) {
187 if (dowarn) {
188 error("Warning: use of DES is strongly discouraged "
189 "due to cryptographic weaknesses");
190 dowarn = 0;
191 }
192 if (keylen > 8)
193 keylen = 8;
194 }
195 cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
196
94ec8c6b 197 if (keylen < cipher->key_len)
198 fatal("cipher_init: key length %d is insufficient for %s.",
199 keylen, cipher->name);
200 if (iv != NULL && ivlen < cipher->block_size)
201 fatal("cipher_init: iv length %d is insufficient for %s.",
202 ivlen, cipher->name);
203 cc->cipher = cipher;
70fc1609 204
205 type = (*cipher->evptype)();
206
207 EVP_CIPHER_CTX_init(&cc->evp);
a068d86f 208#ifdef SSH_OLD_EVP
209 if (type->key_len > 0 && type->key_len != keylen) {
210 debug("cipher_init: set keylen (%d -> %d)",
211 type->key_len, keylen);
212 type->key_len = keylen;
213 }
214 EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv,
215 (encrypt == CIPHER_ENCRYPT));
216#else
70fc1609 217 if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
218 (encrypt == CIPHER_ENCRYPT)) == 0)
219 fatal("cipher_init: EVP_CipherInit failed for %s",
220 cipher->name);
221 klen = EVP_CIPHER_CTX_key_length(&cc->evp);
222 if (klen > 0 && keylen != klen) {
223 debug("cipher_init: set keylen (%d -> %d)", klen, keylen);
224 if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0)
225 fatal("cipher_init: set keylen failed (%d -> %d)",
226 klen, keylen);
227 }
228 if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0)
229 fatal("cipher_init: EVP_CipherInit: set key failed for %s",
230 cipher->name);
a068d86f 231#endif
94ec8c6b 232}
233
234void
3ee832e5 235cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
94ec8c6b 236{
237 if (len % cc->cipher->block_size)
238 fatal("cipher_encrypt: bad plaintext length %d", len);
a068d86f 239#ifdef SSH_OLD_EVP
240 EVP_Cipher(&cc->evp, dest, (u_char *)src, len);
241#else
70fc1609 242 if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0)
243 fatal("evp_crypt: EVP_Cipher failed");
a068d86f 244#endif
94ec8c6b 245}
246
247void
3ee832e5 248cipher_cleanup(CipherContext *cc)
94ec8c6b 249{
a068d86f 250#ifdef SSH_OLD_EVP
251 EVP_CIPHER_CTX_cleanup(&cc->evp);
252#else
70fc1609 253 if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
254 error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
a068d86f 255#endif
8efc0c15 256}
257
aa3378df 258/*
259 * Selects the cipher, and keys if by computing the MD5 checksum of the
260 * passphrase and using the resulting 16 bytes as the key.
261 */
8efc0c15 262
6ae2364d 263void
94ec8c6b 264cipher_set_key_string(CipherContext *cc, Cipher *cipher,
3ee832e5 265 const char *passphrase, int encrypt)
8efc0c15 266{
5260325f 267 MD5_CTX md;
1e3b8b07 268 u_char digest[16];
5260325f 269
270 MD5_Init(&md);
94ec8c6b 271 MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase));
5260325f 272 MD5_Final(digest, &md);
273
3ee832e5 274 cipher_init(cc, cipher, digest, 16, NULL, 0, encrypt);
5260325f 275
276 memset(digest, 0, sizeof(digest));
277 memset(&md, 0, sizeof(md));
8efc0c15 278}
70fc1609 279
280/* Implementations for other non-EVP ciphers */
281
282/*
283 * This is used by SSH1:
284 *
285 * What kind of triple DES are these 2 routines?
286 *
287 * Why is there a redundant initialization vector?
288 *
289 * If only iv3 was used, then, this would till effect have been
290 * outer-cbc. However, there is also a private iv1 == iv2 which
291 * perhaps makes differential analysis easier. On the other hand, the
292 * private iv1 probably makes the CRC-32 attack ineffective. This is a
293 * result of that there is no longer any known iv1 to use when
294 * choosing the X block.
295 */
296struct ssh1_3des_ctx
297{
298 EVP_CIPHER_CTX k1, k2, k3;
299};
300static int
301ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
302 int enc)
303{
304 struct ssh1_3des_ctx *c;
305 u_char *k1, *k2, *k3;
306
307 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
308 c = xmalloc(sizeof(*c));
309 EVP_CIPHER_CTX_set_app_data(ctx, c);
310 }
311 if (key == NULL)
312 return (1);
313 if (enc == -1)
314 enc = ctx->encrypt;
315 k1 = k2 = k3 = (u_char *) key;
316 k2 += 8;
317 if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) {
318 if (enc)
319 k3 += 16;
320 else
321 k1 += 16;
322 }
323 EVP_CIPHER_CTX_init(&c->k1);
324 EVP_CIPHER_CTX_init(&c->k2);
325 EVP_CIPHER_CTX_init(&c->k3);
a068d86f 326#ifdef SSH_OLD_EVP
327 EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc);
328 EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc);
329 EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc);
330#else
70fc1609 331 if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
332 EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
333 EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
334 memset(c, 0, sizeof(*c));
335 xfree(c);
336 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
337 return (0);
338 }
a068d86f 339#endif
70fc1609 340 return (1);
341}
342static int
343ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len)
344{
345 struct ssh1_3des_ctx *c;
346
347 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
348 error("ssh1_3des_cbc: no context");
349 return (0);
350 }
a068d86f 351#ifdef SSH_OLD_EVP
352 EVP_Cipher(&c->k1, dest, (u_char *)src, len);
353 EVP_Cipher(&c->k2, dest, dest, len);
354 EVP_Cipher(&c->k3, dest, dest, len);
355#else
70fc1609 356 if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 ||
357 EVP_Cipher(&c->k2, dest, dest, len) == 0 ||
358 EVP_Cipher(&c->k3, dest, dest, len) == 0)
359 return (0);
a068d86f 360#endif
70fc1609 361 return (1);
362}
363static int
364ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
365{
366 struct ssh1_3des_ctx *c;
367
368 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
369 memset(c, 0, sizeof(*c));
370 xfree(c);
371 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
372 }
373 return (1);
374}
375static EVP_CIPHER *
376evp_ssh1_3des(void)
377{
378 static EVP_CIPHER ssh1_3des;
379
380 memset(&ssh1_3des, 0, sizeof(EVP_CIPHER));
381 ssh1_3des.nid = NID_undef;
382 ssh1_3des.block_size = 8;
383 ssh1_3des.iv_len = 0;
384 ssh1_3des.key_len = 16;
385 ssh1_3des.init = ssh1_3des_init;
386 ssh1_3des.cleanup = ssh1_3des_cleanup;
387 ssh1_3des.do_cipher = ssh1_3des_cbc;
a068d86f 388#ifndef SSH_OLD_EVP
70fc1609 389 ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH;
a068d86f 390#endif
70fc1609 391 return (&ssh1_3des);
392}
393
394/*
395 * SSH1 uses a variation on Blowfish, all bytes must be swapped before
396 * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
397 */
398static void
399swap_bytes(const u_char *src, u_char *dst, int n)
400{
401 u_char c[4];
402
403 /* Process 4 bytes every lap. */
404 for (n = n / 4; n > 0; n--) {
405 c[3] = *src++;
406 c[2] = *src++;
407 c[1] = *src++;
408 c[0] = *src++;
409
410 *dst++ = c[0];
411 *dst++ = c[1];
412 *dst++ = c[2];
413 *dst++ = c[3];
414 }
415}
416static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *, const u_char *, u_int) = NULL;
417static int
418bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in, u_int len)
419{
420 int ret;
421
422 swap_bytes(in, out, len);
423 ret = (*orig_bf)(ctx, out, out, len);
424 swap_bytes(out, out, len);
425 return (ret);
426}
427static EVP_CIPHER *
428evp_ssh1_bf(void)
429{
430 static EVP_CIPHER ssh1_bf;
431
432 memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER));
433 orig_bf = ssh1_bf.do_cipher;
434 ssh1_bf.nid = NID_undef;
435 ssh1_bf.do_cipher = bf_ssh1_cipher;
436 ssh1_bf.key_len = 32;
437 return (&ssh1_bf);
438}
439
440/* RIJNDAEL */
441#define RIJNDAEL_BLOCKSIZE 16
442struct ssh_rijndael_ctx
443{
444 rijndael_ctx r_ctx;
445 u_char r_iv[RIJNDAEL_BLOCKSIZE];
446};
447
448static int
449ssh_rijndael_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
450 int enc)
451{
452 struct ssh_rijndael_ctx *c;
453
454 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
455 c = xmalloc(sizeof(*c));
456 EVP_CIPHER_CTX_set_app_data(ctx, c);
457 }
458 if (key != NULL) {
459 if (enc == -1)
460 enc = ctx->encrypt;
461 rijndael_set_key(&c->r_ctx, (u_char *)key,
462 8*EVP_CIPHER_CTX_key_length(ctx), enc);
463 }
464 if (iv != NULL)
465 memcpy(c->r_iv, iv, RIJNDAEL_BLOCKSIZE);
466 return (1);
467}
468static int
469ssh_rijndael_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
470 u_int len)
471{
472 struct ssh_rijndael_ctx *c;
473 u_char buf[RIJNDAEL_BLOCKSIZE];
474 u_char *cprev, *cnow, *plain, *ivp;
475 int i, j, blocks = len / RIJNDAEL_BLOCKSIZE;
476
477 if (len == 0)
478 return (1);
479 if (len % RIJNDAEL_BLOCKSIZE)
480 fatal("ssh_rijndael_cbc: bad len %d", len);
481 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
482 error("ssh_rijndael_cbc: no context");
483 return (0);
484 }
485 if (ctx->encrypt) {
486 cnow = dest;
487 plain = (u_char *)src;
488 cprev = c->r_iv;
489 for (i = 0; i < blocks; i++, plain+=RIJNDAEL_BLOCKSIZE,
490 cnow+=RIJNDAEL_BLOCKSIZE) {
491 for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
492 buf[j] = plain[j] ^ cprev[j];
493 rijndael_encrypt(&c->r_ctx, buf, cnow);
494 cprev = cnow;
495 }
496 memcpy(c->r_iv, cprev, RIJNDAEL_BLOCKSIZE);
497 } else {
498 cnow = (u_char *) (src+len-RIJNDAEL_BLOCKSIZE);
499 plain = dest+len-RIJNDAEL_BLOCKSIZE;
500
501 memcpy(buf, cnow, RIJNDAEL_BLOCKSIZE);
502 for (i = blocks; i > 0; i--, cnow-=RIJNDAEL_BLOCKSIZE,
503 plain-=RIJNDAEL_BLOCKSIZE) {
504 rijndael_decrypt(&c->r_ctx, cnow, plain);
505 ivp = (i == 1) ? c->r_iv : cnow-RIJNDAEL_BLOCKSIZE;
506 for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
507 plain[j] ^= ivp[j];
508 }
509 memcpy(c->r_iv, buf, RIJNDAEL_BLOCKSIZE);
510 }
511 return (1);
512}
513static int
514ssh_rijndael_cleanup(EVP_CIPHER_CTX *ctx)
515{
516 struct ssh_rijndael_ctx *c;
517
518 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
519 memset(c, 0, sizeof(*c));
520 xfree(c);
521 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
522 }
523 return (1);
524}
525static EVP_CIPHER *
526evp_rijndael(void)
527{
528 static EVP_CIPHER rijndal_cbc;
529
530 memset(&rijndal_cbc, 0, sizeof(EVP_CIPHER));
531 rijndal_cbc.nid = NID_undef;
532 rijndal_cbc.block_size = RIJNDAEL_BLOCKSIZE;
533 rijndal_cbc.iv_len = RIJNDAEL_BLOCKSIZE;
534 rijndal_cbc.key_len = 16;
535 rijndal_cbc.init = ssh_rijndael_init;
536 rijndal_cbc.cleanup = ssh_rijndael_cleanup;
537 rijndal_cbc.do_cipher = ssh_rijndael_cbc;
a068d86f 538#ifndef SSH_OLD_EVP
70fc1609 539 rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
540 EVP_CIPH_ALWAYS_CALL_INIT;
a068d86f 541#endif
70fc1609 542 return (&rijndal_cbc);
543}
This page took 0.330594 seconds and 5 git commands to generate.