2 * Copyright (C) 2010-2015 Martin Willi
3 * Copyright (C) 2010-2015 revosec AG
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>.
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
16 #include "aesni_ccm.h"
17 #include "aesni_key.h"
19 #include <crypto/iv/iv_gen_seq.h>
21 #include <tmmintrin.h>
25 #define NONCE_SIZE (SALT_SIZE + IV_SIZE) /* 11 */
26 #define Q_SIZE (AES_BLOCK_SIZE - NONCE_SIZE - 1) /* 4 */
28 typedef struct private_aesni_ccm_t private_aesni_ccm_t
;
31 * CCM en/decryption method type
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
*);
37 * Private data of an aesni_ccm_t object.
39 struct private_aesni_ccm_t
{
42 * Public aesni_ccm_t interface.
47 * Encryption key schedule
57 * Length of the integrity check value
62 * Length of the key in bytes
67 * CCM encryption function
69 aesni_ccm_fn_t encrypt
;
72 * CCM decryption function
74 aesni_ccm_fn_t decrypt
;
77 * salt to add to nonce
79 u_char salt
[SALT_SIZE
];
83 * First block with control information
85 typedef struct __attribute__((packed
)) {
87 /* size of p length field q, as q-1 */
89 /* size of our ICV t, as (t-2)/2 */
91 /* do we have associated data */
96 struct __attribute__((packed
)) {
97 u_char salt
[SALT_SIZE
];
100 /* length of plain text, q */
107 typedef struct __attribute__((packed
)) {
109 /* size of p length field q, as q-1 */
115 struct __attribute__((packed
)) {
116 u_char salt
[SALT_SIZE
];
124 * Build the first block B0
126 static void build_b0(private_aesni_ccm_t
*this, size_t len
, size_t alen
,
127 u_char
*iv
, void *out
)
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
);
141 * Build a counter block for counter i
143 static void build_ctr(private_aesni_ccm_t
*this, u_int32_t i
, u_char
*iv
,
148 ctr
->flags
.reserved
= 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
);
157 * Calculate the ICV for the b0 and associated data
159 static __m128i
icv_header(private_aesni_ccm_t
*this, size_t len
, u_char
*iv
,
160 u_int16_t alen
, u_char
*assoc
)
162 __m128i
*ks
, b
, t
, c
;
163 u_int i
, round
, blocks
, rem
;
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
++)
171 c
= _mm_aesenc_si128(c
, ks
[round
]);
173 c
= _mm_aesenclast_si128(c
, ks
[this->key
->rounds
]);
177 blocks
= (alen
+ sizeof(alen
)) / AES_BLOCK_SIZE
;
178 rem
= (alen
+ sizeof(alen
)) % AES_BLOCK_SIZE
;
183 for (i
= 0; i
< blocks
; i
++)
187 memset(&b
, 0, sizeof(b
));
189 memcpy(((u_char
*)&b
) + sizeof(alen
), assoc
,
190 min(alen
, sizeof(b
) - sizeof(alen
)));
191 t
= _mm_loadu_si128(&b
);
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
);
201 t
= _mm_loadu_si128(((__m128i
*)(assoc
- sizeof(alen
))) + i
);
203 c
= _mm_xor_si128(t
, c
);
204 c
= _mm_xor_si128(c
, ks
[0]);
205 for (round
= 1; round
< this->key
->rounds
; round
++)
207 c
= _mm_aesenc_si128(c
, ks
[round
]);
209 c
= _mm_aesenclast_si128(c
, ks
[this->key
->rounds
]);
216 * En-/Decrypt the ICV, trim and store it
218 static void crypt_icv(private_aesni_ccm_t
*this, u_char
*iv
,
219 __m128i c
, u_char
*icv
)
224 ks
= this->key
->schedule
;
225 build_ctr(this, 0, iv
, &b
);
227 t
= _mm_loadu_si128(&b
);
228 t
= _mm_xor_si128(t
, ks
[0]);
229 for (round
= 1; round
< this->key
->rounds
; round
++)
231 t
= _mm_aesenc_si128(t
, ks
[round
]);
233 t
= _mm_aesenclast_si128(t
, ks
[this->key
->rounds
]);
235 t
= _mm_xor_si128(t
, c
);
237 _mm_storeu_si128(&b
, t
);
238 memcpy(icv
, &b
, this->icv_size
);
242 * Do big-endian increment on x
244 static inline __m128i
increment_be(__m128i x
)
248 swap
= _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
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
);
258 * Encrypt a remaining incomplete block
260 static __m128i
encrypt_ccm_rem(aesni_key_t
*key
, u_int rem
, __m128i state
,
261 void *in
, void *out
, __m128i c
)
263 __m128i
*ks
, t
, b
, d
;
267 memset(&b
, 0, sizeof(b
));
269 d
= _mm_loadu_si128(&b
);
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
++)
276 c
= _mm_aesenc_si128(c
, ks
[round
]);
277 t
= _mm_aesenc_si128(t
, ks
[round
]);
279 c
= _mm_aesenclast_si128(c
, ks
[key
->rounds
]);
280 t
= _mm_aesenclast_si128(t
, ks
[key
->rounds
]);
282 t
= _mm_xor_si128(t
, d
);
283 _mm_storeu_si128(&b
, t
);
285 memcpy(out
, &b
, rem
);
291 * Decrypt a remaining incomplete block
293 static __m128i
decrypt_ccm_rem(aesni_key_t
*key
, u_int rem
, __m128i state
,
294 void *in
, void *out
, __m128i c
)
296 __m128i
*ks
, t
, b
, d
;
300 memset(&b
, 0, sizeof(b
));
302 d
= _mm_loadu_si128(&b
);
304 t
= _mm_xor_si128(state
, ks
[0]);
305 for (round
= 1; round
< key
->rounds
; round
++)
307 t
= _mm_aesenc_si128(t
, ks
[round
]);
309 t
= _mm_aesenclast_si128(t
, ks
[key
->rounds
]);
310 t
= _mm_xor_si128(t
, d
);
311 _mm_storeu_si128(&b
, t
);
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
++)
319 c
= _mm_aesenc_si128(c
, ks
[round
]);
321 c
= _mm_aesenclast_si128(c
, ks
[key
->rounds
]);
323 memcpy(out
, &b
, rem
);
329 * AES-128 CCM encryption/ICV generation
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
)
335 __m128i
*ks
, d
, t
, c
, b
, state
, *bi
, *bo
;
336 u_int blocks
, rem
, i
;
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
;
346 ks
= this->key
->schedule
;
348 for (i
= 0; i
< blocks
; i
++)
350 d
= _mm_loadu_si128(bi
+ i
);
352 c
= _mm_xor_si128(d
, c
);
353 c
= _mm_xor_si128(c
, ks
[0]);
354 t
= _mm_xor_si128(state
, ks
[0]);
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]);
375 c
= _mm_aesenclast_si128(c
, ks
[10]);
376 t
= _mm_aesenclast_si128(t
, ks
[10]);
378 t
= _mm_xor_si128(t
, d
);
379 _mm_storeu_si128(bo
+ i
, t
);
381 state
= increment_be(state
);
386 c
= encrypt_ccm_rem(this->key
, rem
, state
, bi
+ blocks
, bo
+ blocks
, c
);
388 crypt_icv(this, iv
, c
, icv
);
392 * AES-128 CCM decryption/ICV generation
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
)
398 __m128i
*ks
, d
, t
, c
, b
, state
, *bi
, *bo
;
399 u_int blocks
, rem
, i
;
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
;
409 ks
= this->key
->schedule
;
411 for (i
= 0; i
< blocks
; i
++)
413 d
= _mm_loadu_si128(bi
+ i
);
415 t
= _mm_xor_si128(state
, ks
[0]);
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]);
427 t
= _mm_aesenclast_si128(t
, ks
[10]);
428 t
= _mm_xor_si128(t
, d
);
429 _mm_storeu_si128(bo
+ i
, t
);
431 c
= _mm_xor_si128(t
, c
);
432 c
= _mm_xor_si128(c
, ks
[0]);
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]);
444 c
= _mm_aesenclast_si128(c
, ks
[10]);
446 state
= increment_be(state
);
451 c
= decrypt_ccm_rem(this->key
, rem
, state
, bi
+ blocks
, bo
+ blocks
, c
);
453 crypt_icv(this, iv
, c
, icv
);
457 * AES-192 CCM encryption/ICV generation
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
)
463 __m128i
*ks
, d
, t
, c
, b
, state
, *bi
, *bo
;
464 u_int blocks
, rem
, i
;
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
;
474 ks
= this->key
->schedule
;
476 for (i
= 0; i
< blocks
; i
++)
478 d
= _mm_loadu_si128(bi
+ i
);
480 c
= _mm_xor_si128(d
, c
);
481 c
= _mm_xor_si128(c
, ks
[0]);
482 t
= _mm_xor_si128(state
, ks
[0]);
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]);
507 c
= _mm_aesenclast_si128(c
, ks
[12]);
508 t
= _mm_aesenclast_si128(t
, ks
[12]);
510 t
= _mm_xor_si128(t
, d
);
511 _mm_storeu_si128(bo
+ i
, t
);
513 state
= increment_be(state
);
518 c
= encrypt_ccm_rem(this->key
, rem
, state
, bi
+ blocks
, bo
+ blocks
, c
);
520 crypt_icv(this, iv
, c
, icv
);
524 * AES-192 CCM decryption/ICV generation
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
)
530 __m128i
*ks
, d
, t
, c
, b
, state
, *bi
, *bo
;
531 u_int blocks
, rem
, i
;
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
;
541 ks
= this->key
->schedule
;
543 for (i
= 0; i
< blocks
; i
++)
545 d
= _mm_loadu_si128(bi
+ i
);
547 t
= _mm_xor_si128(state
, ks
[0]);
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]);
561 t
= _mm_aesenclast_si128(t
, ks
[12]);
562 t
= _mm_xor_si128(t
, d
);
563 _mm_storeu_si128(bo
+ i
, t
);
565 c
= _mm_xor_si128(t
, c
);
566 c
= _mm_xor_si128(c
, ks
[0]);
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]);
580 c
= _mm_aesenclast_si128(c
, ks
[12]);
582 state
= increment_be(state
);
587 c
= decrypt_ccm_rem(this->key
, rem
, state
, bi
+ blocks
, bo
+ blocks
, c
);
589 crypt_icv(this, iv
, c
, icv
);
593 * AES-256 CCM encryption/ICV generation
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
)
599 __m128i
*ks
, d
, t
, c
, b
, state
, *bi
, *bo
;
600 u_int blocks
, rem
, i
;
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
;
610 ks
= this->key
->schedule
;
612 for (i
= 0; i
< blocks
; i
++)
614 d
= _mm_loadu_si128(bi
+ i
);
616 c
= _mm_xor_si128(d
, c
);
617 c
= _mm_xor_si128(c
, ks
[0]);
618 t
= _mm_xor_si128(state
, ks
[0]);
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]);
647 c
= _mm_aesenclast_si128(c
, ks
[14]);
648 t
= _mm_aesenclast_si128(t
, ks
[14]);
650 t
= _mm_xor_si128(t
, d
);
651 _mm_storeu_si128(bo
+ i
, t
);
653 state
= increment_be(state
);
658 c
= encrypt_ccm_rem(this->key
, rem
, state
, bi
+ blocks
, bo
+ blocks
, c
);
660 crypt_icv(this, iv
, c
, icv
);
664 * AES-256 CCM decryption/ICV generation
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
)
670 __m128i
*ks
, d
, t
, c
, b
, state
, *bi
, *bo
;
671 u_int blocks
, rem
, i
;
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
;
681 ks
= this->key
->schedule
;
683 for (i
= 0; i
< blocks
; i
++)
685 d
= _mm_loadu_si128(bi
+ i
);
687 t
= _mm_xor_si128(state
, ks
[0]);
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]);
703 t
= _mm_aesenclast_si128(t
, ks
[14]);
704 t
= _mm_xor_si128(t
, d
);
705 _mm_storeu_si128(bo
+ i
, t
);
707 c
= _mm_xor_si128(t
, c
);
708 c
= _mm_xor_si128(c
, ks
[0]);
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]);
724 c
= _mm_aesenclast_si128(c
, ks
[14]);
726 state
= increment_be(state
);
731 c
= decrypt_ccm_rem(this->key
, rem
, state
, bi
+ blocks
, bo
+ blocks
, c
);
733 crypt_icv(this, iv
, c
, icv
);
736 METHOD(aead_t
, encrypt
, bool,
737 private_aesni_ccm_t
*this, chunk_t plain
, chunk_t assoc
, chunk_t iv
,
742 if (!this->key
|| iv
.len
!= IV_SIZE
)
749 *encr
= chunk_alloc(plain
.len
+ this->icv_size
);
752 this->encrypt(this, plain
.len
, plain
.ptr
, out
, iv
.ptr
,
753 assoc
.len
, assoc
.ptr
, out
+ plain
.len
);
757 METHOD(aead_t
, decrypt
, bool,
758 private_aesni_ccm_t
*this, chunk_t encr
, chunk_t assoc
, chunk_t iv
,
761 u_char
*out
, icv
[this->icv_size
];
763 if (!this->key
|| iv
.len
!= IV_SIZE
|| encr
.len
< this->icv_size
)
767 encr
.len
-= this->icv_size
;
771 *plain
= chunk_alloc(encr
.len
);
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
);
780 METHOD(aead_t
, get_block_size
, size_t,
781 private_aesni_ccm_t
*this)
786 METHOD(aead_t
, get_icv_size
, size_t,
787 private_aesni_ccm_t
*this)
789 return this->icv_size
;
792 METHOD(aead_t
, get_iv_size
, size_t,
793 private_aesni_ccm_t
*this)
798 METHOD(aead_t
, get_iv_gen
, iv_gen_t
*,
799 private_aesni_ccm_t
*this)
804 METHOD(aead_t
, get_key_size
, size_t,
805 private_aesni_ccm_t
*this)
807 return this->key_size
+ SALT_SIZE
;
810 METHOD(aead_t
, set_key
, bool,
811 private_aesni_ccm_t
*this, chunk_t key
)
813 if (key
.len
!= this->key_size
+ SALT_SIZE
)
818 memcpy(this->salt
, key
.ptr
+ key
.len
- SALT_SIZE
, SALT_SIZE
);
819 key
.len
-= SALT_SIZE
;
821 DESTROY_IF(this->key
);
822 this->key
= aesni_key_create(TRUE
, key
);
826 METHOD(aead_t
, destroy
, void,
827 private_aesni_ccm_t
*this)
829 DESTROY_IF(this->key
);
830 this->iv_gen
->destroy(this->iv_gen
);
837 aesni_ccm_t
*aesni_ccm_create(encryption_algorithm_t algo
,
838 size_t key_size
, size_t salt_size
)
840 private_aesni_ccm_t
*this;
855 if (salt_size
&& salt_size
!= SALT_SIZE
)
857 /* currently not supported */
862 case ENCR_AES_CCM_ICV8
:
866 case ENCR_AES_CCM_ICV12
:
870 case ENCR_AES_CCM_ICV16
:
878 INIT_ALIGN(this, sizeof(__m128i
),
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
,
892 .key_size
= key_size
,
893 .iv_gen
= iv_gen_seq_create(),
894 .icv_size
= icv_size
,
900 this->encrypt
= encrypt_ccm128
;
901 this->decrypt
= decrypt_ccm128
;
904 this->encrypt
= encrypt_ccm192
;
905 this->decrypt
= decrypt_ccm192
;
908 this->encrypt
= encrypt_ccm256
;
909 this->decrypt
= decrypt_ccm256
;
913 return &this->public;