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