]> andersk Git - openssh.git/blob - cipher.c
- Merged very large OpenBSD source code reformat
[openssh.git] / cipher.c
1 /*
2  * 
3  * cipher.c
4  * 
5  * Author: Tatu Ylonen <ylo@cs.hut.fi>
6  * 
7  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8  *                    All rights reserved
9  * 
10  * Created: Wed Apr 19 17:41:39 1995 ylo
11  * 
12  */
13
14 #include "includes.h"
15 RCSID("$Id$");
16
17 #include "ssh.h"
18 #include "cipher.h"
19
20 #ifdef HAVE_OPENSSL
21 #include <openssl/md5.h>
22 #endif
23 #ifdef HAVE_SSL
24 #include <ssl/md5.h>
25 #endif
26
27 /*
28  * What kind of tripple DES are these 2 routines?
29  *
30  * Why is there a redundant initialization vector?
31  *
32  * If only iv3 was used, then, this would till effect have been
33  * outer-cbc. However, there is also a private iv1 == iv2 which
34  * perhaps makes differential analysis easier. On the other hand, the
35  * private iv1 probably makes the CRC-32 attack ineffective. This is a
36  * result of that there is no longer any known iv1 to use when
37  * choosing the X block.
38  */
39 void
40 SSH_3CBC_ENCRYPT(des_key_schedule ks1,
41                  des_key_schedule ks2, des_cblock * iv2,
42                  des_key_schedule ks3, des_cblock * iv3,
43                  void *dest, void *src,
44                  unsigned int len)
45 {
46         des_cblock iv1;
47
48         memcpy(&iv1, iv2, 8);
49
50         des_cbc_encrypt(src, dest, len, ks1, &iv1, DES_ENCRYPT);
51         memcpy(&iv1, dest + len - 8, 8);
52
53         des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_DECRYPT);
54         memcpy(iv2, &iv1, 8);   /* Note how iv1 == iv2 on entry and exit. */
55
56         des_cbc_encrypt(dest, dest, len, ks3, iv3, DES_ENCRYPT);
57         memcpy(iv3, dest + len - 8, 8);
58 }
59
60 void
61 SSH_3CBC_DECRYPT(des_key_schedule ks1,
62                  des_key_schedule ks2, des_cblock * iv2,
63                  des_key_schedule ks3, des_cblock * iv3,
64                  void *dest, void *src,
65                  unsigned int len)
66 {
67         des_cblock iv1;
68
69         memcpy(&iv1, iv2, 8);
70
71         des_cbc_encrypt(src, dest, len, ks3, iv3, DES_DECRYPT);
72         memcpy(iv3, src + len - 8, 8);
73
74         des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_ENCRYPT);
75         memcpy(iv2, dest + len - 8, 8);
76
77         des_cbc_encrypt(dest, dest, len, ks1, &iv1, DES_DECRYPT);
78         /* memcpy(&iv1, iv2, 8); */
79         /* Note how iv1 == iv2 on entry and exit. */
80 }
81
82 /*
83  * SSH uses a variation on Blowfish, all bytes must be swapped before
84  * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
85  */
86 static void
87 swap_bytes(const unsigned char *src, unsigned char *dst_, int n)
88 {
89         /* dst must be properly aligned. */
90         u_int32_t *dst = (u_int32_t *) dst_;
91         union {
92                 u_int32_t i;
93                 char c[4];
94         } t;
95
96         /* Process 8 bytes every lap. */
97         for (n = n / 8; n > 0; n--) {
98                 t.c[3] = *src++;
99                 t.c[2] = *src++;
100                 t.c[1] = *src++;
101                 t.c[0] = *src++;
102                 *dst++ = t.i;
103
104                 t.c[3] = *src++;
105                 t.c[2] = *src++;
106                 t.c[1] = *src++;
107                 t.c[0] = *src++;
108                 *dst++ = t.i;
109         }
110 }
111
112 void (*cipher_attack_detected) (const char *fmt,...) = fatal;
113
114 static inline void
115 detect_cbc_attack(const unsigned char *src,
116                   unsigned int len)
117 {
118         return;
119
120         log("CRC-32 CBC insertion attack detected");
121         cipher_attack_detected("CRC-32 CBC insertion attack detected");
122 }
123
124 /* Names of all encryption algorithms.  These must match the numbers defined
125    int cipher.h. */
126 static char *cipher_names[] =
127 {
128         "none",
129         "idea",
130         "des",
131         "3des",
132         "tss",
133         "rc4",
134         "blowfish"
135 };
136
137 /* Returns a bit mask indicating which ciphers are supported by this
138    implementation.  The bit mask has the corresponding bit set of each
139    supported cipher. */
140
141 unsigned int 
142 cipher_mask()
143 {
144         unsigned int mask = 0;
145         mask |= 1 << SSH_CIPHER_3DES;           /* Mandatory */
146         mask |= 1 << SSH_CIPHER_BLOWFISH;
147         return mask;
148 }
149
150 /* Returns the name of the cipher. */
151
152 const char *
153 cipher_name(int cipher)
154 {
155         if (cipher < 0 || cipher >= sizeof(cipher_names) / sizeof(cipher_names[0]) ||
156             cipher_names[cipher] == NULL)
157                 fatal("cipher_name: bad cipher number: %d", cipher);
158         return cipher_names[cipher];
159 }
160
161 /* Parses the name of the cipher.  Returns the number of the corresponding
162    cipher, or -1 on error. */
163
164 int
165 cipher_number(const char *name)
166 {
167         int i;
168         for (i = 0; i < sizeof(cipher_names) / sizeof(cipher_names[0]); i++)
169                 if (strcmp(cipher_names[i], name) == 0 &&
170                     (cipher_mask() & (1 << i)))
171                         return i;
172         return -1;
173 }
174
175 /* Selects the cipher, and keys if by computing the MD5 checksum of the
176    passphrase and using the resulting 16 bytes as the key. */
177
178 void 
179 cipher_set_key_string(CipherContext *context, int cipher,
180                       const char *passphrase, int for_encryption)
181 {
182         MD5_CTX md;
183         unsigned char digest[16];
184
185         MD5_Init(&md);
186         MD5_Update(&md, (const unsigned char *) passphrase, strlen(passphrase));
187         MD5_Final(digest, &md);
188
189         cipher_set_key(context, cipher, digest, 16, for_encryption);
190
191         memset(digest, 0, sizeof(digest));
192         memset(&md, 0, sizeof(md));
193 }
194
195 /* Selects the cipher to use and sets the key. */
196
197 void 
198 cipher_set_key(CipherContext *context, int cipher,
199                const unsigned char *key, int keylen, int for_encryption)
200 {
201         unsigned char padded[32];
202
203         /* Set cipher type. */
204         context->type = cipher;
205
206         /* Get 32 bytes of key data.  Pad if necessary.  (So that code
207            below does not need to worry about key size). */
208         memset(padded, 0, sizeof(padded));
209         memcpy(padded, key, keylen < sizeof(padded) ? keylen : sizeof(padded));
210
211         /* Initialize the initialization vector. */
212         switch (cipher) {
213         case SSH_CIPHER_NONE:
214                 /* Has to stay for authfile saving of private key with
215                    no passphrase */
216                 break;
217
218         case SSH_CIPHER_3DES:
219                 /* Note: the least significant bit of each byte of key is
220                    parity, and must be ignored by the implementation.  16
221                    bytes of key are used (first and last keys are the
222                    same). */
223                 if (keylen < 16)
224                         error("Key length %d is insufficient for 3DES.", keylen);
225                 des_set_key((void *) padded, context->u.des3.key1);
226                 des_set_key((void *) (padded + 8), context->u.des3.key2);
227                 if (keylen <= 16)
228                         des_set_key((void *) padded, context->u.des3.key3);
229                 else
230                         des_set_key((void *) (padded + 16), context->u.des3.key3);
231                 memset(context->u.des3.iv2, 0, sizeof(context->u.des3.iv2));
232                 memset(context->u.des3.iv3, 0, sizeof(context->u.des3.iv3));
233                 break;
234
235         case SSH_CIPHER_BLOWFISH:
236                 BF_set_key(&context->u.bf.key, keylen, padded);
237                 memset(context->u.bf.iv, 0, 8);
238                 break;
239
240         default:
241                 fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher));
242         }
243         memset(padded, 0, sizeof(padded));
244 }
245
246 /* Encrypts data using the cipher. */
247
248 void 
249 cipher_encrypt(CipherContext *context, unsigned char *dest,
250                const unsigned char *src, unsigned int len)
251 {
252         if ((len & 7) != 0)
253                 fatal("cipher_encrypt: bad plaintext length %d", len);
254
255         switch (context->type) {
256         case SSH_CIPHER_NONE:
257                 memcpy(dest, src, len);
258                 break;
259
260         case SSH_CIPHER_3DES:
261                 SSH_3CBC_ENCRYPT(context->u.des3.key1,
262                                  context->u.des3.key2, &context->u.des3.iv2,
263                                  context->u.des3.key3, &context->u.des3.iv3,
264                                  dest, (void *) src, len);
265                 break;
266
267         case SSH_CIPHER_BLOWFISH:
268                 swap_bytes(src, dest, len);
269                 BF_cbc_encrypt(dest, dest, len,
270                                &context->u.bf.key, context->u.bf.iv,
271                                BF_ENCRYPT);
272                 swap_bytes(dest, dest, len);
273                 break;
274
275         default:
276                 fatal("cipher_encrypt: unknown cipher: %s", cipher_name(context->type));
277         }
278 }
279
280 /* Decrypts data using the cipher. */
281
282 void 
283 cipher_decrypt(CipherContext *context, unsigned char *dest,
284                const unsigned char *src, unsigned int len)
285 {
286         if ((len & 7) != 0)
287                 fatal("cipher_decrypt: bad ciphertext length %d", len);
288
289         switch (context->type) {
290         case SSH_CIPHER_NONE:
291                 memcpy(dest, src, len);
292                 break;
293
294         case SSH_CIPHER_3DES:
295                 /* CRC-32 attack? */
296                 SSH_3CBC_DECRYPT(context->u.des3.key1,
297                                  context->u.des3.key2, &context->u.des3.iv2,
298                                  context->u.des3.key3, &context->u.des3.iv3,
299                                  dest, (void *) src, len);
300                 break;
301
302         case SSH_CIPHER_BLOWFISH:
303                 detect_cbc_attack(src, len);
304                 swap_bytes(src, dest, len);
305                 BF_cbc_encrypt((void *) dest, dest, len,
306                                &context->u.bf.key, context->u.bf.iv,
307                                BF_DECRYPT);
308                 swap_bytes(dest, dest, len);
309                 break;
310
311         default:
312                 fatal("cipher_decrypt: unknown cipher: %s", cipher_name(context->type));
313         }
314 }
This page took 0.083835 seconds and 5 git commands to generate.