Annotation of src/usr.bin/ssh/cipher.c, Revision 1.6
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.6 ! deraadt 15: RCSID("$Id: cipher.c,v 1.5 1999/09/30 05:19:57 deraadt 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: "no des",
128: "3des",
129: "no tss",
130: "no rc4",
131: "blowfish"
132: };
133:
134: /* Returns a bit mask indicating which ciphers are supported by this
135: implementation. The bit mask has the corresponding bit set of each
136: supported cipher. */
137:
138: unsigned int cipher_mask()
139: {
140: unsigned int mask = 0;
141: mask |= 1 << SSH_CIPHER_NONE;
142: mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */
143: mask |= 1 << SSH_CIPHER_BLOWFISH;
144: return mask;
145: }
146:
147: /* Returns the name of the cipher. */
148:
1.4 provos 149: const
150: char *cipher_name(int cipher)
1.1 deraadt 151: {
152: if (cipher < 0 || cipher >= sizeof(cipher_names) / sizeof(cipher_names[0]))
153: fatal("cipher_name: bad cipher number: %d", cipher);
154: return cipher_names[cipher];
155: }
156:
157: /* Parses the name of the cipher. Returns the number of the corresponding
158: cipher, or -1 on error. */
159:
1.4 provos 160: int
161: cipher_number(const char *name)
1.1 deraadt 162: {
163: int i;
164: for (i = 0; i < sizeof(cipher_names) / sizeof(cipher_names[0]); i++)
165: if (strcmp(cipher_names[i], name) == 0)
166: return i;
167: return -1;
168: }
169:
170: /* Selects the cipher, and keys if by computing the MD5 checksum of the
171: passphrase and using the resulting 16 bytes as the key. */
172:
173: void cipher_set_key_string(CipherContext *context, int cipher,
174: const char *passphrase, int for_encryption)
175: {
176: struct MD5Context md;
177: unsigned char digest[16];
178:
179: MD5Init(&md);
180: MD5Update(&md, (const unsigned char *)passphrase, strlen(passphrase));
181: MD5Final(digest, &md);
182:
183: cipher_set_key(context, cipher, digest, 16, for_encryption);
184:
185: memset(digest, 0, sizeof(digest));
186: memset(&md, 0, sizeof(md));
187: }
188:
189: /* Selects the cipher to use and sets the key. */
190:
191: void cipher_set_key(CipherContext *context, int cipher,
192: const unsigned char *key, int keylen, int for_encryption)
193: {
194: unsigned char padded[32];
195:
196: /* Set cipher type. */
197: context->type = cipher;
198:
199: /* Get 32 bytes of key data. Pad if necessary. (So that code below does
200: not need to worry about key size). */
201: memset(padded, 0, sizeof(padded));
202: memcpy(padded, key, keylen < sizeof(padded) ? keylen : sizeof(padded));
203:
204: /* Initialize the initialization vector. */
205: switch (cipher)
206: {
207: case SSH_CIPHER_NONE:
208: break;
209:
210: case SSH_CIPHER_3DES:
211: /* Note: the least significant bit of each byte of key is parity,
212: and must be ignored by the implementation. 16 bytes of key are
213: used (first and last keys are the same). */
214: if (keylen < 16)
215: error("Key length %d is insufficient for 3DES.", keylen);
216: des_set_key((void*)padded, context->u.des3.key1);
217: des_set_key((void*)(padded + 8), context->u.des3.key2);
218: if (keylen <= 16)
219: des_set_key((void*)padded, context->u.des3.key3);
220: else
221: des_set_key((void*)(padded + 16), context->u.des3.key3);
222: memset(context->u.des3.iv2, 0, sizeof(context->u.des3.iv2));
223: memset(context->u.des3.iv3, 0, sizeof(context->u.des3.iv3));
224: break;
225:
226: case SSH_CIPHER_BLOWFISH:
227: BF_set_key(&context->u.bf.key, keylen, padded);
228: memset(context->u.bf.iv, 0, 8);
229: break;
230:
231: default:
232: fatal("cipher_set_key: unknown cipher: %d", cipher);
233: }
234: memset(padded, 0, sizeof(padded));
235: }
236:
237: /* Encrypts data using the cipher. */
238:
239: void cipher_encrypt(CipherContext *context, unsigned char *dest,
240: const unsigned char *src, unsigned int len)
241: {
242: assert((len & 7) == 0);
243:
244: switch (context->type)
245: {
246: case SSH_CIPHER_NONE:
247: memcpy(dest, src, len);
248: break;
249:
250: case SSH_CIPHER_3DES:
251: SSH_3CBC_ENCRYPT(context->u.des3.key1,
252: context->u.des3.key2, &context->u.des3.iv2,
253: context->u.des3.key3, &context->u.des3.iv3,
254: dest, (void*)src, len);
255: break;
256:
257: case SSH_CIPHER_BLOWFISH:
258: swap_bytes(src, dest, len);
259: BF_cbc_encrypt(dest, dest, len,
260: &context->u.bf.key, context->u.bf.iv, BF_ENCRYPT);
261: swap_bytes(dest, dest, len);
262: break;
263:
264: default:
265: fatal("cipher_encrypt: unknown cipher: %d", context->type);
266: }
267: }
268:
269: /* Decrypts data using the cipher. */
270:
271: void cipher_decrypt(CipherContext *context, unsigned char *dest,
272: const unsigned char *src, unsigned int len)
273: {
274: assert((len & 7) == 0);
275:
276: switch (context->type)
277: {
278: case SSH_CIPHER_NONE:
279: memcpy(dest, src, len);
280: break;
281:
282: case SSH_CIPHER_3DES:
283: /* CRC-32 attack? */
284: SSH_3CBC_DECRYPT(context->u.des3.key1,
285: context->u.des3.key2, &context->u.des3.iv2,
286: context->u.des3.key3, &context->u.des3.iv3,
287: dest, (void*)src, len);
288: break;
289:
290: case SSH_CIPHER_BLOWFISH:
291: detect_cbc_attack(src, len);
292: swap_bytes(src, dest, len);
293: BF_cbc_encrypt((void*)dest, dest, len,
294: &context->u.bf.key, context->u.bf.iv, BF_DECRYPT);
295: swap_bytes(dest, dest, len);
296: break;
297:
298: default:
299: fatal("cipher_decrypt: unknown cipher: %d", context->type);
300: }
301: }