diff options
Diffstat (limited to 'cipher.c')
-rw-r--r-- | cipher.c | 123 |
1 files changed, 121 insertions, 2 deletions
@@ -12,7 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "includes.h" | 14 | #include "includes.h" |
15 | RCSID("$Id: cipher.c,v 1.14 2000/03/26 03:04:52 damien Exp $"); | 15 | RCSID("$Id: cipher.c,v 1.15 2000/04/01 01:09:23 damien Exp $"); |
16 | 16 | ||
17 | #include "ssh.h" | 17 | #include "ssh.h" |
18 | #include "cipher.h" | 18 | #include "cipher.h" |
@@ -122,7 +122,12 @@ static char *cipher_names[] = | |||
122 | "3des", | 122 | "3des", |
123 | "tss", | 123 | "tss", |
124 | "rc4", | 124 | "rc4", |
125 | "blowfish" | 125 | "blowfish", |
126 | "reserved", | ||
127 | "blowfish-cbc", | ||
128 | "3des-cbc", | ||
129 | "arcfour", | ||
130 | "cast128-cbc" | ||
126 | }; | 131 | }; |
127 | 132 | ||
128 | /* | 133 | /* |
@@ -137,6 +142,10 @@ cipher_mask() | |||
137 | unsigned int mask = 0; | 142 | unsigned int mask = 0; |
138 | mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ | 143 | mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ |
139 | mask |= 1 << SSH_CIPHER_BLOWFISH; | 144 | mask |= 1 << SSH_CIPHER_BLOWFISH; |
145 | mask |= 1 << SSH_CIPHER_BLOWFISH_CBC; | ||
146 | mask |= 1 << SSH_CIPHER_3DES_CBC; | ||
147 | mask |= 1 << SSH_CIPHER_ARCFOUR; | ||
148 | mask |= 1 << SSH_CIPHER_CAST128_CBC; | ||
140 | return mask; | 149 | return mask; |
141 | } | 150 | } |
142 | 151 | ||
@@ -233,16 +242,84 @@ cipher_set_key(CipherContext *context, int cipher, | |||
233 | break; | 242 | break; |
234 | 243 | ||
235 | case SSH_CIPHER_BLOWFISH: | 244 | case SSH_CIPHER_BLOWFISH: |
245 | if (keylen < 16) | ||
246 | error("Key length %d is insufficient for blowfish.", keylen); | ||
236 | BF_set_key(&context->u.bf.key, keylen, padded); | 247 | BF_set_key(&context->u.bf.key, keylen, padded); |
237 | memset(context->u.bf.iv, 0, 8); | 248 | memset(context->u.bf.iv, 0, 8); |
238 | break; | 249 | break; |
239 | 250 | ||
251 | case SSH_CIPHER_3DES_CBC: | ||
252 | case SSH_CIPHER_BLOWFISH_CBC: | ||
253 | case SSH_CIPHER_ARCFOUR: | ||
254 | case SSH_CIPHER_CAST128_CBC: | ||
255 | fatal("cipher_set_key: illegal cipher: %s", cipher_name(cipher)); | ||
256 | break; | ||
257 | |||
240 | default: | 258 | default: |
241 | fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher)); | 259 | fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher)); |
242 | } | 260 | } |
243 | memset(padded, 0, sizeof(padded)); | 261 | memset(padded, 0, sizeof(padded)); |
244 | } | 262 | } |
245 | 263 | ||
264 | |||
265 | void | ||
266 | cipher_set_key_iv(CipherContext * context, int cipher, | ||
267 | const unsigned char *key, int keylen, | ||
268 | const unsigned char *iv, int ivlen) | ||
269 | { | ||
270 | /* Set cipher type. */ | ||
271 | context->type = cipher; | ||
272 | |||
273 | /* Initialize the initialization vector. */ | ||
274 | switch (cipher) { | ||
275 | case SSH_CIPHER_NONE: | ||
276 | break; | ||
277 | |||
278 | case SSH_CIPHER_3DES: | ||
279 | case SSH_CIPHER_BLOWFISH: | ||
280 | fatal("cipher_set_key_iv: illegal cipher: %s", cipher_name(cipher)); | ||
281 | break; | ||
282 | |||
283 | case SSH_CIPHER_3DES_CBC: | ||
284 | if (keylen < 24) | ||
285 | error("Key length %d is insufficient for 3des-cbc.", keylen); | ||
286 | des_set_key((void *) key, context->u.des3.key1); | ||
287 | des_set_key((void *) (key+8), context->u.des3.key2); | ||
288 | des_set_key((void *) (key+16), context->u.des3.key3); | ||
289 | if (ivlen < 8) | ||
290 | error("IV length %d is insufficient for 3des-cbc.", ivlen); | ||
291 | memcpy(context->u.des3.iv3, (char *)iv, 8); | ||
292 | break; | ||
293 | |||
294 | case SSH_CIPHER_BLOWFISH_CBC: | ||
295 | if (keylen < 16) | ||
296 | error("Key length %d is insufficient for blowfish.", keylen); | ||
297 | if (ivlen < 8) | ||
298 | error("IV length %d is insufficient for blowfish.", ivlen); | ||
299 | BF_set_key(&context->u.bf.key, keylen, (unsigned char *)key); | ||
300 | memcpy(context->u.bf.iv, (char *)iv, 8); | ||
301 | break; | ||
302 | |||
303 | case SSH_CIPHER_ARCFOUR: | ||
304 | if (keylen < 16) | ||
305 | error("Key length %d is insufficient for arcfour.", keylen); | ||
306 | RC4_set_key(&context->u.rc4, keylen, (unsigned char *)key); | ||
307 | break; | ||
308 | |||
309 | case SSH_CIPHER_CAST128_CBC: | ||
310 | if (keylen < 16) | ||
311 | error("Key length %d is insufficient for cast128.", keylen); | ||
312 | if (ivlen < 8) | ||
313 | error("IV length %d is insufficient for cast128.", ivlen); | ||
314 | CAST_set_key(&context->u.cast.key, keylen, (unsigned char *) key); | ||
315 | memcpy(context->u.cast.iv, (char *)iv, 8); | ||
316 | break; | ||
317 | |||
318 | default: | ||
319 | fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher)); | ||
320 | } | ||
321 | } | ||
322 | |||
246 | /* Encrypts data using the cipher. */ | 323 | /* Encrypts data using the cipher. */ |
247 | 324 | ||
248 | void | 325 | void |
@@ -272,6 +349,27 @@ cipher_encrypt(CipherContext *context, unsigned char *dest, | |||
272 | swap_bytes(dest, dest, len); | 349 | swap_bytes(dest, dest, len); |
273 | break; | 350 | break; |
274 | 351 | ||
352 | case SSH_CIPHER_BLOWFISH_CBC: | ||
353 | BF_cbc_encrypt((void *)src, dest, len, | ||
354 | &context->u.bf.key, context->u.bf.iv, | ||
355 | BF_ENCRYPT); | ||
356 | break; | ||
357 | |||
358 | case SSH_CIPHER_3DES_CBC: | ||
359 | des_ede3_cbc_encrypt(src, dest, len, | ||
360 | context->u.des3.key1, context->u.des3.key2, | ||
361 | context->u.des3.key3, &context->u.des3.iv3, DES_ENCRYPT); | ||
362 | break; | ||
363 | |||
364 | case SSH_CIPHER_ARCFOUR: | ||
365 | RC4(&context->u.rc4, len, (unsigned char *)src, dest); | ||
366 | break; | ||
367 | |||
368 | case SSH_CIPHER_CAST128_CBC: | ||
369 | CAST_cbc_encrypt(src, dest, len, | ||
370 | &context->u.cast.key, context->u.cast.iv, CAST_ENCRYPT); | ||
371 | break; | ||
372 | |||
275 | default: | 373 | default: |
276 | fatal("cipher_encrypt: unknown cipher: %s", cipher_name(context->type)); | 374 | fatal("cipher_encrypt: unknown cipher: %s", cipher_name(context->type)); |
277 | } | 375 | } |
@@ -306,6 +404,27 @@ cipher_decrypt(CipherContext *context, unsigned char *dest, | |||
306 | swap_bytes(dest, dest, len); | 404 | swap_bytes(dest, dest, len); |
307 | break; | 405 | break; |
308 | 406 | ||
407 | case SSH_CIPHER_BLOWFISH_CBC: | ||
408 | BF_cbc_encrypt((void *) src, dest, len, | ||
409 | &context->u.bf.key, context->u.bf.iv, | ||
410 | BF_DECRYPT); | ||
411 | break; | ||
412 | |||
413 | case SSH_CIPHER_3DES_CBC: | ||
414 | des_ede3_cbc_encrypt(src, dest, len, | ||
415 | context->u.des3.key1, context->u.des3.key2, | ||
416 | context->u.des3.key3, &context->u.des3.iv3, DES_DECRYPT); | ||
417 | break; | ||
418 | |||
419 | case SSH_CIPHER_ARCFOUR: | ||
420 | RC4(&context->u.rc4, len, (unsigned char *)src, dest); | ||
421 | break; | ||
422 | |||
423 | case SSH_CIPHER_CAST128_CBC: | ||
424 | CAST_cbc_encrypt(src, dest, len, | ||
425 | &context->u.cast.key, context->u.cast.iv, CAST_DECRYPT); | ||
426 | break; | ||
427 | |||
309 | default: | 428 | default: |
310 | fatal("cipher_decrypt: unknown cipher: %s", cipher_name(context->type)); | 429 | fatal("cipher_decrypt: unknown cipher: %s", cipher_name(context->type)); |
311 | } | 430 | } |