#include #include #include #include "algs.h" #include "alg-util.h" typedef struct tdes_state TDES_STATE; struct tdes_state { unsigned char key[24]; unsigned char iv[8]; int direction; } ; static void *enc_3des_cbc_init_enc(const void *key, const void *iv) { TDES_STATE *s; s = malloc(sizeof(TDES_STATE)); if (s == 0) return(0); bcopy(key,&s->key[0],24); bcopy(iv,&s->iv[0],8); s->direction = ENCRYPT; return(s); } static void *enc_3des_cbc_init_dec(const void *key, const void *iv) { TDES_STATE *s; s = malloc(sizeof(TDES_STATE)); if (s == 0) return(0); bcopy(key,&s->key[0],24); bcopy(iv,&s->iv[0],8); s->direction = DECRYPT; return(s); } static void enc_3des_cbc_process(void *state, const void *in, void *out, int datalen) { TDES_STATE *s; const unsigned char *ip; unsigned char *op; s = state; ip = in; op = out; if (datalen & 7) abort(); switch (s->direction) { case ENCRYPT: { unsigned char xorbuf[8]; bcopy(&s->iv[0],&xorbuf[0],8); while (datalen > 0) { xor_block(&xorbuf[0],ip,&xorbuf[0],8); des3(&xorbuf[0],&xorbuf[0],&s->key[0],ENCRYPT); 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); des3(op,ip,&s->key[0],DECRYPT); 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_3des_cbc_done(void *state) { free(state); } ENCALG encalg_3des_cbc = { "3des-cbc", 8, 8, 24, &enc_3des_cbc_init_enc, &enc_3des_cbc_init_dec, &enc_3des_cbc_process, &enc_3des_cbc_done };