/* This file is in the public domain. */ #include #include #include #include "algs.h" #include "panic.h" #include "verbose.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; if (VERB(CRYPTO)) { int i; verb(CRYPTO,"blowfish-cbc %p: enc key=",(void *)s); for (i=0;i<16;i++) verb(CRYPTO,"%02x",((const unsigned char *)key)[i]); verb(CRYPTO," iv="); for (i=0;i<8;i++) verb(CRYPTO,"%02x",s->iv[i]); verb(CRYPTO,"\n"); } 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; if (VERB(CRYPTO)) { int i; verb(CRYPTO,"blowfish-cbc %p: dec key=",(void *)s); for (i=0;i<16;i++) verb(CRYPTO,"%02x",((const unsigned char *)key)[i]); verb(CRYPTO," iv="); for (i=0;i<8;i++) verb(CRYPTO,"%02x",s->iv[i]); verb(CRYPTO,"\n"); } 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; int len0; s = state; ip = in; op = out; if (datalen & 7) panic("misaligned length"); if (VERB(CRYPTO)) { int i; verb(CRYPTO,"blowfish-cbc %p\n in ",(void *)s); for (i=0;iiv[i]); verb(CRYPTO,"\n"); len0 = datalen; } switch (s->direction) { case ENCRYPT: while (datalen > 0) { xor_block(&s->iv[0],ip,&s->iv[0],8); blowfish_encrypt(&s->key,&s->iv[0],&s->iv[0]); bcopy(&s->iv[0],op,8); ip += 8; op += 8; datalen -= 8; } break; case DECRYPT: while (datalen > 0) { unsigned char ib[8]; bcopy(ip,&ib[0],8); blowfish_decrypt(&s->key,ip,op); xor_block(&s->iv[0],op,op,8); bcopy(ib,&s->iv[0],8); ip += 8; op += 8; datalen -= 8; } break; default: panic("bad direction"); break; } if (VERB(CRYPTO)) { int i; verb(CRYPTO,"out "); for (i=0;iiv[i]); verb(CRYPTO,"\n"); } } static void enc_blowfish_cbc_done(void *state) { free(state); } static void *enc_blowfish_ctr_init(const void *key, const void *iv) { BF_STATE *s; s = malloc(sizeof(BF_STATE)); if (s == 0) return(0); blowfish_setkey(&s->key,key,32); bcopy(iv,&s->iv[0],8); if (VERB(CRYPTO)) { int i; verb(CRYPTO,"blowfish-ctr %p: key=",(void *)s); for (i=0;i<32;i++) verb(CRYPTO,"%02x",((const unsigned char *)key)[i]); verb(CRYPTO," iv="); for (i=0;i<8;i++) verb(CRYPTO,"%02x",s->iv[i]); verb(CRYPTO,"\n"); } return(s); } static void enc_blowfish_ctr_process(void *state, const void *in, void *out, int datalen) { BF_STATE *s; const unsigned char *ip; unsigned char *op; unsigned char *x; unsigned char xorbuf[8]; int i; int left; s = state; ip = in; op = out; x = &s->iv[0]; if (datalen & 7) panic("misaligned length"); if (VERB(CRYPTO)) { int i; verb(CRYPTO,"blowfish-ctr %p\n in",(void *)s); for (i=0;i0;left-=8) { blowfish_encrypt(&s->key,&x[0],&xorbuf[0]); xor_block(&xorbuf[0],ip,op,8); i = 7; while (1) { if (i < 0) break; if (x[i] != 0xff) { x[i] ++; break; } x[i] = 0; i --; } ip += 8; op += 8; } if (VERB(CRYPTO)) { int i; verb(CRYPTO,"out"); for (i=0;i