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