diff options
Diffstat (limited to 'lib/libcrypto/include/cbc_generic.h')
-rw-r--r-- | lib/libcrypto/include/cbc_generic.h | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/lib/libcrypto/include/cbc_generic.h b/lib/libcrypto/include/cbc_generic.h new file mode 100644 index 000000000..0dd3a77d6 --- /dev/null +++ b/lib/libcrypto/include/cbc_generic.h @@ -0,0 +1,110 @@ +#ifndef _CBC_GENERIC_H +#define _CBC_GENERIC_H +/* + * CBC macro helpers + * + * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + */ + +/* + * Heavily inspired in loop_AES + */ +#define CBC_IMPL_BLK16(name, ctx_type, addr_type, enc_func, dec_func) \ +int name(ctx_type *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \ + int ret=ilen, pos; \ + const u_int32_t *iv_i; \ + if ((ilen) % 16) return 0; \ + if (encrypt) { \ + pos=0; \ + while(pos<ilen) { \ + if (pos==0) \ + iv_i=(const u_int32_t*) iv; \ + else \ + iv_i=(const u_int32_t*) (out-16); \ + *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \ + *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \ + *((u_int32_t *)(&out[ 8])) = iv_i[2]^*((const u_int32_t *)(&in[ 8])); \ + *((u_int32_t *)(&out[12])) = iv_i[3]^*((const u_int32_t *)(&in[12])); \ + enc_func(ctx, (addr_type) out, (addr_type) out); \ + in+=16; \ + out+=16; \ + pos+=16; \ + } \ + } else { \ + pos=ilen-16; \ + in+=pos; \ + out+=pos; \ + while(pos>=0) { \ + dec_func(ctx, (const addr_type) in, (addr_type) out); \ + if (pos==0) \ + iv_i=(const u_int32_t*) (iv); \ + else \ + iv_i=(const u_int32_t*) (in-16); \ + *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \ + *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \ + *((u_int32_t *)(&out[ 8])) ^= iv_i[2]; \ + *((u_int32_t *)(&out[12])) ^= iv_i[3]; \ + in-=16; \ + out-=16; \ + pos-=16; \ + } \ + } \ + return ret; \ +} +#define CBC_IMPL_BLK8(name, ctx_type, addr_type, enc_func, dec_func) \ +int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \ + int ret=ilen, pos; \ + const u_int32_t *iv_i; \ + if ((ilen) % 8) return 0; \ + if (encrypt) { \ + pos=0; \ + while(pos<ilen) { \ + if (pos==0) \ + iv_i=(const u_int32_t*) iv; \ + else \ + iv_i=(const u_int32_t*) (out-8); \ + *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \ + *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \ + enc_func(ctx, (addr_type)out, (addr_type)out); \ + in+=8; \ + out+=8; \ + pos+=8; \ + } \ + } else { \ + pos=ilen-8; \ + in+=pos; \ + out+=pos; \ + while(pos>=0) { \ + dec_func(ctx, (const addr_type)in, (addr_type)out); \ + if (pos==0) \ + iv_i=(const u_int32_t*) (iv); \ + else \ + iv_i=(const u_int32_t*) (in-8); \ + *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \ + *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \ + in-=8; \ + out-=8; \ + pos-=8; \ + } \ + } \ + return ret; \ +} +#define CBC_DECL(name, ctx_type) \ +int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) +/* +Eg.: +CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt); +CBC_DECL(AES_cbc_encrypt, aes_context); +*/ +#endif /* _CBC_GENERIC_H */ |