#include #include #include #include "algs.h" #include "alg-util.h" typedef struct bf_state BF_STATE; struct bf_state { BLOWFISH_KEY key; unsigned char iv[8]; int direction; #define ENCRYPT 1 #define DECRYPT 2 } ; static void *enc_blowfish_cbc_init_enc(const void *key, const void *iv) { BF_STATE *s; s = malloc(sizeof(BF_STATE)); if (s == 0) return(0); blowfish_setkey(&s->key,key,16); bcopy(iv,&s->iv[0],8); s->direction = ENCRYPT; return(s); } static void *enc_blowfish_cbc_init_dec(const void *key, const void *iv) { BF_STATE *s; s = malloc(sizeof(BF_STATE)); if (s == 0) return(0); blowfish_setkey(&s->key,key,16); bcopy(iv,&s->iv[0],8); s->direction = DECRYPT; return(s); } static void enc_blowfish_cbc_process(void *state, const void *in, void *out, int datalen) { BF_STATE *s; const unsigned char *ip; unsigned char *op; unsigned char xorbuf[8]; s = state; ip = in; op = out; if (datalen & 7) abort(); switch (s->direction) { case ENCRYPT: bcopy(&s->iv[0],&xorbuf[0],8); while (datalen > 0) { xor_block(&xorbuf[0],ip,&xorbuf[0],8); blowfish_encrypt(&s->key,&xorbuf[0],&xorbuf[0]); bcopy(&xorbuf[0],op,8); ip += 8; op += 8; datalen -= 8; } bcopy(&xorbuf[0],&s->iv[0],8); break; case DECRYPT: { unsigned char iv1[8] __attribute__((__aligned__)); unsigned char iv2[8] __attribute__((__aligned__)); bcopy(&s->iv[0],&iv1[0],8); while (datalen > 0) { bcopy(ip,&iv2[0],8); blowfish_decrypt(&s->key,ip,op); xor_block(&iv1[0],op,op,8); bcopy(&iv2[0],&iv1[0],8); ip += 8; op += 8; datalen -= 8; } bcopy(&iv1[0],&s->iv[0],8); } break; default: abort(); break; } } static void enc_blowfish_cbc_done(void *state) { free(state); } ENCALG encalg_blowfish_cbc = { "blowfish-cbc", 8, 8, 16, &enc_blowfish_cbc_init_enc, &enc_blowfish_cbc_init_dec, &enc_blowfish_cbc_process, &enc_blowfish_cbc_done };