version 1.50, 2002/01/21 22:30:12 |
version 1.51, 2002/02/14 23:41:01 |
|
|
|
|
#include <openssl/md5.h> |
#include <openssl/md5.h> |
|
|
|
struct Cipher { |
|
char *name; |
|
int number; /* for ssh1 only */ |
|
u_int block_size; |
|
u_int key_len; |
|
void (*setkey)(CipherContext *, const u_char *, u_int); |
|
void (*setiv)(CipherContext *, const u_char *, u_int); |
|
void (*encrypt)(CipherContext *, u_char *, const u_char *, u_int); |
|
void (*decrypt)(CipherContext *, u_char *, const u_char *, u_int); |
|
}; |
|
|
/* no encryption */ |
/* no encryption */ |
static void |
static void |
none_setkey(CipherContext *cc, const u_char *key, u_int keylen) |
none_setkey(CipherContext *cc, const u_char *key, u_int keylen) |
|
|
|
|
/*--*/ |
/*--*/ |
|
|
|
u_int |
|
cipher_blocksize(Cipher *c) |
|
{ |
|
return (c->block_size); |
|
} |
|
|
|
u_int |
|
cipher_keylen(Cipher *c) |
|
{ |
|
return (c->key_len); |
|
} |
|
|
u_int |
u_int |
cipher_mask_ssh1(int client) |
cipher_mask_ssh1(int client) |
{ |
{ |
|
|
} |
} |
|
|
void |
void |
cipher_init(CipherContext *cc, Cipher *cipher, |
cipher_init(CipherContext *cc, Cipher *cipher, const u_char *key, |
const u_char *key, u_int keylen, const u_char *iv, u_int ivlen) |
u_int keylen, const u_char *iv, u_int ivlen, int encrypt) |
{ |
{ |
if (keylen < cipher->key_len) |
if (keylen < cipher->key_len) |
fatal("cipher_init: key length %d is insufficient for %s.", |
fatal("cipher_init: key length %d is insufficient for %s.", |
|
|
fatal("cipher_init: iv length %d is insufficient for %s.", |
fatal("cipher_init: iv length %d is insufficient for %s.", |
ivlen, cipher->name); |
ivlen, cipher->name); |
cc->cipher = cipher; |
cc->cipher = cipher; |
|
cc->encrypt = (encrypt == CIPHER_ENCRYPT); |
cipher->setkey(cc, key, keylen); |
cipher->setkey(cc, key, keylen); |
cipher->setiv(cc, iv, ivlen); |
cipher->setiv(cc, iv, ivlen); |
} |
} |
|
|
void |
void |
cipher_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) |
cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) |
{ |
{ |
if (len % cc->cipher->block_size) |
if (len % cc->cipher->block_size) |
fatal("cipher_encrypt: bad plaintext length %d", len); |
fatal("cipher_encrypt: bad plaintext length %d", len); |
cc->cipher->encrypt(cc, dest, src, len); |
if (cc->encrypt) |
|
cc->cipher->encrypt(cc, dest, src, len); |
|
else |
|
cc->cipher->decrypt(cc, dest, src, len); |
} |
} |
|
|
void |
void |
cipher_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) |
cipher_cleanup(CipherContext *cc) |
{ |
{ |
if (len % cc->cipher->block_size) |
memset(cc, 0, sizeof(*cc)); |
fatal("cipher_decrypt: bad ciphertext length %d", len); |
|
cc->cipher->decrypt(cc, dest, src, len); |
|
} |
} |
|
|
/* |
/* |
|
|
|
|
void |
void |
cipher_set_key_string(CipherContext *cc, Cipher *cipher, |
cipher_set_key_string(CipherContext *cc, Cipher *cipher, |
const char *passphrase) |
const char *passphrase, int encrypt) |
{ |
{ |
MD5_CTX md; |
MD5_CTX md; |
u_char digest[16]; |
u_char digest[16]; |
|
|
MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase)); |
MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase)); |
MD5_Final(digest, &md); |
MD5_Final(digest, &md); |
|
|
cipher_init(cc, cipher, digest, 16, NULL, 0); |
cipher_init(cc, cipher, digest, 16, NULL, 0, encrypt); |
|
|
memset(digest, 0, sizeof(digest)); |
memset(digest, 0, sizeof(digest)); |
memset(&md, 0, sizeof(md)); |
memset(&md, 0, sizeof(md)); |