diff options
Diffstat (limited to 'src/lib/libcrypto/aes/aes_ige.c')
-rw-r--r-- | src/lib/libcrypto/aes/aes_ige.c | 145 |
1 files changed, 65 insertions, 80 deletions
diff --git a/src/lib/libcrypto/aes/aes_ige.c b/src/lib/libcrypto/aes/aes_ige.c index c161351e65..0882a3d853 100644 --- a/src/lib/libcrypto/aes/aes_ige.c +++ b/src/lib/libcrypto/aes/aes_ige.c | |||
@@ -56,7 +56,7 @@ | |||
56 | 56 | ||
57 | #define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long)) | 57 | #define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long)) |
58 | typedef struct { | 58 | typedef struct { |
59 | unsigned long data[N_WORDS]; | 59 | unsigned long data[N_WORDS]; |
60 | } aes_block_t; | 60 | } aes_block_t; |
61 | 61 | ||
62 | /* XXX: probably some better way to do this */ | 62 | /* XXX: probably some better way to do this */ |
@@ -76,48 +76,44 @@ typedef struct { | |||
76 | 76 | ||
77 | /* N.B. The IV for this mode is _twice_ the block size */ | 77 | /* N.B. The IV for this mode is _twice_ the block size */ |
78 | 78 | ||
79 | void AES_ige_encrypt(const unsigned char *in, unsigned char *out, | 79 | void |
80 | size_t length, const AES_KEY *key, | 80 | AES_ige_encrypt(const unsigned char *in, unsigned char *out, size_t length, |
81 | unsigned char *ivec, const int enc) | 81 | const AES_KEY *key, unsigned char *ivec, const int enc) |
82 | { | 82 | { |
83 | size_t n; | 83 | size_t n; |
84 | size_t len = length; | 84 | size_t len = length; |
85 | 85 | ||
86 | OPENSSL_assert(in && out && key && ivec); | 86 | OPENSSL_assert(in && out && key && ivec); |
87 | OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc)); | 87 | OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc)); |
88 | OPENSSL_assert((length%AES_BLOCK_SIZE) == 0); | 88 | OPENSSL_assert((length % AES_BLOCK_SIZE) == 0); |
89 | 89 | ||
90 | len = length / AES_BLOCK_SIZE; | 90 | len = length / AES_BLOCK_SIZE; |
91 | 91 | ||
92 | if (AES_ENCRYPT == enc) | 92 | if (AES_ENCRYPT == enc) { |
93 | { | 93 | if (in != out && (UNALIGNED_MEMOPS_ARE_FAST || |
94 | if (in != out && | 94 | ((size_t)in|(size_t)out|(size_t)ivec) % |
95 | (UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0)) | 95 | sizeof(long) == 0)) { |
96 | { | ||
97 | aes_block_t *ivp = (aes_block_t *)ivec; | 96 | aes_block_t *ivp = (aes_block_t *)ivec; |
98 | aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE); | 97 | aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE); |
99 | 98 | ||
100 | while (len) | 99 | while (len) { |
101 | { | ||
102 | aes_block_t *inp = (aes_block_t *)in; | 100 | aes_block_t *inp = (aes_block_t *)in; |
103 | aes_block_t *outp = (aes_block_t *)out; | 101 | aes_block_t *outp = (aes_block_t *)out; |
104 | 102 | ||
105 | for(n=0 ; n < N_WORDS; ++n) | 103 | for (n = 0; n < N_WORDS; ++n) |
106 | outp->data[n] = inp->data[n] ^ ivp->data[n]; | 104 | outp->data[n] = inp->data[n] ^ ivp->data[n]; |
107 | AES_encrypt((unsigned char *)outp->data, (unsigned char *)outp->data, key); | 105 | AES_encrypt((unsigned char *)outp->data, (unsigned char *)outp->data, key); |
108 | for(n=0 ; n < N_WORDS; ++n) | 106 | for (n = 0; n < N_WORDS; ++n) |
109 | outp->data[n] ^= iv2p->data[n]; | 107 | outp->data[n] ^= iv2p->data[n]; |
110 | ivp = outp; | 108 | ivp = outp; |
111 | iv2p = inp; | 109 | iv2p = inp; |
112 | --len; | 110 | --len; |
113 | in += AES_BLOCK_SIZE; | 111 | in += AES_BLOCK_SIZE; |
114 | out += AES_BLOCK_SIZE; | 112 | out += AES_BLOCK_SIZE; |
115 | } | 113 | } |
116 | memcpy(ivec, ivp->data, AES_BLOCK_SIZE); | 114 | memcpy(ivec, ivp->data, AES_BLOCK_SIZE); |
117 | memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); | 115 | memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); |
118 | } | 116 | } else { |
119 | else | ||
120 | { | ||
121 | aes_block_t tmp, tmp2; | 117 | aes_block_t tmp, tmp2; |
122 | aes_block_t iv; | 118 | aes_block_t iv; |
123 | aes_block_t iv2; | 119 | aes_block_t iv2; |
@@ -125,13 +121,13 @@ void AES_ige_encrypt(const unsigned char *in, unsigned char *out, | |||
125 | load_block(iv, ivec); | 121 | load_block(iv, ivec); |
126 | load_block(iv2, ivec + AES_BLOCK_SIZE); | 122 | load_block(iv2, ivec + AES_BLOCK_SIZE); |
127 | 123 | ||
128 | while (len) | 124 | while (len) { |
129 | { | ||
130 | load_block(tmp, in); | 125 | load_block(tmp, in); |
131 | for(n=0 ; n < N_WORDS; ++n) | 126 | for (n = 0; n < N_WORDS; ++n) |
132 | tmp2.data[n] = tmp.data[n] ^ iv.data[n]; | 127 | tmp2.data[n] = tmp.data[n] ^ iv.data[n]; |
133 | AES_encrypt((unsigned char *)tmp2.data, (unsigned char *)tmp2.data, key); | 128 | AES_encrypt((unsigned char *)tmp2.data, |
134 | for(n=0 ; n < N_WORDS; ++n) | 129 | (unsigned char *)tmp2.data, key); |
130 | for (n = 0; n < N_WORDS; ++n) | ||
135 | tmp2.data[n] ^= iv2.data[n]; | 131 | tmp2.data[n] ^= iv2.data[n]; |
136 | store_block(out, tmp2); | 132 | store_block(out, tmp2); |
137 | iv = tmp2; | 133 | iv = tmp2; |
@@ -139,41 +135,37 @@ void AES_ige_encrypt(const unsigned char *in, unsigned char *out, | |||
139 | --len; | 135 | --len; |
140 | in += AES_BLOCK_SIZE; | 136 | in += AES_BLOCK_SIZE; |
141 | out += AES_BLOCK_SIZE; | 137 | out += AES_BLOCK_SIZE; |
142 | } | 138 | } |
143 | memcpy(ivec, iv.data, AES_BLOCK_SIZE); | 139 | memcpy(ivec, iv.data, AES_BLOCK_SIZE); |
144 | memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); | 140 | memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); |
145 | } | ||
146 | } | 141 | } |
147 | else | 142 | } else { |
148 | { | 143 | if (in != out && (UNALIGNED_MEMOPS_ARE_FAST || |
149 | if (in != out && | 144 | ((size_t)in|(size_t)out|(size_t)ivec) % |
150 | (UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0)) | 145 | sizeof(long) == 0)) { |
151 | { | ||
152 | aes_block_t *ivp = (aes_block_t *)ivec; | 146 | aes_block_t *ivp = (aes_block_t *)ivec; |
153 | aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE); | 147 | aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE); |
154 | 148 | ||
155 | while (len) | 149 | while (len) { |
156 | { | ||
157 | aes_block_t tmp; | 150 | aes_block_t tmp; |
158 | aes_block_t *inp = (aes_block_t *)in; | 151 | aes_block_t *inp = (aes_block_t *)in; |
159 | aes_block_t *outp = (aes_block_t *)out; | 152 | aes_block_t *outp = (aes_block_t *)out; |
160 | 153 | ||
161 | for(n=0 ; n < N_WORDS; ++n) | 154 | for (n = 0; n < N_WORDS; ++n) |
162 | tmp.data[n] = inp->data[n] ^ iv2p->data[n]; | 155 | tmp.data[n] = inp->data[n] ^ iv2p->data[n]; |
163 | AES_decrypt((unsigned char *)tmp.data, (unsigned char *)outp->data, key); | 156 | AES_decrypt((unsigned char *)tmp.data, |
164 | for(n=0 ; n < N_WORDS; ++n) | 157 | (unsigned char *)outp->data, key); |
158 | for (n = 0; n < N_WORDS; ++n) | ||
165 | outp->data[n] ^= ivp->data[n]; | 159 | outp->data[n] ^= ivp->data[n]; |
166 | ivp = inp; | 160 | ivp = inp; |
167 | iv2p = outp; | 161 | iv2p = outp; |
168 | --len; | 162 | --len; |
169 | in += AES_BLOCK_SIZE; | 163 | in += AES_BLOCK_SIZE; |
170 | out += AES_BLOCK_SIZE; | 164 | out += AES_BLOCK_SIZE; |
171 | } | 165 | } |
172 | memcpy(ivec, ivp->data, AES_BLOCK_SIZE); | 166 | memcpy(ivec, ivp->data, AES_BLOCK_SIZE); |
173 | memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); | 167 | memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); |
174 | } | 168 | } else { |
175 | else | ||
176 | { | ||
177 | aes_block_t tmp, tmp2; | 169 | aes_block_t tmp, tmp2; |
178 | aes_block_t iv; | 170 | aes_block_t iv; |
179 | aes_block_t iv2; | 171 | aes_block_t iv2; |
@@ -181,14 +173,14 @@ void AES_ige_encrypt(const unsigned char *in, unsigned char *out, | |||
181 | load_block(iv, ivec); | 173 | load_block(iv, ivec); |
182 | load_block(iv2, ivec + AES_BLOCK_SIZE); | 174 | load_block(iv2, ivec + AES_BLOCK_SIZE); |
183 | 175 | ||
184 | while (len) | 176 | while (len) { |
185 | { | ||
186 | load_block(tmp, in); | 177 | load_block(tmp, in); |
187 | tmp2 = tmp; | 178 | tmp2 = tmp; |
188 | for(n=0 ; n < N_WORDS; ++n) | 179 | for (n = 0; n < N_WORDS; ++n) |
189 | tmp.data[n] ^= iv2.data[n]; | 180 | tmp.data[n] ^= iv2.data[n]; |
190 | AES_decrypt((unsigned char *)tmp.data, (unsigned char *)tmp.data, key); | 181 | AES_decrypt((unsigned char *)tmp.data, |
191 | for(n=0 ; n < N_WORDS; ++n) | 182 | (unsigned char *)tmp.data, key); |
183 | for (n = 0; n < N_WORDS; ++n) | ||
192 | tmp.data[n] ^= iv.data[n]; | 184 | tmp.data[n] ^= iv.data[n]; |
193 | store_block(out, tmp); | 185 | store_block(out, tmp); |
194 | iv = tmp2; | 186 | iv = tmp2; |
@@ -196,12 +188,12 @@ void AES_ige_encrypt(const unsigned char *in, unsigned char *out, | |||
196 | --len; | 188 | --len; |
197 | in += AES_BLOCK_SIZE; | 189 | in += AES_BLOCK_SIZE; |
198 | out += AES_BLOCK_SIZE; | 190 | out += AES_BLOCK_SIZE; |
199 | } | 191 | } |
200 | memcpy(ivec, iv.data, AES_BLOCK_SIZE); | 192 | memcpy(ivec, iv.data, AES_BLOCK_SIZE); |
201 | memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); | 193 | memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); |
202 | } | ||
203 | } | 194 | } |
204 | } | 195 | } |
196 | } | ||
205 | 197 | ||
206 | /* | 198 | /* |
207 | * Note that its effectively impossible to do biIGE in anything other | 199 | * Note that its effectively impossible to do biIGE in anything other |
@@ -210,11 +202,11 @@ void AES_ige_encrypt(const unsigned char *in, unsigned char *out, | |||
210 | 202 | ||
211 | /* N.B. The IV for this mode is _four times_ the block size */ | 203 | /* N.B. The IV for this mode is _four times_ the block size */ |
212 | 204 | ||
213 | void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, | 205 | void |
214 | size_t length, const AES_KEY *key, | 206 | AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, size_t length, |
215 | const AES_KEY *key2, const unsigned char *ivec, | 207 | const AES_KEY *key, const AES_KEY *key2, const unsigned char *ivec, |
216 | const int enc) | 208 | const int enc) |
217 | { | 209 | { |
218 | size_t n; | 210 | size_t n; |
219 | size_t len = length; | 211 | size_t len = length; |
220 | unsigned char tmp[AES_BLOCK_SIZE]; | 212 | unsigned char tmp[AES_BLOCK_SIZE]; |
@@ -225,23 +217,21 @@ void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, | |||
225 | const unsigned char *iv2; | 217 | const unsigned char *iv2; |
226 | 218 | ||
227 | OPENSSL_assert(in && out && key && ivec); | 219 | OPENSSL_assert(in && out && key && ivec); |
228 | OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc)); | 220 | OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc)); |
229 | OPENSSL_assert((length%AES_BLOCK_SIZE) == 0); | 221 | OPENSSL_assert((length % AES_BLOCK_SIZE) == 0); |
230 | 222 | ||
231 | if (AES_ENCRYPT == enc) | 223 | if (AES_ENCRYPT == enc) { |
232 | { | ||
233 | /* XXX: Do a separate case for when in != out (strictly should | 224 | /* XXX: Do a separate case for when in != out (strictly should |
234 | check for overlap, too) */ | 225 | check for overlap, too) */ |
235 | 226 | ||
236 | /* First the forward pass */ | 227 | /* First the forward pass */ |
237 | iv = ivec; | 228 | iv = ivec; |
238 | iv2 = ivec + AES_BLOCK_SIZE; | 229 | iv2 = ivec + AES_BLOCK_SIZE; |
239 | while (len >= AES_BLOCK_SIZE) | 230 | while (len >= AES_BLOCK_SIZE) { |
240 | { | 231 | for (n = 0; n < AES_BLOCK_SIZE; ++n) |
241 | for(n=0 ; n < AES_BLOCK_SIZE ; ++n) | ||
242 | out[n] = in[n] ^ iv[n]; | 232 | out[n] = in[n] ^ iv[n]; |
243 | AES_encrypt(out, out, key); | 233 | AES_encrypt(out, out, key); |
244 | for(n=0 ; n < AES_BLOCK_SIZE ; ++n) | 234 | for (n = 0; n < AES_BLOCK_SIZE; ++n) |
245 | out[n] ^= iv2[n]; | 235 | out[n] ^= iv2[n]; |
246 | iv = out; | 236 | iv = out; |
247 | memcpy(prev, in, AES_BLOCK_SIZE); | 237 | memcpy(prev, in, AES_BLOCK_SIZE); |
@@ -249,68 +239,63 @@ void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, | |||
249 | len -= AES_BLOCK_SIZE; | 239 | len -= AES_BLOCK_SIZE; |
250 | in += AES_BLOCK_SIZE; | 240 | in += AES_BLOCK_SIZE; |
251 | out += AES_BLOCK_SIZE; | 241 | out += AES_BLOCK_SIZE; |
252 | } | 242 | } |
253 | 243 | ||
254 | /* And now backwards */ | 244 | /* And now backwards */ |
255 | iv = ivec + AES_BLOCK_SIZE*2; | 245 | iv = ivec + AES_BLOCK_SIZE*2; |
256 | iv2 = ivec + AES_BLOCK_SIZE*3; | 246 | iv2 = ivec + AES_BLOCK_SIZE*3; |
257 | len = length; | 247 | len = length; |
258 | while(len >= AES_BLOCK_SIZE) | 248 | while (len >= AES_BLOCK_SIZE) { |
259 | { | ||
260 | out -= AES_BLOCK_SIZE; | 249 | out -= AES_BLOCK_SIZE; |
261 | /* XXX: reduce copies by alternating between buffers */ | 250 | /* XXX: reduce copies by alternating between buffers */ |
262 | memcpy(tmp, out, AES_BLOCK_SIZE); | 251 | memcpy(tmp, out, AES_BLOCK_SIZE); |
263 | for(n=0 ; n < AES_BLOCK_SIZE ; ++n) | 252 | for (n = 0; n < AES_BLOCK_SIZE; ++n) |
264 | out[n] ^= iv[n]; | 253 | out[n] ^= iv[n]; |
265 | /* hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE); */ | 254 | /* hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE); */ |
266 | AES_encrypt(out, out, key); | 255 | AES_encrypt(out, out, key); |
267 | /* hexdump(stdout,"enc", out, AES_BLOCK_SIZE); */ | 256 | /* hexdump(stdout,"enc", out, AES_BLOCK_SIZE); */ |
268 | /* hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); */ | 257 | /* hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); */ |
269 | for(n=0 ; n < AES_BLOCK_SIZE ; ++n) | 258 | for (n = 0; n < AES_BLOCK_SIZE; ++n) |
270 | out[n] ^= iv2[n]; | 259 | out[n] ^= iv2[n]; |
271 | /* hexdump(stdout,"out", out, AES_BLOCK_SIZE); */ | 260 | /* hexdump(stdout,"out", out, AES_BLOCK_SIZE); */ |
272 | iv = out; | 261 | iv = out; |
273 | memcpy(prev, tmp, AES_BLOCK_SIZE); | 262 | memcpy(prev, tmp, AES_BLOCK_SIZE); |
274 | iv2 = prev; | 263 | iv2 = prev; |
275 | len -= AES_BLOCK_SIZE; | 264 | len -= AES_BLOCK_SIZE; |
276 | } | ||
277 | } | 265 | } |
278 | else | 266 | } else { |
279 | { | ||
280 | /* First backwards */ | 267 | /* First backwards */ |
281 | iv = ivec + AES_BLOCK_SIZE*2; | 268 | iv = ivec + AES_BLOCK_SIZE*2; |
282 | iv2 = ivec + AES_BLOCK_SIZE*3; | 269 | iv2 = ivec + AES_BLOCK_SIZE*3; |
283 | in += length; | 270 | in += length; |
284 | out += length; | 271 | out += length; |
285 | while (len >= AES_BLOCK_SIZE) | 272 | while (len >= AES_BLOCK_SIZE) { |
286 | { | ||
287 | in -= AES_BLOCK_SIZE; | 273 | in -= AES_BLOCK_SIZE; |
288 | out -= AES_BLOCK_SIZE; | 274 | out -= AES_BLOCK_SIZE; |
289 | memcpy(tmp, in, AES_BLOCK_SIZE); | 275 | memcpy(tmp, in, AES_BLOCK_SIZE); |
290 | memcpy(tmp2, in, AES_BLOCK_SIZE); | 276 | memcpy(tmp2, in, AES_BLOCK_SIZE); |
291 | for(n=0 ; n < AES_BLOCK_SIZE ; ++n) | 277 | for (n = 0; n < AES_BLOCK_SIZE; ++n) |
292 | tmp[n] ^= iv2[n]; | 278 | tmp[n] ^= iv2[n]; |
293 | AES_decrypt(tmp, out, key); | 279 | AES_decrypt(tmp, out, key); |
294 | for(n=0 ; n < AES_BLOCK_SIZE ; ++n) | 280 | for (n = 0; n < AES_BLOCK_SIZE; ++n) |
295 | out[n] ^= iv[n]; | 281 | out[n] ^= iv[n]; |
296 | memcpy(tmp3, tmp2, AES_BLOCK_SIZE); | 282 | memcpy(tmp3, tmp2, AES_BLOCK_SIZE); |
297 | iv = tmp3; | 283 | iv = tmp3; |
298 | iv2 = out; | 284 | iv2 = out; |
299 | len -= AES_BLOCK_SIZE; | 285 | len -= AES_BLOCK_SIZE; |
300 | } | 286 | } |
301 | 287 | ||
302 | /* And now forwards */ | 288 | /* And now forwards */ |
303 | iv = ivec; | 289 | iv = ivec; |
304 | iv2 = ivec + AES_BLOCK_SIZE; | 290 | iv2 = ivec + AES_BLOCK_SIZE; |
305 | len = length; | 291 | len = length; |
306 | while (len >= AES_BLOCK_SIZE) | 292 | while (len >= AES_BLOCK_SIZE) { |
307 | { | ||
308 | memcpy(tmp, out, AES_BLOCK_SIZE); | 293 | memcpy(tmp, out, AES_BLOCK_SIZE); |
309 | memcpy(tmp2, out, AES_BLOCK_SIZE); | 294 | memcpy(tmp2, out, AES_BLOCK_SIZE); |
310 | for(n=0 ; n < AES_BLOCK_SIZE ; ++n) | 295 | for (n = 0; n < AES_BLOCK_SIZE; ++n) |
311 | tmp[n] ^= iv2[n]; | 296 | tmp[n] ^= iv2[n]; |
312 | AES_decrypt(tmp, out, key); | 297 | AES_decrypt(tmp, out, key); |
313 | for(n=0 ; n < AES_BLOCK_SIZE ; ++n) | 298 | for (n = 0; n < AES_BLOCK_SIZE; ++n) |
314 | out[n] ^= iv[n]; | 299 | out[n] ^= iv[n]; |
315 | memcpy(tmp3, tmp2, AES_BLOCK_SIZE); | 300 | memcpy(tmp3, tmp2, AES_BLOCK_SIZE); |
316 | iv = tmp3; | 301 | iv = tmp3; |
@@ -318,6 +303,6 @@ void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, | |||
318 | len -= AES_BLOCK_SIZE; | 303 | len -= AES_BLOCK_SIZE; |
319 | in += AES_BLOCK_SIZE; | 304 | in += AES_BLOCK_SIZE; |
320 | out += AES_BLOCK_SIZE; | 305 | out += AES_BLOCK_SIZE; |
321 | } | ||
322 | } | 306 | } |
323 | } | 307 | } |
308 | } | ||