Annotation of src/usr.bin/ssh/cipher.c, Revision 1.3
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.3 ! deraadt 15: RCSID("$Id: cipher.c,v 1.2 1999/09/26 21:02:15 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: /*
75: * SSH uses a variation on Blowfish, all bytes must be swapped before
76: * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
77: */
78: static
79: void
80: swap_bytes(const unsigned char *src, unsigned char *dst_, int n)
81: {
82: uint32 *dst = (uint32 *)dst_; /* dst must be properly aligned. */
83: union {
84: uint32 i;
85: char c[4];
86: } t;
87:
88: /* assert((n & 7) == 0); */
89:
90: /* Process 8 bytes every lap. */
91: for (n = n / 8; n > 0; n--)
92: {
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:
107: void (*cipher_attack_detected)(const char *fmt, ...) = fatal;
108:
109: static inline
110: void
111: detect_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: /* Names of all encryption algorithms. These must match the numbers defined
121: int cipher.h. */
122: static char *cipher_names[] =
123: { "none",
124: "no idea",
125: #ifdef WITH_DES
126: "des",
127: #else
128: "no des",
129: #endif
130: "3des",
131: "no tss",
132: #ifdef WITH_RC4
133: "rc4",
134: #else
135: "no rc4",
136: #endif
137: "blowfish"
138: };
139:
140: /* Returns a bit mask indicating which ciphers are supported by this
141: implementation. The bit mask has the corresponding bit set of each
142: supported cipher. */
143:
144: unsigned int cipher_mask()
145: {
146: unsigned int mask = 0;
147: mask |= 1 << SSH_CIPHER_NONE;
148: #ifdef WITH_DES
149: mask |= 1 << SSH_CIPHER_DES;
150: #endif
151: mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */
152: #ifdef WITH_RC4
153: mask |= 1 << SSH_CIPHER_RC4;
154: #endif
155: mask |= 1 << SSH_CIPHER_BLOWFISH;
156: return mask;
157: }
158:
159: /* Returns the name of the cipher. */
160:
161: const char *cipher_name(int cipher)
162: {
163: if (cipher < 0 || cipher >= sizeof(cipher_names) / sizeof(cipher_names[0]))
164: fatal("cipher_name: bad cipher number: %d", cipher);
165: return cipher_names[cipher];
166: }
167:
168: /* Parses the name of the cipher. Returns the number of the corresponding
169: cipher, or -1 on error. */
170:
171: int cipher_number(const char *name)
172: {
173: int i;
174: for (i = 0; i < sizeof(cipher_names) / sizeof(cipher_names[0]); i++)
175: if (strcmp(cipher_names[i], name) == 0)
176: return i;
177: return -1;
178: }
179:
180: /* Selects the cipher, and keys if by computing the MD5 checksum of the
181: passphrase and using the resulting 16 bytes as the key. */
182:
183: void cipher_set_key_string(CipherContext *context, int cipher,
184: const char *passphrase, int for_encryption)
185: {
186: struct MD5Context md;
187: unsigned char digest[16];
188:
189: MD5Init(&md);
190: MD5Update(&md, (const unsigned char *)passphrase, strlen(passphrase));
191: MD5Final(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:
201: void cipher_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 below does
210: 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: {
217: case SSH_CIPHER_NONE:
218: break;
219:
220: #ifdef WITH_DES
221: case SSH_CIPHER_DES:
222: /* Note: the least significant bit of each byte of key is parity,
223: and must be ignored by the implementation. 8 bytes of key are
224: used. */
225: if (keylen < 8)
226: error("Key length %d is insufficient for DES.", keylen);
227: des_set_key((void*)padded, context->u.des.key);
228: memset(context->u.des.iv, 0, sizeof(context->u.des.iv));
229: break;
230: #endif /* WITH_DES */
231:
232: case SSH_CIPHER_3DES:
233: /* Note: the least significant bit of each byte of key is parity,
234: and must be ignored by the implementation. 16 bytes of key are
235: used (first and last keys are the same). */
236: if (keylen < 16)
237: error("Key length %d is insufficient for 3DES.", keylen);
238: des_set_key((void*)padded, context->u.des3.key1);
239: des_set_key((void*)(padded + 8), context->u.des3.key2);
240: if (keylen <= 16)
241: des_set_key((void*)padded, context->u.des3.key3);
242: else
243: des_set_key((void*)(padded + 16), context->u.des3.key3);
244: memset(context->u.des3.iv2, 0, sizeof(context->u.des3.iv2));
245: memset(context->u.des3.iv3, 0, sizeof(context->u.des3.iv3));
246: break;
247:
248: #ifdef WITH_RC4
249: case SSH_CIPHER_RC4:
250: rc4_init(&context->u.rc4, key, keylen);
251: break;
252: #endif /* WITH_RC4 */
253:
254: case SSH_CIPHER_BLOWFISH:
255: BF_set_key(&context->u.bf.key, keylen, padded);
256: memset(context->u.bf.iv, 0, 8);
257: break;
258:
259: default:
260: fatal("cipher_set_key: unknown cipher: %d", cipher);
261: }
262: memset(padded, 0, sizeof(padded));
263: }
264:
265: /* Encrypts data using the cipher. */
266:
267: void cipher_encrypt(CipherContext *context, unsigned char *dest,
268: const unsigned char *src, unsigned int len)
269: {
270: assert((len & 7) == 0);
271:
272: switch (context->type)
273: {
274: case SSH_CIPHER_NONE:
275: memcpy(dest, src, len);
276: break;
277:
278: #ifdef WITH_DES
279: case SSH_CIPHER_DES:
280: des_cbc_encrypt((void*)src, (void*)dest, len,
281: context->u.des.key, &context->u.des.iv, DES_ENCRYPT);
282: memcpy(context->u.des.iv, dest + len - 8, 8);
283: break;
284: #endif /* WITH_DES */
285:
286: case SSH_CIPHER_3DES:
287: SSH_3CBC_ENCRYPT(context->u.des3.key1,
288: context->u.des3.key2, &context->u.des3.iv2,
289: context->u.des3.key3, &context->u.des3.iv3,
290: dest, (void*)src, len);
291: break;
292:
293: #ifdef WITH_RC4
294: case SSH_CIPHER_RC4:
295: rc4_encrypt(&context->u.rc4, dest, src, len);
296: break;
297: #endif /* WITH_RC4 */
298:
299: case SSH_CIPHER_BLOWFISH:
300: swap_bytes(src, dest, len);
301: BF_cbc_encrypt(dest, dest, len,
302: &context->u.bf.key, context->u.bf.iv, BF_ENCRYPT);
303: swap_bytes(dest, dest, len);
304: break;
305:
306: default:
307: fatal("cipher_encrypt: unknown cipher: %d", context->type);
308: }
309: }
310:
311: /* Decrypts data using the cipher. */
312:
313: void cipher_decrypt(CipherContext *context, unsigned char *dest,
314: const unsigned char *src, unsigned int len)
315: {
316: assert((len & 7) == 0);
317:
318: switch (context->type)
319: {
320: case SSH_CIPHER_NONE:
321: memcpy(dest, src, len);
322: break;
323:
324: #ifdef WITH_DES
325: case SSH_CIPHER_DES:
326: detect_cbc_attack(src, len);
327: des_cbc_encrypt((void*)src, (void*)dest, len,
328: context->u.des.key, &context->u.des.iv, DES_DECRYPT);
329: memcpy(context->u.des.iv, src + len - 8, 8);
330: break;
331: #endif /* WITH_DES */
332:
333: case SSH_CIPHER_3DES:
334: /* CRC-32 attack? */
335: SSH_3CBC_DECRYPT(context->u.des3.key1,
336: context->u.des3.key2, &context->u.des3.iv2,
337: context->u.des3.key3, &context->u.des3.iv3,
338: dest, (void*)src, len);
339: break;
340:
341: #ifdef WITH_RC4
342: case SSH_CIPHER_RC4:
343: /* CRC-32 attack? */
344: rc4_decrypt(&context->u.rc4, dest, src, len);
345: break;
346: #endif /* WITH_RC4 */
347:
348: case SSH_CIPHER_BLOWFISH:
349: detect_cbc_attack(src, len);
350: swap_bytes(src, dest, len);
351: BF_cbc_encrypt((void*)dest, dest, len,
352: &context->u.bf.key, context->u.bf.iv, BF_DECRYPT);
353: swap_bytes(dest, dest, len);
354: break;
355:
356: default:
357: fatal("cipher_decrypt: unknown cipher: %d", context->type);
358: }
359: }