summaryrefslogtreecommitdiff
path: root/lib/libcrypto/include/cbc_generic.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libcrypto/include/cbc_generic.h')
-rw-r--r--lib/libcrypto/include/cbc_generic.h110
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 */