/* $Id: blowfish.c,v 1.13 1999/06/25 05:33:38 levitte Exp $ */

#include "gnu_extras.h"

#include <stdio.h>		/* Because some versions of OpenSSL need it */
#include <string.h>
#include <lib$routines.h>
#include <starlet.h>
#ifdef __GNUC__
#define __DECC
#endif
#include <openssl/blowfish.h>
#ifdef __GNUC__
#undef __DECC
#endif
#include "ssh.h"
#include "fish.h"
#include "util.h"
#include "fishmsg.h"

typedef struct {
    BF_KEY bf_key;
    unsigned char ivec[BF_BLOCK];
} Tblowfish_state;

void ssh_blowfish_encrypt(unsigned char *in, unsigned char *out, long len,
    void *encryptstate_)
{
    Tblowfish_state *encryptstate = encryptstate_;

    invert_byte_order(len, in);
    BF_cbc_encrypt(in, out, len, &encryptstate->bf_key,
		   encryptstate->ivec, BF_ENCRYPT);
    invert_byte_order(len, in);
}

void ssh_blowfish_decrypt(unsigned char *in, unsigned char *out, long len,
    void *decryptstate_)
{
    Tblowfish_state *decryptstate = decryptstate_;

    invert_byte_order(len, in);
    BF_cbc_encrypt(in, out, len, &decryptstate->bf_key,
		   decryptstate->ivec, BF_DECRYPT);
    invert_byte_order(len, in);
}

void ssh_blowfish_clean(ssh_state *state)
{
    xfree(state->encryptstate);
    xfree(state->decryptstate);
    state->encrypt = NULL;
    state->decrypt = NULL;
    state->cryptclean = NULL;
}

void *ssh_blowfish_encryptstate(ssh_state *state, int keylen, Erf erf, void *erfp)
{
    Tblowfish_state *encryptstate = xmalloc(sizeof(Tblowfish_state));
    if (!encryptstate) {
	ssh_F_memfull();
	return NULL;
    }
    BF_set_key(&encryptstate->bf_key, 32, state->sesskey);
    memset(encryptstate->ivec, 0, BF_BLOCK);

    return encryptstate;
}

void *ssh_blowfish_decryptstate(ssh_state *state, int keylen, Erf erf, void *erfp)
{
    Tblowfish_state *decryptstate = xmalloc(sizeof(Tblowfish_state));
    if (!decryptstate) {
	ssh_F_memfull();
	return NULL;
    }
    BF_set_key(&decryptstate->bf_key, 32, state->sesskey);
    memset(decryptstate->ivec, 0, BF_BLOCK);

    return decryptstate;
}

/* Emacs local variables

Local variables:
eval: (set-c-style "BSD")
end:

*/
