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