]> andersk Git - openssh.git/blob - cipher.c
- Merged OpenBSD CVS changes:
[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); */   /* Note how iv1 == iv2 on entry and exit. */
79 }
80
81 /*
82  * SSH uses a variation on Blowfish, all bytes must be swapped before
83  * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
84  */
85 static
86 void
87 swap_bytes(const unsigned char *src, unsigned char *dst_, int n)
88 {
89   u_int32_t *dst = (u_int32_t *)dst_;   /* dst must be properly aligned. */
90   union {
91     u_int32_t i;
92     char c[4];
93   } t;
94
95   /* Process 8 bytes every lap. */
96   for (n = n / 8; n > 0; n--)
97     {
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
115 void
116 detect_cbc_attack(const unsigned char *src,
117                   unsigned int len)
118 {
119   return;
120   
121   log("CRC-32 CBC insertion attack detected");
122   cipher_attack_detected("CRC-32 CBC insertion attack detected");
123 }
124
125 /* Names of all encryption algorithms.  These must match the numbers defined
126    int cipher.h. */
127 static char *cipher_names[] =
128 {
129   "none",
130   "idea",
131   "des",
132   "3des",
133   "tss",
134   "rc4",
135   "blowfish"
136 };
137
138 /* Returns a bit mask indicating which ciphers are supported by this
139    implementation.  The bit mask has the corresponding bit set of each
140    supported cipher. */
141
142 unsigned int 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
153 char *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 cipher_set_key_string(CipherContext *context, int cipher,
179                            const char *passphrase, int for_encryption)
180 {
181   MD5_CTX md;
182   unsigned char digest[16];
183   
184   MD5_Init(&md);
185   MD5_Update(&md, (const unsigned char *)passphrase, strlen(passphrase));
186   MD5_Final(digest, &md);
187
188   cipher_set_key(context, cipher, digest, 16, for_encryption);
189   
190   memset(digest, 0, sizeof(digest));
191   memset(&md, 0, sizeof(md));
192 }
193
194 /* Selects the cipher to use and sets the key. */
195
196 void cipher_set_key(CipherContext *context, int cipher,
197                     const unsigned char *key, int keylen, int for_encryption)
198 {
199   unsigned char padded[32];
200
201   /* Set cipher type. */
202   context->type = cipher;
203
204   /* Get 32 bytes of key data.  Pad if necessary.  (So that code below does
205      not need to worry about key size). */
206   memset(padded, 0, sizeof(padded));
207   memcpy(padded, key, keylen < sizeof(padded) ? keylen : sizeof(padded));
208
209   /* Initialize the initialization vector. */
210   switch (cipher)
211     {
212     case SSH_CIPHER_NONE:
213       /* Has to stay for authfile saving of private key with no passphrase */
214       break;
215
216     case SSH_CIPHER_3DES:
217       /* Note: the least significant bit of each byte of key is parity, 
218          and must be ignored by the implementation.  16 bytes of key are
219          used (first and last keys are the same). */
220       if (keylen < 16)
221         error("Key length %d is insufficient for 3DES.", keylen);
222       des_set_key((void*)padded, context->u.des3.key1);
223       des_set_key((void*)(padded + 8), context->u.des3.key2);
224       if (keylen <= 16)
225         des_set_key((void*)padded, context->u.des3.key3);
226       else
227         des_set_key((void*)(padded + 16), context->u.des3.key3);
228       memset(context->u.des3.iv2, 0, sizeof(context->u.des3.iv2));
229       memset(context->u.des3.iv3, 0, sizeof(context->u.des3.iv3));
230       break;
231
232     case SSH_CIPHER_BLOWFISH:
233       BF_set_key(&context->u.bf.key, keylen, padded);
234       memset(context->u.bf.iv, 0, 8);
235       break;
236
237     default:
238       fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher));
239     }
240   memset(padded, 0, sizeof(padded));
241 }
242
243 /* Encrypts data using the cipher. */
244
245 void cipher_encrypt(CipherContext *context, unsigned char *dest,
246                     const unsigned char *src, unsigned int len)
247 {
248   if ((len & 7) != 0)
249     fatal("cipher_encrypt: bad plaintext length %d", len);
250
251   switch (context->type)
252     {
253     case SSH_CIPHER_NONE:
254       memcpy(dest, src, len);
255       break;
256
257     case SSH_CIPHER_3DES:
258       SSH_3CBC_ENCRYPT(context->u.des3.key1,
259                        context->u.des3.key2, &context->u.des3.iv2,
260                        context->u.des3.key3, &context->u.des3.iv3,
261                        dest, (void*)src, len);
262       break;
263
264     case SSH_CIPHER_BLOWFISH:
265       swap_bytes(src, dest, len);
266       BF_cbc_encrypt(dest, dest, len,
267                      &context->u.bf.key, context->u.bf.iv, BF_ENCRYPT);
268       swap_bytes(dest, dest, len);
269       break;
270
271     default:
272       fatal("cipher_encrypt: unknown cipher: %d", context->type);
273     }
274 }
275   
276 /* Decrypts data using the cipher. */
277
278 void cipher_decrypt(CipherContext *context, unsigned char *dest,
279                     const unsigned char *src, unsigned int len)
280 {
281   if ((len & 7) != 0)
282     fatal("cipher_decrypt: bad ciphertext length %d", len);
283
284   switch (context->type)
285     {
286     case SSH_CIPHER_NONE:
287       memcpy(dest, src, len);
288       break;
289
290     case SSH_CIPHER_3DES:
291       /* CRC-32 attack? */
292       SSH_3CBC_DECRYPT(context->u.des3.key1,
293                        context->u.des3.key2, &context->u.des3.iv2,
294                        context->u.des3.key3, &context->u.des3.iv3,
295                        dest, (void*)src, len);
296       break;
297
298     case SSH_CIPHER_BLOWFISH:
299       detect_cbc_attack(src, len);
300       swap_bytes(src, dest, len);
301       BF_cbc_encrypt((void*)dest, dest, len,
302                      &context->u.bf.key, context->u.bf.iv, BF_DECRYPT);
303       swap_bytes(dest, dest, len);
304       break;
305
306     default:
307       fatal("cipher_decrypt: unknown cipher: %d", context->type);
308     }
309 }
This page took 0.058905 seconds and 5 git commands to generate.