]> andersk Git - openssh.git/blob - cipher.c
- deraadt@cvs.openbsd.org 2006/03/19 18:51:18
[openssh.git] / cipher.c
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"
38
39 #include "xmalloc.h"
40 #include "log.h"
41 #include "cipher.h"
42
43 #include <openssl/md5.h>
44
45 /* compatibility with old or broken OpenSSL versions */
46 #include "openbsd-compat/openssl-compat.h"
47
48 extern const EVP_CIPHER *evp_ssh1_bf(void);
49 extern const EVP_CIPHER *evp_ssh1_3des(void);
50 extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
51 extern const EVP_CIPHER *evp_aes_128_ctr(void);
52 extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
53
54 struct Cipher {
55         char    *name;
56         int     number;         /* for ssh1 only */
57         u_int   block_size;
58         u_int   key_len;
59         u_int   discard_len;
60         const EVP_CIPHER        *(*evptype)(void);
61 } ciphers[] = {
62         { "none",               SSH_CIPHER_NONE, 8, 0, 0, EVP_enc_null },
63         { "des",                SSH_CIPHER_DES, 8, 8, 0, EVP_des_cbc },
64         { "3des",               SSH_CIPHER_3DES, 8, 16, 0, evp_ssh1_3des },
65         { "blowfish",           SSH_CIPHER_BLOWFISH, 8, 32, 0, evp_ssh1_bf },
66
67         { "3des-cbc",           SSH_CIPHER_SSH2, 8, 24, 0, EVP_des_ede3_cbc },
68         { "blowfish-cbc",       SSH_CIPHER_SSH2, 8, 16, 0, EVP_bf_cbc },
69         { "cast128-cbc",        SSH_CIPHER_SSH2, 8, 16, 0, EVP_cast5_cbc },
70         { "arcfour",            SSH_CIPHER_SSH2, 8, 16, 0, EVP_rc4 },
71         { "arcfour128",         SSH_CIPHER_SSH2, 8, 16, 1536, EVP_rc4 },
72         { "arcfour256",         SSH_CIPHER_SSH2, 8, 32, 1536, EVP_rc4 },
73         { "aes128-cbc",         SSH_CIPHER_SSH2, 16, 16, 0, EVP_aes_128_cbc },
74         { "aes192-cbc",         SSH_CIPHER_SSH2, 16, 24, 0, EVP_aes_192_cbc },
75         { "aes256-cbc",         SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc },
76         { "rijndael-cbc@lysator.liu.se",
77                                 SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc },
78         { "aes128-ctr",         SSH_CIPHER_SSH2, 16, 16, 0, evp_aes_128_ctr },
79         { "aes192-ctr",         SSH_CIPHER_SSH2, 16, 24, 0, evp_aes_128_ctr },
80         { "aes256-ctr",         SSH_CIPHER_SSH2, 16, 32, 0, evp_aes_128_ctr },
81 #ifdef USE_CIPHER_ACSS
82         { "acss@openssh.org",   SSH_CIPHER_SSH2, 16, 5, 0, EVP_acss },
83 #endif
84         { NULL,                 SSH_CIPHER_INVALID, 0, 0, 0, NULL }
85 };
86
87 /*--*/
88
89 u_int
90 cipher_blocksize(const Cipher *c)
91 {
92         return (c->block_size);
93 }
94
95 u_int
96 cipher_keylen(const Cipher *c)
97 {
98         return (c->key_len);
99 }
100
101 u_int
102 cipher_get_number(const Cipher *c)
103 {
104         return (c->number);
105 }
106
107 u_int
108 cipher_mask_ssh1(int client)
109 {
110         u_int mask = 0;
111         mask |= 1 << SSH_CIPHER_3DES;           /* Mandatory */
112         mask |= 1 << SSH_CIPHER_BLOWFISH;
113         if (client) {
114                 mask |= 1 << SSH_CIPHER_DES;
115         }
116         return mask;
117 }
118
119 Cipher *
120 cipher_by_name(const char *name)
121 {
122         Cipher *c;
123         for (c = ciphers; c->name != NULL; c++)
124                 if (strcmp(c->name, name) == 0)
125                         return c;
126         return NULL;
127 }
128
129 Cipher *
130 cipher_by_number(int id)
131 {
132         Cipher *c;
133         for (c = ciphers; c->name != NULL; c++)
134                 if (c->number == id)
135                         return c;
136         return NULL;
137 }
138
139 #define CIPHER_SEP      ","
140 int
141 ciphers_valid(const char *names)
142 {
143         Cipher *c;
144         char *cipher_list, *cp;
145         char *p;
146
147         if (names == NULL || strcmp(names, "") == 0)
148                 return 0;
149         cipher_list = cp = xstrdup(names);
150         for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
151             (p = strsep(&cp, CIPHER_SEP))) {
152                 c = cipher_by_name(p);
153                 if (c == NULL || c->number != SSH_CIPHER_SSH2) {
154                         debug("bad cipher %s [%s]", p, names);
155                         xfree(cipher_list);
156                         return 0;
157                 } else {
158                         debug3("cipher ok: %s [%s]", p, names);
159                 }
160         }
161         debug3("ciphers ok: [%s]", names);
162         xfree(cipher_list);
163         return 1;
164 }
165
166 /*
167  * Parses the name of the cipher.  Returns the number of the corresponding
168  * cipher, or -1 on error.
169  */
170
171 int
172 cipher_number(const char *name)
173 {
174         Cipher *c;
175         if (name == NULL)
176                 return -1;
177         for (c = ciphers; c->name != NULL; c++)
178                 if (strcasecmp(c->name, name) == 0)
179                         return c->number;
180         return -1;
181 }
182
183 char *
184 cipher_name(int id)
185 {
186         Cipher *c = cipher_by_number(id);
187         return (c==NULL) ? "<unknown>" : c->name;
188 }
189
190 void
191 cipher_init(CipherContext *cc, Cipher *cipher,
192     const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
193     int do_encrypt)
194 {
195         static int dowarn = 1;
196 #ifdef SSH_OLD_EVP
197         EVP_CIPHER *type;
198 #else
199         const EVP_CIPHER *type;
200         int klen;
201 #endif
202         u_char *junk, *discard;
203
204         if (cipher->number == SSH_CIPHER_DES) {
205                 if (dowarn) {
206                         error("Warning: use of DES is strongly discouraged "
207                             "due to cryptographic weaknesses");
208                         dowarn = 0;
209                 }
210                 if (keylen > 8)
211                         keylen = 8;
212         }
213         cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
214
215         if (keylen < cipher->key_len)
216                 fatal("cipher_init: key length %d is insufficient for %s.",
217                     keylen, cipher->name);
218         if (iv != NULL && ivlen < cipher->block_size)
219                 fatal("cipher_init: iv length %d is insufficient for %s.",
220                     ivlen, cipher->name);
221         cc->cipher = cipher;
222
223         type = (*cipher->evptype)();
224
225         EVP_CIPHER_CTX_init(&cc->evp);
226 #ifdef SSH_OLD_EVP
227         if (type->key_len > 0 && type->key_len != keylen) {
228                 debug("cipher_init: set keylen (%d -> %d)",
229                     type->key_len, keylen);
230                 type->key_len = keylen;
231         }
232         EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv,
233             (do_encrypt == CIPHER_ENCRYPT));
234 #else
235         if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
236             (do_encrypt == CIPHER_ENCRYPT)) == 0)
237                 fatal("cipher_init: EVP_CipherInit failed for %s",
238                     cipher->name);
239         klen = EVP_CIPHER_CTX_key_length(&cc->evp);
240         if (klen > 0 && keylen != (u_int)klen) {
241                 debug2("cipher_init: set keylen (%d -> %d)", klen, keylen);
242                 if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0)
243                         fatal("cipher_init: set keylen failed (%d -> %d)",
244                             klen, keylen);
245         }
246         if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0)
247                 fatal("cipher_init: EVP_CipherInit: set key failed for %s",
248                     cipher->name);
249 #endif
250
251         if (cipher->discard_len > 0) {
252                 junk = xmalloc(cipher->discard_len);
253                 discard = xmalloc(cipher->discard_len);
254                 if (EVP_Cipher(&cc->evp, discard, junk,
255                     cipher->discard_len) == 0)
256                         fatal("evp_crypt: EVP_Cipher failed during discard");
257                 memset(discard, 0, cipher->discard_len);
258                 xfree(junk);
259                 xfree(discard);
260         }
261 }
262
263 void
264 cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
265 {
266         if (len % cc->cipher->block_size)
267                 fatal("cipher_encrypt: bad plaintext length %d", len);
268         if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0)
269                 fatal("evp_crypt: EVP_Cipher failed");
270 }
271
272 void
273 cipher_cleanup(CipherContext *cc)
274 {
275         if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
276                 error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
277 }
278
279 /*
280  * Selects the cipher, and keys if by computing the MD5 checksum of the
281  * passphrase and using the resulting 16 bytes as the key.
282  */
283
284 void
285 cipher_set_key_string(CipherContext *cc, Cipher *cipher,
286     const char *passphrase, int do_encrypt)
287 {
288         MD5_CTX md;
289         u_char digest[16];
290
291         MD5_Init(&md);
292         MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase));
293         MD5_Final(digest, &md);
294
295         cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt);
296
297         memset(digest, 0, sizeof(digest));
298         memset(&md, 0, sizeof(md));
299 }
300
301 /*
302  * Exports an IV from the CipherContext required to export the key
303  * state back from the unprivileged child to the privileged parent
304  * process.
305  */
306
307 int
308 cipher_get_keyiv_len(const CipherContext *cc)
309 {
310         Cipher *c = cc->cipher;
311         int ivlen;
312
313         if (c->number == SSH_CIPHER_3DES)
314                 ivlen = 24;
315         else
316                 ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp);
317         return (ivlen);
318 }
319
320 void
321 cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
322 {
323         Cipher *c = cc->cipher;
324         int evplen;
325
326         switch (c->number) {
327         case SSH_CIPHER_SSH2:
328         case SSH_CIPHER_DES:
329         case SSH_CIPHER_BLOWFISH:
330                 evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
331                 if (evplen <= 0)
332                         return;
333                 if ((u_int)evplen != len)
334                         fatal("%s: wrong iv length %d != %d", __func__,
335                             evplen, len);
336 #ifdef USE_BUILTIN_RIJNDAEL
337                 if (c->evptype == evp_rijndael)
338                         ssh_rijndael_iv(&cc->evp, 0, iv, len);
339                 else
340 #endif
341                 if (c->evptype == evp_aes_128_ctr)
342                         ssh_aes_ctr_iv(&cc->evp, 0, iv, len);
343                 else
344                         memcpy(iv, cc->evp.iv, len);
345                 break;
346         case SSH_CIPHER_3DES:
347                 ssh1_3des_iv(&cc->evp, 0, iv, 24);
348                 break;
349         default:
350                 fatal("%s: bad cipher %d", __func__, c->number);
351         }
352 }
353
354 void
355 cipher_set_keyiv(CipherContext *cc, u_char *iv)
356 {
357         Cipher *c = cc->cipher;
358         int evplen = 0;
359
360         switch (c->number) {
361         case SSH_CIPHER_SSH2:
362         case SSH_CIPHER_DES:
363         case SSH_CIPHER_BLOWFISH:
364                 evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
365                 if (evplen == 0)
366                         return;
367 #ifdef USE_BUILTIN_RIJNDAEL
368                 if (c->evptype == evp_rijndael)
369                         ssh_rijndael_iv(&cc->evp, 1, iv, evplen);
370                 else
371 #endif
372                 if (c->evptype == evp_aes_128_ctr)
373                         ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen);
374                 else
375                         memcpy(cc->evp.iv, iv, evplen);
376                 break;
377         case SSH_CIPHER_3DES:
378                 ssh1_3des_iv(&cc->evp, 1, iv, 24);
379                 break;
380         default:
381                 fatal("%s: bad cipher %d", __func__, c->number);
382         }
383 }
384
385 #if OPENSSL_VERSION_NUMBER < 0x00907000L
386 #define EVP_X_STATE(evp)        &(evp).c
387 #define EVP_X_STATE_LEN(evp)    sizeof((evp).c)
388 #else
389 #define EVP_X_STATE(evp)        (evp).cipher_data
390 #define EVP_X_STATE_LEN(evp)    (evp).cipher->ctx_size
391 #endif
392
393 int
394 cipher_get_keycontext(const CipherContext *cc, u_char *dat)
395 {
396         Cipher *c = cc->cipher;
397         int plen = 0;
398
399         if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) {
400                 plen = EVP_X_STATE_LEN(cc->evp);
401                 if (dat == NULL)
402                         return (plen);
403                 memcpy(dat, EVP_X_STATE(cc->evp), plen);
404         }
405         return (plen);
406 }
407
408 void
409 cipher_set_keycontext(CipherContext *cc, u_char *dat)
410 {
411         Cipher *c = cc->cipher;
412         int plen;
413
414         if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) {
415                 plen = EVP_X_STATE_LEN(cc->evp);
416                 memcpy(EVP_X_STATE(cc->evp), dat, plen);
417         }
418 }
This page took 0.811088 seconds and 5 git commands to generate.