/* $Id: 3des.c,v 1.11 1999/06/25 05:33:38 levitte Exp $ */ #include "gnu_extras.h" #include #include #include #ifdef __GNUC__ #define __DECC #endif #include #include #ifdef __GNUC__ #undef __DECC #endif #include "des_hack.h" #include "fish.h" #include "ssh.h" #include "util.h" #include "fishmsg.h" typedef struct { des_key_schedule k1; des_key_schedule k2; des_key_schedule k3; des_cblock ivec1; des_cblock ivec2; des_cblock ivec3; } T3des_state; void ssh_3des_encrypt(unsigned char *in, unsigned char *out, long len, void *encryptstate_) { T3des_state *encryptstate = encryptstate_; des_ncbc_encrypt(des_cblock_arg(in), des_cblock_arg(out), len, encryptstate->k1, des_cblock_ivec(encryptstate->ivec1), DES_ENCRYPT); des_ncbc_encrypt(des_cblock_arg(out), des_cblock_arg(out), len, encryptstate->k2, des_cblock_ivec(encryptstate->ivec2), DES_DECRYPT); des_ncbc_encrypt(des_cblock_arg(out), des_cblock_arg(out), len, encryptstate->k3, des_cblock_ivec(encryptstate->ivec3), DES_ENCRYPT); } void ssh_3des_decrypt(unsigned char *in, unsigned char *out, long len, void *decryptstate_) { T3des_state *decryptstate = decryptstate_; des_ncbc_encrypt(des_cblock_arg(in), des_cblock_arg(out), len, decryptstate->k3, des_cblock_ivec(decryptstate->ivec3), DES_DECRYPT); des_ncbc_encrypt(des_cblock_arg(out), des_cblock_arg(out), len, decryptstate->k2, des_cblock_ivec(decryptstate->ivec2), DES_ENCRYPT); des_ncbc_encrypt(des_cblock_arg(out), des_cblock_arg(out), len, decryptstate->k1, des_cblock_ivec(decryptstate->ivec1), DES_DECRYPT); } void ssh_3des_clean(ssh_state *state) { xfree(state->encryptstate); xfree(state->decryptstate); state->encrypt = NULL; state->decrypt = NULL; state->cryptclean = NULL; } void *ssh_3des_encryptstate(ssh_state *state, int keylen, Erf erf, void *erfp) { T3des_state *encryptstate = xmalloc(sizeof(T3des_state)); des_cblock k1, k2, k3; if (!encryptstate) { ssh_F_memfull(); return NULL; } memcpy(k1,state->sesskey,sizeof(k1)); memcpy(k2,state->sesskey+8,sizeof(k2)); if (keylen <= 16) memcpy(k3,state->sesskey,sizeof(k3)); else memcpy(k3,state->sesskey+16,sizeof(k3)); des_set_key(des_cblock_set_arg(k1),encryptstate->k1); des_set_key(des_cblock_set_arg(k2),encryptstate->k2); des_set_key(des_cblock_set_arg(k3),encryptstate->k3); memset(encryptstate->ivec1, 0, 8); memset(encryptstate->ivec2, 0, 8); memset(encryptstate->ivec3, 0, 8); return encryptstate; } void *ssh_3des_decryptstate(ssh_state *state, int keylen, Erf erf, void *erfp) { T3des_state *encryptstate = xmalloc(sizeof(T3des_state)); des_cblock k1, k2, k3; if (!encryptstate) { ssh_F_memfull(); return NULL; } memcpy(k1,state->sesskey,sizeof(k1)); memcpy(k2,state->sesskey+8,sizeof(k2)); if (keylen <= 16) memcpy(k3,state->sesskey,sizeof(k3)); else memcpy(k3,state->sesskey+16,sizeof(k3)); des_set_key(des_cblock_set_arg(k1),encryptstate->k1); des_set_key(des_cblock_set_arg(k2),encryptstate->k2); des_set_key(des_cblock_set_arg(k3),encryptstate->k3); memset(encryptstate->ivec1, 0, 8); memset(encryptstate->ivec2, 0, 8); memset(encryptstate->ivec3, 0, 8); return encryptstate; } /* Emacs local variables Local variables: eval: (set-c-style "BSD") end: */