1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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 */
|