]> git.ipfire.org Git - people/ms/strongswan.git/blob - src/libstrongswan/plugins/aesni/aesni_ccm.c
aesni: Avoid loading AES/GHASH round keys into local variables
[people/ms/strongswan.git] / src / libstrongswan / plugins / aesni / aesni_ccm.c
1 /*
2 * Copyright (C) 2010-2015 Martin Willi
3 * Copyright (C) 2010-2015 revosec AG
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "aesni_ccm.h"
17 #include "aesni_key.h"
18
19 #include <crypto/iv/iv_gen_seq.h>
20
21 #include <tmmintrin.h>
22
23 #define SALT_SIZE 3
24 #define IV_SIZE 8
25 #define NONCE_SIZE (SALT_SIZE + IV_SIZE) /* 11 */
26 #define Q_SIZE (AES_BLOCK_SIZE - NONCE_SIZE - 1) /* 4 */
27
28 typedef struct private_aesni_ccm_t private_aesni_ccm_t;
29
30 /**
31 * CCM en/decryption method type
32 */
33 typedef void (*aesni_ccm_fn_t)(private_aesni_ccm_t*, size_t, u_char*, u_char*,
34 u_char*, size_t, u_char*, u_char*);
35
36 /**
37 * Private data of an aesni_ccm_t object.
38 */
39 struct private_aesni_ccm_t {
40
41 /**
42 * Public aesni_ccm_t interface.
43 */
44 aesni_ccm_t public;
45
46 /**
47 * Encryption key schedule
48 */
49 aesni_key_t *key;
50
51 /**
52 * IV generator.
53 */
54 iv_gen_t *iv_gen;
55
56 /**
57 * Length of the integrity check value
58 */
59 size_t icv_size;
60
61 /**
62 * Length of the key in bytes
63 */
64 size_t key_size;
65
66 /**
67 * CCM encryption function
68 */
69 aesni_ccm_fn_t encrypt;
70
71 /**
72 * CCM decryption function
73 */
74 aesni_ccm_fn_t decrypt;
75
76 /**
77 * salt to add to nonce
78 */
79 u_char salt[SALT_SIZE];
80 };
81
82 /**
83 * First block with control information
84 */
85 typedef struct __attribute__((packed)) {
86 BITFIELD4(u_int8_t,
87 /* size of p length field q, as q-1 */
88 q_len: 3,
89 /* size of our ICV t, as (t-2)/2 */
90 t_len: 3,
91 /* do we have associated data */
92 assoc: 1,
93 reserved: 1,
94 ) flags;
95 /* nonce value */
96 struct __attribute__((packed)) {
97 u_char salt[SALT_SIZE];
98 u_char iv[IV_SIZE];
99 } nonce;
100 /* length of plain text, q */
101 u_char q[Q_SIZE];
102 } b0_t;
103
104 /**
105 * Counter block
106 */
107 typedef struct __attribute__((packed)) {
108 BITFIELD3(u_int8_t,
109 /* size of p length field q, as q-1 */
110 q_len: 3,
111 zero: 3,
112 reserved: 2,
113 ) flags;
114 /* nonce value */
115 struct __attribute__((packed)) {
116 u_char salt[SALT_SIZE];
117 u_char iv[IV_SIZE];
118 } nonce;
119 /* counter value */
120 u_char i[Q_SIZE];
121 } ctr_t;
122
123 /**
124 * Build the first block B0
125 */
126 static void build_b0(private_aesni_ccm_t *this, size_t len, size_t alen,
127 u_char *iv, void *out)
128 {
129 b0_t *block = out;
130
131 block->flags.reserved = 0;
132 block->flags.assoc = alen ? 1 : 0;
133 block->flags.t_len = (this->icv_size - 2) / 2;
134 block->flags.q_len = Q_SIZE - 1;
135 memcpy(block->nonce.salt, this->salt, SALT_SIZE);
136 memcpy(block->nonce.iv, iv, IV_SIZE);
137 htoun32(block->q, len);
138 }
139
140 /**
141 * Build a counter block for counter i
142 */
143 static void build_ctr(private_aesni_ccm_t *this, u_int32_t i, u_char *iv,
144 void *out)
145 {
146 ctr_t *ctr = out;
147
148 ctr->flags.reserved = 0;
149 ctr->flags.zero = 0;
150 ctr->flags.q_len = Q_SIZE - 1;
151 memcpy(ctr->nonce.salt, this->salt, SALT_SIZE);
152 memcpy(ctr->nonce.iv, iv, IV_SIZE);
153 htoun32(ctr->i, i);
154 }
155
156 /**
157 * Calculate the ICV for the b0 and associated data
158 */
159 static __m128i icv_header(private_aesni_ccm_t *this, size_t len, u_char *iv,
160 u_int16_t alen, u_char *assoc)
161 {
162 __m128i *ks, b, t, c;
163 u_int i, round, blocks, rem;
164
165 ks = this->key->schedule;
166 build_b0(this, len, alen, iv, &b);
167 c = _mm_loadu_si128(&b);
168 c = _mm_xor_si128(c, ks[0]);
169 for (round = 1; round < this->key->rounds; round++)
170 {
171 c = _mm_aesenc_si128(c, ks[round]);
172 }
173 c = _mm_aesenclast_si128(c, ks[this->key->rounds]);
174
175 if (alen)
176 {
177 blocks = (alen + sizeof(alen)) / AES_BLOCK_SIZE;
178 rem = (alen + sizeof(alen)) % AES_BLOCK_SIZE;
179 if (rem)
180 {
181 blocks++;
182 }
183 for (i = 0; i < blocks; i++)
184 {
185 if (i == 0)
186 { /* first block */
187 memset(&b, 0, sizeof(b));
188 htoun16(&b, alen);
189 memcpy(((u_char*)&b) + sizeof(alen), assoc,
190 min(alen, sizeof(b) - sizeof(alen)));
191 t = _mm_loadu_si128(&b);
192 }
193 else if (i == blocks - 1 && rem)
194 { /* last block with padding */
195 memset(&b, 0, sizeof(b));
196 memcpy(&b, ((__m128i*)(assoc - sizeof(alen))) + i, rem);
197 t = _mm_loadu_si128(&b);
198 }
199 else
200 { /* full block */
201 t = _mm_loadu_si128(((__m128i*)(assoc - sizeof(alen))) + i);
202 }
203 c = _mm_xor_si128(t, c);
204 c = _mm_xor_si128(c, ks[0]);
205 for (round = 1; round < this->key->rounds; round++)
206 {
207 c = _mm_aesenc_si128(c, ks[round]);
208 }
209 c = _mm_aesenclast_si128(c, ks[this->key->rounds]);
210 }
211 }
212 return c;
213 }
214
215 /**
216 * En-/Decrypt the ICV, trim and store it
217 */
218 static void crypt_icv(private_aesni_ccm_t *this, u_char *iv,
219 __m128i c, u_char *icv)
220 {
221 __m128i *ks, b, t;
222 u_int round;
223
224 ks = this->key->schedule;
225 build_ctr(this, 0, iv, &b);
226
227 t = _mm_loadu_si128(&b);
228 t = _mm_xor_si128(t, ks[0]);
229 for (round = 1; round < this->key->rounds; round++)
230 {
231 t = _mm_aesenc_si128(t, ks[round]);
232 }
233 t = _mm_aesenclast_si128(t, ks[this->key->rounds]);
234
235 t = _mm_xor_si128(t, c);
236
237 _mm_storeu_si128(&b, t);
238 memcpy(icv, &b, this->icv_size);
239 }
240
241 /**
242 * Do big-endian increment on x
243 */
244 static inline __m128i increment_be(__m128i x)
245 {
246 __m128i swap;
247
248 swap = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
249
250 x = _mm_shuffle_epi8(x, swap);
251 x = _mm_add_epi64(x, _mm_set_epi32(0, 0, 0, 1));
252 x = _mm_shuffle_epi8(x, swap);
253
254 return x;
255 }
256
257 /**
258 * Encrypt a remaining incomplete block
259 */
260 static __m128i encrypt_ccm_rem(aesni_key_t *key, u_int rem, __m128i state,
261 void *in, void *out, __m128i c)
262 {
263 __m128i *ks, t, b, d;
264 u_int round;
265
266 ks = key->schedule;
267 memset(&b, 0, sizeof(b));
268 memcpy(&b, in, rem);
269 d = _mm_loadu_si128(&b);
270
271 c = _mm_xor_si128(d, c);
272 c = _mm_xor_si128(c, ks[0]);
273 t = _mm_xor_si128(state, ks[0]);
274 for (round = 1; round < key->rounds; round++)
275 {
276 c = _mm_aesenc_si128(c, ks[round]);
277 t = _mm_aesenc_si128(t, ks[round]);
278 }
279 c = _mm_aesenclast_si128(c, ks[key->rounds]);
280 t = _mm_aesenclast_si128(t, ks[key->rounds]);
281
282 t = _mm_xor_si128(t, d);
283 _mm_storeu_si128(&b, t);
284
285 memcpy(out, &b, rem);
286
287 return c;
288 }
289
290 /**
291 * Decrypt a remaining incomplete block
292 */
293 static __m128i decrypt_ccm_rem(aesni_key_t *key, u_int rem, __m128i state,
294 void *in, void *out, __m128i c)
295 {
296 __m128i *ks, t, b, d;
297 u_int round;
298
299 ks = key->schedule;
300 memset(&b, 0, sizeof(b));
301 memcpy(&b, in, rem);
302 d = _mm_loadu_si128(&b);
303
304 t = _mm_xor_si128(state, ks[0]);
305 for (round = 1; round < key->rounds; round++)
306 {
307 t = _mm_aesenc_si128(t, ks[round]);
308 }
309 t = _mm_aesenclast_si128(t, ks[key->rounds]);
310 t = _mm_xor_si128(t, d);
311 _mm_storeu_si128(&b, t);
312
313 memset((u_char*)&b + rem, 0, sizeof(b) - rem);
314 t = _mm_loadu_si128(&b);
315 c = _mm_xor_si128(t, c);
316 c = _mm_xor_si128(c, ks[0]);
317 for (round = 1; round < key->rounds; round++)
318 {
319 c = _mm_aesenc_si128(c, ks[round]);
320 }
321 c = _mm_aesenclast_si128(c, ks[key->rounds]);
322
323 memcpy(out, &b, rem);
324
325 return c;
326 }
327
328 /**
329 * AES-128 CCM encryption/ICV generation
330 */
331 static void encrypt_ccm128(private_aesni_ccm_t *this,
332 size_t len, u_char *in, u_char *out, u_char *iv,
333 size_t alen, u_char *assoc, u_char *icv)
334 {
335 __m128i *ks, d, t, c, b, state, *bi, *bo;
336 u_int blocks, rem, i;
337
338 c = icv_header(this, len, iv, alen, assoc);
339 build_ctr(this, 1, iv, &b);
340 state = _mm_load_si128(&b);
341 blocks = len / AES_BLOCK_SIZE;
342 rem = len % AES_BLOCK_SIZE;
343 bi = (__m128i*)in;
344 bo = (__m128i*)out;
345
346 ks = this->key->schedule;
347
348 for (i = 0; i < blocks; i++)
349 {
350 d = _mm_loadu_si128(bi + i);
351
352 c = _mm_xor_si128(d, c);
353 c = _mm_xor_si128(c, ks[0]);
354 t = _mm_xor_si128(state, ks[0]);
355
356 c = _mm_aesenc_si128(c, ks[1]);
357 t = _mm_aesenc_si128(t, ks[1]);
358 c = _mm_aesenc_si128(c, ks[2]);
359 t = _mm_aesenc_si128(t, ks[2]);
360 c = _mm_aesenc_si128(c, ks[3]);
361 t = _mm_aesenc_si128(t, ks[3]);
362 c = _mm_aesenc_si128(c, ks[4]);
363 t = _mm_aesenc_si128(t, ks[4]);
364 c = _mm_aesenc_si128(c, ks[5]);
365 t = _mm_aesenc_si128(t, ks[5]);
366 c = _mm_aesenc_si128(c, ks[6]);
367 t = _mm_aesenc_si128(t, ks[6]);
368 c = _mm_aesenc_si128(c, ks[7]);
369 t = _mm_aesenc_si128(t, ks[7]);
370 c = _mm_aesenc_si128(c, ks[8]);
371 t = _mm_aesenc_si128(t, ks[8]);
372 c = _mm_aesenc_si128(c, ks[9]);
373 t = _mm_aesenc_si128(t, ks[9]);
374
375 c = _mm_aesenclast_si128(c, ks[10]);
376 t = _mm_aesenclast_si128(t, ks[10]);
377
378 t = _mm_xor_si128(t, d);
379 _mm_storeu_si128(bo + i, t);
380
381 state = increment_be(state);
382 }
383
384 if (rem)
385 {
386 c = encrypt_ccm_rem(this->key, rem, state, bi + blocks, bo + blocks, c);
387 }
388 crypt_icv(this, iv, c, icv);
389 }
390
391 /**
392 * AES-128 CCM decryption/ICV generation
393 */
394 static void decrypt_ccm128(private_aesni_ccm_t *this,
395 size_t len, u_char *in, u_char *out, u_char *iv,
396 size_t alen, u_char *assoc, u_char *icv)
397 {
398 __m128i *ks, d, t, c, b, state, *bi, *bo;
399 u_int blocks, rem, i;
400
401 c = icv_header(this, len, iv, alen, assoc);
402 build_ctr(this, 1, iv, &b);
403 state = _mm_load_si128(&b);
404 blocks = len / AES_BLOCK_SIZE;
405 rem = len % AES_BLOCK_SIZE;
406 bi = (__m128i*)in;
407 bo = (__m128i*)out;
408
409 ks = this->key->schedule;
410
411 for (i = 0; i < blocks; i++)
412 {
413 d = _mm_loadu_si128(bi + i);
414
415 t = _mm_xor_si128(state, ks[0]);
416
417 t = _mm_aesenc_si128(t, ks[1]);
418 t = _mm_aesenc_si128(t, ks[2]);
419 t = _mm_aesenc_si128(t, ks[3]);
420 t = _mm_aesenc_si128(t, ks[4]);
421 t = _mm_aesenc_si128(t, ks[5]);
422 t = _mm_aesenc_si128(t, ks[6]);
423 t = _mm_aesenc_si128(t, ks[7]);
424 t = _mm_aesenc_si128(t, ks[8]);
425 t = _mm_aesenc_si128(t, ks[9]);
426
427 t = _mm_aesenclast_si128(t, ks[10]);
428 t = _mm_xor_si128(t, d);
429 _mm_storeu_si128(bo + i, t);
430
431 c = _mm_xor_si128(t, c);
432 c = _mm_xor_si128(c, ks[0]);
433
434 c = _mm_aesenc_si128(c, ks[1]);
435 c = _mm_aesenc_si128(c, ks[2]);
436 c = _mm_aesenc_si128(c, ks[3]);
437 c = _mm_aesenc_si128(c, ks[4]);
438 c = _mm_aesenc_si128(c, ks[5]);
439 c = _mm_aesenc_si128(c, ks[6]);
440 c = _mm_aesenc_si128(c, ks[7]);
441 c = _mm_aesenc_si128(c, ks[8]);
442 c = _mm_aesenc_si128(c, ks[9]);
443
444 c = _mm_aesenclast_si128(c, ks[10]);
445
446 state = increment_be(state);
447 }
448
449 if (rem)
450 {
451 c = decrypt_ccm_rem(this->key, rem, state, bi + blocks, bo + blocks, c);
452 }
453 crypt_icv(this, iv, c, icv);
454 }
455
456 /**
457 * AES-192 CCM encryption/ICV generation
458 */
459 static void encrypt_ccm192(private_aesni_ccm_t *this,
460 size_t len, u_char *in, u_char *out, u_char *iv,
461 size_t alen, u_char *assoc, u_char *icv)
462 {
463 __m128i *ks, d, t, c, b, state, *bi, *bo;
464 u_int blocks, rem, i;
465
466 c = icv_header(this, len, iv, alen, assoc);
467 build_ctr(this, 1, iv, &b);
468 state = _mm_load_si128(&b);
469 blocks = len / AES_BLOCK_SIZE;
470 rem = len % AES_BLOCK_SIZE;
471 bi = (__m128i*)in;
472 bo = (__m128i*)out;
473
474 ks = this->key->schedule;
475
476 for (i = 0; i < blocks; i++)
477 {
478 d = _mm_loadu_si128(bi + i);
479
480 c = _mm_xor_si128(d, c);
481 c = _mm_xor_si128(c, ks[0]);
482 t = _mm_xor_si128(state, ks[0]);
483
484 c = _mm_aesenc_si128(c, ks[1]);
485 t = _mm_aesenc_si128(t, ks[1]);
486 c = _mm_aesenc_si128(c, ks[2]);
487 t = _mm_aesenc_si128(t, ks[2]);
488 c = _mm_aesenc_si128(c, ks[3]);
489 t = _mm_aesenc_si128(t, ks[3]);
490 c = _mm_aesenc_si128(c, ks[4]);
491 t = _mm_aesenc_si128(t, ks[4]);
492 c = _mm_aesenc_si128(c, ks[5]);
493 t = _mm_aesenc_si128(t, ks[5]);
494 c = _mm_aesenc_si128(c, ks[6]);
495 t = _mm_aesenc_si128(t, ks[6]);
496 c = _mm_aesenc_si128(c, ks[7]);
497 t = _mm_aesenc_si128(t, ks[7]);
498 c = _mm_aesenc_si128(c, ks[8]);
499 t = _mm_aesenc_si128(t, ks[8]);
500 c = _mm_aesenc_si128(c, ks[9]);
501 t = _mm_aesenc_si128(t, ks[9]);
502 c = _mm_aesenc_si128(c, ks[10]);
503 t = _mm_aesenc_si128(t, ks[10]);
504 c = _mm_aesenc_si128(c, ks[11]);
505 t = _mm_aesenc_si128(t, ks[11]);
506
507 c = _mm_aesenclast_si128(c, ks[12]);
508 t = _mm_aesenclast_si128(t, ks[12]);
509
510 t = _mm_xor_si128(t, d);
511 _mm_storeu_si128(bo + i, t);
512
513 state = increment_be(state);
514 }
515
516 if (rem)
517 {
518 c = encrypt_ccm_rem(this->key, rem, state, bi + blocks, bo + blocks, c);
519 }
520 crypt_icv(this, iv, c, icv);
521 }
522
523 /**
524 * AES-192 CCM decryption/ICV generation
525 */
526 static void decrypt_ccm192(private_aesni_ccm_t *this,
527 size_t len, u_char *in, u_char *out, u_char *iv,
528 size_t alen, u_char *assoc, u_char *icv)
529 {
530 __m128i *ks, d, t, c, b, state, *bi, *bo;
531 u_int blocks, rem, i;
532
533 c = icv_header(this, len, iv, alen, assoc);
534 build_ctr(this, 1, iv, &b);
535 state = _mm_load_si128(&b);
536 blocks = len / AES_BLOCK_SIZE;
537 rem = len % AES_BLOCK_SIZE;
538 bi = (__m128i*)in;
539 bo = (__m128i*)out;
540
541 ks = this->key->schedule;
542
543 for (i = 0; i < blocks; i++)
544 {
545 d = _mm_loadu_si128(bi + i);
546
547 t = _mm_xor_si128(state, ks[0]);
548
549 t = _mm_aesenc_si128(t, ks[1]);
550 t = _mm_aesenc_si128(t, ks[2]);
551 t = _mm_aesenc_si128(t, ks[3]);
552 t = _mm_aesenc_si128(t, ks[4]);
553 t = _mm_aesenc_si128(t, ks[5]);
554 t = _mm_aesenc_si128(t, ks[6]);
555 t = _mm_aesenc_si128(t, ks[7]);
556 t = _mm_aesenc_si128(t, ks[8]);
557 t = _mm_aesenc_si128(t, ks[9]);
558 t = _mm_aesenc_si128(t, ks[10]);
559 t = _mm_aesenc_si128(t, ks[11]);
560
561 t = _mm_aesenclast_si128(t, ks[12]);
562 t = _mm_xor_si128(t, d);
563 _mm_storeu_si128(bo + i, t);
564
565 c = _mm_xor_si128(t, c);
566 c = _mm_xor_si128(c, ks[0]);
567
568 c = _mm_aesenc_si128(c, ks[1]);
569 c = _mm_aesenc_si128(c, ks[2]);
570 c = _mm_aesenc_si128(c, ks[3]);
571 c = _mm_aesenc_si128(c, ks[4]);
572 c = _mm_aesenc_si128(c, ks[5]);
573 c = _mm_aesenc_si128(c, ks[6]);
574 c = _mm_aesenc_si128(c, ks[7]);
575 c = _mm_aesenc_si128(c, ks[8]);
576 c = _mm_aesenc_si128(c, ks[9]);
577 c = _mm_aesenc_si128(c, ks[10]);
578 c = _mm_aesenc_si128(c, ks[11]);
579
580 c = _mm_aesenclast_si128(c, ks[12]);
581
582 state = increment_be(state);
583 }
584
585 if (rem)
586 {
587 c = decrypt_ccm_rem(this->key, rem, state, bi + blocks, bo + blocks, c);
588 }
589 crypt_icv(this, iv, c, icv);
590 }
591
592 /**
593 * AES-256 CCM encryption/ICV generation
594 */
595 static void encrypt_ccm256(private_aesni_ccm_t *this,
596 size_t len, u_char *in, u_char *out, u_char *iv,
597 size_t alen, u_char *assoc, u_char *icv)
598 {
599 __m128i *ks, d, t, c, b, state, *bi, *bo;
600 u_int blocks, rem, i;
601
602 c = icv_header(this, len, iv, alen, assoc);
603 build_ctr(this, 1, iv, &b);
604 state = _mm_load_si128(&b);
605 blocks = len / AES_BLOCK_SIZE;
606 rem = len % AES_BLOCK_SIZE;
607 bi = (__m128i*)in;
608 bo = (__m128i*)out;
609
610 ks = this->key->schedule;
611
612 for (i = 0; i < blocks; i++)
613 {
614 d = _mm_loadu_si128(bi + i);
615
616 c = _mm_xor_si128(d, c);
617 c = _mm_xor_si128(c, ks[0]);
618 t = _mm_xor_si128(state, ks[0]);
619
620 c = _mm_aesenc_si128(c, ks[1]);
621 t = _mm_aesenc_si128(t, ks[1]);
622 c = _mm_aesenc_si128(c, ks[2]);
623 t = _mm_aesenc_si128(t, ks[2]);
624 c = _mm_aesenc_si128(c, ks[3]);
625 t = _mm_aesenc_si128(t, ks[3]);
626 c = _mm_aesenc_si128(c, ks[4]);
627 t = _mm_aesenc_si128(t, ks[4]);
628 c = _mm_aesenc_si128(c, ks[5]);
629 t = _mm_aesenc_si128(t, ks[5]);
630 c = _mm_aesenc_si128(c, ks[6]);
631 t = _mm_aesenc_si128(t, ks[6]);
632 c = _mm_aesenc_si128(c, ks[7]);
633 t = _mm_aesenc_si128(t, ks[7]);
634 c = _mm_aesenc_si128(c, ks[8]);
635 t = _mm_aesenc_si128(t, ks[8]);
636 c = _mm_aesenc_si128(c, ks[9]);
637 t = _mm_aesenc_si128(t, ks[9]);
638 c = _mm_aesenc_si128(c, ks[10]);
639 t = _mm_aesenc_si128(t, ks[10]);
640 c = _mm_aesenc_si128(c, ks[11]);
641 t = _mm_aesenc_si128(t, ks[11]);
642 c = _mm_aesenc_si128(c, ks[12]);
643 t = _mm_aesenc_si128(t, ks[12]);
644 c = _mm_aesenc_si128(c, ks[13]);
645 t = _mm_aesenc_si128(t, ks[13]);
646
647 c = _mm_aesenclast_si128(c, ks[14]);
648 t = _mm_aesenclast_si128(t, ks[14]);
649
650 t = _mm_xor_si128(t, d);
651 _mm_storeu_si128(bo + i, t);
652
653 state = increment_be(state);
654 }
655
656 if (rem)
657 {
658 c = encrypt_ccm_rem(this->key, rem, state, bi + blocks, bo + blocks, c);
659 }
660 crypt_icv(this, iv, c, icv);
661 }
662
663 /**
664 * AES-256 CCM decryption/ICV generation
665 */
666 static void decrypt_ccm256(private_aesni_ccm_t *this,
667 size_t len, u_char *in, u_char *out, u_char *iv,
668 size_t alen, u_char *assoc, u_char *icv)
669 {
670 __m128i *ks, d, t, c, b, state, *bi, *bo;
671 u_int blocks, rem, i;
672
673 c = icv_header(this, len, iv, alen, assoc);
674 build_ctr(this, 1, iv, &b);
675 state = _mm_load_si128(&b);
676 blocks = len / AES_BLOCK_SIZE;
677 rem = len % AES_BLOCK_SIZE;
678 bi = (__m128i*)in;
679 bo = (__m128i*)out;
680
681 ks = this->key->schedule;
682
683 for (i = 0; i < blocks; i++)
684 {
685 d = _mm_loadu_si128(bi + i);
686
687 t = _mm_xor_si128(state, ks[0]);
688
689 t = _mm_aesenc_si128(t, ks[1]);
690 t = _mm_aesenc_si128(t, ks[2]);
691 t = _mm_aesenc_si128(t, ks[3]);
692 t = _mm_aesenc_si128(t, ks[4]);
693 t = _mm_aesenc_si128(t, ks[5]);
694 t = _mm_aesenc_si128(t, ks[6]);
695 t = _mm_aesenc_si128(t, ks[7]);
696 t = _mm_aesenc_si128(t, ks[8]);
697 t = _mm_aesenc_si128(t, ks[9]);
698 t = _mm_aesenc_si128(t, ks[10]);
699 t = _mm_aesenc_si128(t, ks[11]);
700 t = _mm_aesenc_si128(t, ks[12]);
701 t = _mm_aesenc_si128(t, ks[13]);
702
703 t = _mm_aesenclast_si128(t, ks[14]);
704 t = _mm_xor_si128(t, d);
705 _mm_storeu_si128(bo + i, t);
706
707 c = _mm_xor_si128(t, c);
708 c = _mm_xor_si128(c, ks[0]);
709
710 c = _mm_aesenc_si128(c, ks[1]);
711 c = _mm_aesenc_si128(c, ks[2]);
712 c = _mm_aesenc_si128(c, ks[3]);
713 c = _mm_aesenc_si128(c, ks[4]);
714 c = _mm_aesenc_si128(c, ks[5]);
715 c = _mm_aesenc_si128(c, ks[6]);
716 c = _mm_aesenc_si128(c, ks[7]);
717 c = _mm_aesenc_si128(c, ks[8]);
718 c = _mm_aesenc_si128(c, ks[9]);
719 c = _mm_aesenc_si128(c, ks[10]);
720 c = _mm_aesenc_si128(c, ks[11]);
721 c = _mm_aesenc_si128(c, ks[12]);
722 c = _mm_aesenc_si128(c, ks[13]);
723
724 c = _mm_aesenclast_si128(c, ks[14]);
725
726 state = increment_be(state);
727 }
728
729 if (rem)
730 {
731 c = decrypt_ccm_rem(this->key, rem, state, bi + blocks, bo + blocks, c);
732 }
733 crypt_icv(this, iv, c, icv);
734 }
735
736 METHOD(aead_t, encrypt, bool,
737 private_aesni_ccm_t *this, chunk_t plain, chunk_t assoc, chunk_t iv,
738 chunk_t *encr)
739 {
740 u_char *out;
741
742 if (!this->key || iv.len != IV_SIZE)
743 {
744 return FALSE;
745 }
746 out = plain.ptr;
747 if (encr)
748 {
749 *encr = chunk_alloc(plain.len + this->icv_size);
750 out = encr->ptr;
751 }
752 this->encrypt(this, plain.len, plain.ptr, out, iv.ptr,
753 assoc.len, assoc.ptr, out + plain.len);
754 return TRUE;
755 }
756
757 METHOD(aead_t, decrypt, bool,
758 private_aesni_ccm_t *this, chunk_t encr, chunk_t assoc, chunk_t iv,
759 chunk_t *plain)
760 {
761 u_char *out, icv[this->icv_size];
762
763 if (!this->key || iv.len != IV_SIZE || encr.len < this->icv_size)
764 {
765 return FALSE;
766 }
767 encr.len -= this->icv_size;
768 out = encr.ptr;
769 if (plain)
770 {
771 *plain = chunk_alloc(encr.len);
772 out = plain->ptr;
773 }
774
775 this->decrypt(this, encr.len, encr.ptr, out, iv.ptr,
776 assoc.len, assoc.ptr, icv);
777 return memeq_const(icv, encr.ptr + encr.len, this->icv_size);
778 }
779
780 METHOD(aead_t, get_block_size, size_t,
781 private_aesni_ccm_t *this)
782 {
783 return 1;
784 }
785
786 METHOD(aead_t, get_icv_size, size_t,
787 private_aesni_ccm_t *this)
788 {
789 return this->icv_size;
790 }
791
792 METHOD(aead_t, get_iv_size, size_t,
793 private_aesni_ccm_t *this)
794 {
795 return IV_SIZE;
796 }
797
798 METHOD(aead_t, get_iv_gen, iv_gen_t*,
799 private_aesni_ccm_t *this)
800 {
801 return this->iv_gen;
802 }
803
804 METHOD(aead_t, get_key_size, size_t,
805 private_aesni_ccm_t *this)
806 {
807 return this->key_size + SALT_SIZE;
808 }
809
810 METHOD(aead_t, set_key, bool,
811 private_aesni_ccm_t *this, chunk_t key)
812 {
813 if (key.len != this->key_size + SALT_SIZE)
814 {
815 return FALSE;
816 }
817
818 memcpy(this->salt, key.ptr + key.len - SALT_SIZE, SALT_SIZE);
819 key.len -= SALT_SIZE;
820
821 DESTROY_IF(this->key);
822 this->key = aesni_key_create(TRUE, key);
823 return TRUE;
824 }
825
826 METHOD(aead_t, destroy, void,
827 private_aesni_ccm_t *this)
828 {
829 DESTROY_IF(this->key);
830 this->iv_gen->destroy(this->iv_gen);
831 free_align(this);
832 }
833
834 /**
835 * See header
836 */
837 aesni_ccm_t *aesni_ccm_create(encryption_algorithm_t algo,
838 size_t key_size, size_t salt_size)
839 {
840 private_aesni_ccm_t *this;
841 size_t icv_size;
842
843 switch (key_size)
844 {
845 case 0:
846 key_size = 16;
847 break;
848 case 16:
849 case 24:
850 case 32:
851 break;
852 default:
853 return NULL;
854 }
855 if (salt_size && salt_size != SALT_SIZE)
856 {
857 /* currently not supported */
858 return NULL;
859 }
860 switch (algo)
861 {
862 case ENCR_AES_CCM_ICV8:
863 algo = ENCR_AES_CBC;
864 icv_size = 8;
865 break;
866 case ENCR_AES_CCM_ICV12:
867 algo = ENCR_AES_CBC;
868 icv_size = 12;
869 break;
870 case ENCR_AES_CCM_ICV16:
871 algo = ENCR_AES_CBC;
872 icv_size = 16;
873 break;
874 default:
875 return NULL;
876 }
877
878 INIT_ALIGN(this, sizeof(__m128i),
879 .public = {
880 .aead = {
881 .encrypt = _encrypt,
882 .decrypt = _decrypt,
883 .get_block_size = _get_block_size,
884 .get_icv_size = _get_icv_size,
885 .get_iv_size = _get_iv_size,
886 .get_iv_gen = _get_iv_gen,
887 .get_key_size = _get_key_size,
888 .set_key = _set_key,
889 .destroy = _destroy,
890 },
891 },
892 .key_size = key_size,
893 .iv_gen = iv_gen_seq_create(),
894 .icv_size = icv_size,
895 );
896
897 switch (key_size)
898 {
899 case 16:
900 this->encrypt = encrypt_ccm128;
901 this->decrypt = decrypt_ccm128;
902 break;
903 case 24:
904 this->encrypt = encrypt_ccm192;
905 this->decrypt = decrypt_ccm192;
906 break;
907 case 32:
908 this->encrypt = encrypt_ccm256;
909 this->decrypt = decrypt_ccm256;
910 break;
911 }
912
913 return &this->public;
914 }