#include #include #include #include "algs.h" #include "alg-util.h" typedef struct idea_state IDEA_STATE; struct idea_state { IDEA_KEY key; unsigned char iv[8]; int direction; #define ENCRYPT 1 #define DECRYPT 2 } ; static void *enc_idea_cbc_init_enc(const void *key, const void *iv) { IDEA_STATE *s; s = malloc(sizeof(IDEA_STATE)); if (s == 0) return(0); idea_setkey_e(key,&s->key); bcopy(iv,&s->iv[0],8); s->direction = ENCRYPT; return(s); } static void *enc_idea_cbc_init_dec(const void *key, const void *iv) { IDEA_STATE *s; s = malloc(sizeof(IDEA_STATE)); if (s == 0) return(0); idea_setkey_d(key,&s->key); bcopy(iv,&s->iv[0],8); s->direction = DECRYPT; return(s); } static void enc_idea_cbc_process(void *state, const void *in, void *out, int datalen) { IDEA_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); idea_crypt(&xorbuf[0],&s->key,&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); idea_crypt(ip,&s->key,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_idea_cbc_done(void *state) { free(state); } ENCALG encalg_idea_cbc = { "idea-cbc", 8, 8, 16, &enc_idea_cbc_init_enc, &enc_idea_cbc_init_dec, &enc_idea_cbc_process, &enc_idea_cbc_done };