X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/94ec8c6bb36d0681d3d8e61de9b260b159772799..dd2495cba27edd8a16dca65037ccceb7128d3509:/cipher.c diff --git a/cipher.c b/cipher.c index 226e4256..5f63cd4b 100644 --- a/cipher.c +++ b/cipher.c @@ -11,7 +11,7 @@ * * * Copyright (c) 1999 Niels Provos. All rights reserved. - * Copyright (c) 1999,2000 Markus Friedl. All rights reserved. + * Copyright (c) 1999, 2000 Markus Friedl. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,31 +35,31 @@ */ #include "includes.h" -RCSID("$OpenBSD: cipher.c,v 1.35 2000/10/13 18:59:13 markus Exp $"); +RCSID("$OpenBSD: cipher.c,v 1.46 2001/06/25 08:25:36 markus Exp $"); -#include "ssh.h" #include "xmalloc.h" +#include "log.h" +#include "cipher.h" #include - /* no encryption */ -void +static void none_setkey(CipherContext *cc, const u_char *key, u_int keylen) { } -void +static void none_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) { } -void +static void none_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) { memcpy(dest, src, len); } /* DES */ -void +static void des_ssh1_setkey(CipherContext *cc, const u_char *key, u_int keylen) { static int dowarn = 1; @@ -70,18 +70,18 @@ des_ssh1_setkey(CipherContext *cc, const u_char *key, u_int keylen) } des_set_key((void *)key, cc->u.des.key); } -void +static void des_ssh1_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) { memset(cc->u.des.iv, 0, sizeof(cc->u.des.iv)); } -void +static void des_ssh1_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) { des_ncbc_encrypt(src, dest, len, cc->u.des.key, &cc->u.des.iv, DES_ENCRYPT); } -void +static void des_ssh1_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) { des_ncbc_encrypt(src, dest, len, cc->u.des.key, &cc->u.des.iv, @@ -89,30 +89,31 @@ des_ssh1_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) } /* 3DES */ -void +static void des3_setkey(CipherContext *cc, const u_char *key, u_int keylen) { des_set_key((void *) key, cc->u.des3.key1); des_set_key((void *) (key+8), cc->u.des3.key2); des_set_key((void *) (key+16), cc->u.des3.key3); } -void +static void des3_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) { + memset(cc->u.des3.iv1, 0, sizeof(cc->u.des3.iv1)); memset(cc->u.des3.iv2, 0, sizeof(cc->u.des3.iv2)); memset(cc->u.des3.iv3, 0, sizeof(cc->u.des3.iv3)); if (iv == NULL) return; memcpy(cc->u.des3.iv3, (char *)iv, 8); } -void +static void des3_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) { des_ede3_cbc_encrypt(src, dest, len, cc->u.des3.key1, cc->u.des3.key2, cc->u.des3.key3, &cc->u.des3.iv3, DES_ENCRYPT); } -void +static void des3_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) { des_ede3_cbc_encrypt(src, dest, len, @@ -134,7 +135,7 @@ des3_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) * result of that there is no longer any known iv1 to use when * choosing the X block. */ -void +static void des3_ssh1_setkey(CipherContext *cc, const u_char *key, u_int keylen) { des_set_key((void *) key, cc->u.des3.key1); @@ -144,53 +145,36 @@ des3_ssh1_setkey(CipherContext *cc, const u_char *key, u_int keylen) else des_set_key((void *) (key+16), cc->u.des3.key3); } -void +static void des3_ssh1_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) { - des_cblock iv1; - des_cblock *iv2 = &cc->u.des3.iv2; - des_cblock *iv3 = &cc->u.des3.iv3; - - memcpy(&iv1, iv2, 8); - - des_cbc_encrypt(src, dest, len, cc->u.des3.key1, &iv1, DES_ENCRYPT); - memcpy(&iv1, dest + len - 8, 8); - - des_cbc_encrypt(dest, dest, len, cc->u.des3.key2, iv2, DES_DECRYPT); - memcpy(iv2, &iv1, 8); /* Note how iv1 == iv2 on entry and exit. */ - - des_cbc_encrypt(dest, dest, len, cc->u.des3.key3, iv3, DES_ENCRYPT); - memcpy(iv3, dest + len - 8, 8); + des_ncbc_encrypt(src, dest, len, cc->u.des3.key1, &cc->u.des3.iv1, + DES_ENCRYPT); + des_ncbc_encrypt(dest, dest, len, cc->u.des3.key2, &cc->u.des3.iv2, + DES_DECRYPT); + des_ncbc_encrypt(dest, dest, len, cc->u.des3.key3, &cc->u.des3.iv3, + DES_ENCRYPT); } -void +static void des3_ssh1_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) { - des_cblock iv1; - des_cblock *iv2 = &cc->u.des3.iv2; - des_cblock *iv3 = &cc->u.des3.iv3; - - memcpy(&iv1, iv2, 8); - - des_cbc_encrypt(src, dest, len, cc->u.des3.key3, iv3, DES_DECRYPT); - memcpy(iv3, src + len - 8, 8); - - des_cbc_encrypt(dest, dest, len, cc->u.des3.key2, iv2, DES_ENCRYPT); - memcpy(iv2, dest + len - 8, 8); - - des_cbc_encrypt(dest, dest, len, cc->u.des3.key1, &iv1, DES_DECRYPT); - /* memcpy(&iv1, iv2, 8); */ - /* Note how iv1 == iv2 on entry and exit. */ + des_ncbc_encrypt(src, dest, len, cc->u.des3.key3, &cc->u.des3.iv3, + DES_DECRYPT); + des_ncbc_encrypt(dest, dest, len, cc->u.des3.key2, &cc->u.des3.iv2, + DES_ENCRYPT); + des_ncbc_encrypt(dest, dest, len, cc->u.des3.key1, &cc->u.des3.iv1, + DES_DECRYPT); } /* Blowfish */ -void +static void blowfish_setkey(CipherContext *cc, const u_char *key, u_int keylen) { - BF_set_key(&cc->u.bf.key, keylen, (unsigned char *)key); + BF_set_key(&cc->u.bf.key, keylen, (u_char *)key); } -void +static void blowfish_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) { if (iv == NULL) @@ -198,14 +182,14 @@ blowfish_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) else memcpy(cc->u.bf.iv, (char *)iv, 8); } -void +static void blowfish_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) { BF_cbc_encrypt((void *)src, dest, len, &cc->u.bf.key, cc->u.bf.iv, BF_ENCRYPT); } -void +static void blowfish_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) { @@ -218,32 +202,25 @@ blowfish_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src, * and after encryption/decryption. Thus the swap_bytes stuff (yuk). */ static void -swap_bytes(const unsigned char *src, unsigned char *dst_, int n) -{ - /* dst must be properly aligned. */ - u_int32_t *dst = (u_int32_t *) dst_; - union { - u_int32_t i; - char c[4]; - } t; - - /* Process 8 bytes every lap. */ - for (n = n / 8; n > 0; n--) { - t.c[3] = *src++; - t.c[2] = *src++; - t.c[1] = *src++; - t.c[0] = *src++; - *dst++ = t.i; - - t.c[3] = *src++; - t.c[2] = *src++; - t.c[1] = *src++; - t.c[0] = *src++; - *dst++ = t.i; +swap_bytes(const u_char *src, u_char *dst, int n) +{ + char c[4]; + + /* Process 4 bytes every lap. */ + for (n = n / 4; n > 0; n--) { + c[3] = *src++; + c[2] = *src++; + c[1] = *src++; + c[0] = *src++; + + *dst++ = c[0]; + *dst++ = c[1]; + *dst++ = c[2]; + *dst++ = c[3]; } } -void +static void blowfish_ssh1_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) { @@ -252,7 +229,7 @@ blowfish_ssh1_encrypt(CipherContext *cc, u_char *dest, const u_char *src, BF_ENCRYPT); swap_bytes(dest, dest, len); } -void +static void blowfish_ssh1_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) { @@ -263,37 +240,37 @@ blowfish_ssh1_decrypt(CipherContext *cc, u_char *dest, const u_char *src, } /* alleged rc4 */ -void +static void arcfour_setkey(CipherContext *cc, const u_char *key, u_int keylen) { RC4_set_key(&cc->u.rc4, keylen, (u_char *)key); } -void +static void arcfour_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) { RC4(&cc->u.rc4, len, (u_char *)src, dest); } /* CAST */ -void +static void cast_setkey(CipherContext *cc, const u_char *key, u_int keylen) { - CAST_set_key(&cc->u.cast.key, keylen, (unsigned char *) key); + CAST_set_key(&cc->u.cast.key, keylen, (u_char *) key); } -void +static void cast_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) { - if (iv == NULL) + if (iv == NULL) fatal("no IV for %s.", cc->cipher->name); memcpy(cc->u.cast.iv, (char *)iv, 8); } -void +static void cast_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) { CAST_cbc_encrypt(src, dest, len, &cc->u.cast.key, cc->u.cast.iv, CAST_ENCRYPT); } -void +static void cast_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) { CAST_cbc_encrypt(src, dest, len, &cc->u.cast.key, cc->u.cast.iv, @@ -303,20 +280,20 @@ cast_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) /* RIJNDAEL */ #define RIJNDAEL_BLOCKSIZE 16 -void +static void rijndael_setkey(CipherContext *cc, const u_char *key, u_int keylen) { rijndael_set_key(&cc->u.rijndael.enc, (u4byte *)key, 8*keylen, 1); rijndael_set_key(&cc->u.rijndael.dec, (u4byte *)key, 8*keylen, 0); } -void +static void rijndael_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) { - if (iv == NULL) + if (iv == NULL) fatal("no IV for %s.", cc->cipher->name); memcpy((u_char *)cc->u.rijndael.iv, iv, RIJNDAEL_BLOCKSIZE); } -void +static void rijndael_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) { @@ -343,7 +320,7 @@ rijndael_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src, memcpy(iv, cprev, RIJNDAEL_BLOCKSIZE); } -void +static void rijndael_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) { @@ -432,15 +409,15 @@ Cipher ciphers[] = { SSH_CIPHER_SSH2, 16, 32, rijndael_setkey, rijndael_setiv, rijndael_cbc_encrypt, rijndael_cbc_decrypt }, - { NULL, SSH_CIPHER_ILLEGAL, 0, 0, NULL, NULL, NULL, NULL } + { NULL, SSH_CIPHER_ILLEGAL, 0, 0, NULL, NULL, NULL, NULL } }; /*--*/ -unsigned int +u_int cipher_mask_ssh1(int client) { - unsigned int mask = 0; + u_int mask = 0; mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ mask |= 1 << SSH_CIPHER_BLOWFISH; if (client) { @@ -488,10 +465,10 @@ ciphers_valid(const char *names) xfree(ciphers); return 0; } else { - debug("cipher ok: %s [%s]", p, names); + debug3("cipher ok: %s [%s]", p, names); } } - debug("ciphers ok: [%s]", names); + debug3("ciphers ok: [%s]", names); xfree(ciphers); return 1; } @@ -559,7 +536,7 @@ cipher_set_key_string(CipherContext *cc, Cipher *cipher, const char *passphrase) { MD5_CTX md; - unsigned char digest[16]; + u_char digest[16]; MD5_Init(&md); MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase));