/* This file is in the public domain. */ #include #include #include #include #include "algs.h" #include "panic.h" #include "verbose.h" #include "alg-util.h" typedef struct des3_state DES3_STATE; struct des3_state { unsigned char key[24]; unsigned char iv[8]; int direction; } ; static void *enc_3des_cbc_init_enc(const void *key, const void *iv) { DES3_STATE *s; s = malloc(sizeof(DES3_STATE)); if (s == 0) return(0); bcopy(key,&s->key[0],24); bcopy(iv,&s->iv[0],8); s->direction = ENCRYPT; if (VERB(CRYPTO)) { int i; verb(CRYPTO,"3des-cbc %p: enc key=",(void *)s); for (i=0;i<24;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_3des_cbc_init_dec(const void *key, const void *iv) { DES3_STATE *s; s = malloc(sizeof(DES3_STATE)); if (s == 0) return(0); bcopy(key,&s->key[0],24); bcopy(iv,&s->iv[0],8); s->direction = DECRYPT; if (VERB(CRYPTO)) { int i; verb(CRYPTO,"3des-cbc %p: dec key=",(void *)s); for (i=0;i<24;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_3des_cbc_process(void *state, const void *in, void *out, int datalen) { DES3_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,"3des-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); des3(&s->iv[0],&s->iv[0],&s->key[0],ENCRYPT); 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); des3(op,ip,&s->key[0],DECRYPT); 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_3des_ctr_init(const void *key, const void *iv) { DES3_STATE *s; s = malloc(sizeof(DES3_STATE)); if (s == 0) return(0); bcopy(key,&s->key[0],24); bcopy(iv,&s->iv[0],8); if (VERB(CRYPTO)) { int i; verb(CRYPTO,"3des-ctr %p: key=",(void *)s); for (i=0;i<24;i++) verb(CRYPTO,"%02x",s->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_3des_ctr_process(void *state, const void *in, void *out, int datalen) { DES3_STATE *s; const unsigned char *ip; unsigned char *op; unsigned char *x; unsigned char xorbuf[8]; int left; int i; s = state; ip = in; op = out; x = &s->iv[0]; if (datalen & 7) panic("misaligned length"); if (VERB(CRYPTO)) { int i; verb(CRYPTO,"3des-ctr %p\n in",(void *)s); for (i=0;i0;left-=8) { des3(&xorbuf[0],&x[0],&s->key[0],ENCRYPT); 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