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