2 * Copyright (C) 2015 Martin Willi
3 * Copyright (C) 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_gcm.h"
17 #include "aesni_key.h"
19 #include <crypto/iv/iv_gen_seq.h>
21 #include <tmmintrin.h>
25 #define SALT_SIZE (NONCE_SIZE - IV_SIZE)
27 typedef struct private_aesni_gcm_t private_aesni_gcm_t
;
30 * GCM en/decryption method type
32 typedef void (*aesni_gcm_fn_t
)(private_aesni_gcm_t
*, size_t, u_char
*, u_char
*,
33 u_char
*, size_t, u_char
*, u_char
*);
36 * Private data of an aesni_gcm_t object.
38 struct private_aesni_gcm_t
{
41 * Public aesni_gcm_t interface.
46 * Encryption key schedule
56 * Length of the integrity check value
61 * Length of the key in bytes
66 * GCM encryption function
68 aesni_gcm_fn_t encrypt
;
71 * GCM decryption function
73 aesni_gcm_fn_t decrypt
;
76 * salt to add to nonce
78 u_char salt
[SALT_SIZE
];
81 * GHASH subkey H, big-endian
87 * Byte-swap a 128-bit integer
89 static inline __m128i
swap128(__m128i x
)
91 return _mm_shuffle_epi8(x
,
92 _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15));
96 * Multiply two blocks in GF128
98 static inline __m128i
mult_block(__m128i h
, __m128i y
)
100 __m128i t1
, t2
, t3
, t4
, t5
, t6
;
104 t1
= _mm_clmulepi64_si128(h
, y
, 0x00);
105 t2
= _mm_clmulepi64_si128(h
, y
, 0x01);
106 t3
= _mm_clmulepi64_si128(h
, y
, 0x10);
107 t4
= _mm_clmulepi64_si128(h
, y
, 0x11);
109 t2
= _mm_xor_si128(t2
, t3
);
110 t3
= _mm_slli_si128(t2
, 8);
111 t2
= _mm_srli_si128(t2
, 8);
112 t1
= _mm_xor_si128(t1
, t3
);
113 t4
= _mm_xor_si128(t4
, t2
);
115 t5
= _mm_srli_epi32(t1
, 31);
116 t1
= _mm_slli_epi32(t1
, 1);
117 t6
= _mm_srli_epi32(t4
, 31);
118 t4
= _mm_slli_epi32(t4
, 1);
120 t3
= _mm_srli_si128(t5
, 12);
121 t6
= _mm_slli_si128(t6
, 4);
122 t5
= _mm_slli_si128(t5
, 4);
123 t1
= _mm_or_si128(t1
, t5
);
124 t4
= _mm_or_si128(t4
, t6
);
125 t4
= _mm_or_si128(t4
, t3
);
127 t5
= _mm_slli_epi32(t1
, 31);
128 t6
= _mm_slli_epi32(t1
, 30);
129 t3
= _mm_slli_epi32(t1
, 25);
131 t5
= _mm_xor_si128(t5
, t6
);
132 t5
= _mm_xor_si128(t5
, t3
);
133 t6
= _mm_srli_si128(t5
, 4);
134 t4
= _mm_xor_si128(t4
, t6
);
135 t5
= _mm_slli_si128(t5
, 12);
136 t1
= _mm_xor_si128(t1
, t5
);
137 t4
= _mm_xor_si128(t4
, t1
);
139 t5
= _mm_srli_epi32(t1
, 1);
140 t2
= _mm_srli_epi32(t1
, 2);
141 t3
= _mm_srli_epi32(t1
, 7);
142 t4
= _mm_xor_si128(t4
, t2
);
143 t4
= _mm_xor_si128(t4
, t3
);
144 t4
= _mm_xor_si128(t4
, t5
);
150 * GHASH on a single block
152 static __m128i
ghash(__m128i h
, __m128i y
, __m128i x
)
154 return mult_block(h
, _mm_xor_si128(y
, x
));
158 * Start constructing the ICV for the associated data
160 static __m128i
icv_header(private_aesni_gcm_t
*this, void *assoc
, size_t alen
)
162 u_int blocks
, rem
, i
;
163 __m128i y
, last
, *ab
;
165 y
= _mm_setzero_si128();
167 blocks
= alen
/ AES_BLOCK_SIZE
;
168 rem
= alen
% AES_BLOCK_SIZE
;
169 for (i
= 0; i
< blocks
; i
++)
171 y
= ghash(this->h
, y
, _mm_loadu_si128(ab
+ i
));
175 last
= _mm_setzero_si128();
176 memcpy(&last
, ab
+ blocks
, rem
);
178 y
= ghash(this->h
, y
, last
);
185 * Complete the ICV by hashing a assoc/data length block
187 static __m128i
icv_tailer(private_aesni_gcm_t
*this, __m128i y
,
188 size_t alen
, size_t dlen
)
192 htoun64(&b
, alen
* 8);
193 htoun64((u_char
*)&b
+ sizeof(u_int64_t
), dlen
* 8);
195 return ghash(this->h
, y
, b
);
199 * En-/Decrypt the ICV, trim and store it
201 static void icv_crypt(private_aesni_gcm_t
*this, __m128i y
, __m128i j
,
207 t
= _mm_xor_si128(j
, this->key
->schedule
[0]);
208 for (round
= 1; round
< this->key
->rounds
; round
++)
210 t
= _mm_aesenc_si128(t
, this->key
->schedule
[round
]);
212 t
= _mm_aesenclast_si128(t
, this->key
->schedule
[this->key
->rounds
]);
214 t
= _mm_xor_si128(y
, t
);
216 _mm_storeu_si128(&b
, t
);
217 memcpy(icv
, &b
, this->icv_size
);
221 * Do big-endian increment on x
223 static inline __m128i
increment_be(__m128i x
)
226 x
= _mm_add_epi64(x
, _mm_set_epi32(0, 0, 0, 1));
233 * Generate the block J0
235 static inline __m128i
create_j(private_aesni_gcm_t
*this, u_char
*iv
)
237 u_char j
[AES_BLOCK_SIZE
];
239 memcpy(j
, this->salt
, SALT_SIZE
);
240 memcpy(j
+ SALT_SIZE
, iv
, IV_SIZE
);
241 htoun32(j
+ SALT_SIZE
+ IV_SIZE
, 1);
243 return _mm_loadu_si128((__m128i
*)j
);
247 * Encrypt a remaining incomplete block, return updated Y
249 static __m128i
encrypt_gcm_rem(private_aesni_gcm_t
*this, u_int rem
,
250 void *in
, void *out
, __m128i cb
, __m128i y
)
255 memset(&b
, 0, sizeof(b
));
258 t
= _mm_xor_si128(cb
, this->key
->schedule
[0]);
259 for (round
= 1; round
< this->key
->rounds
; round
++)
261 t
= _mm_aesenc_si128(t
, this->key
->schedule
[round
]);
263 t
= _mm_aesenclast_si128(t
, this->key
->schedule
[this->key
->rounds
]);
264 b
= _mm_xor_si128(t
, b
);
266 memcpy(out
, &b
, rem
);
268 memset((u_char
*)&b
+ rem
, 0, AES_BLOCK_SIZE
- rem
);
269 return ghash(this->h
, y
, b
);
273 * Decrypt a remaining incomplete block, return updated Y
275 static __m128i
decrypt_gcm_rem(private_aesni_gcm_t
*this, u_int rem
,
276 void *in
, void *out
, __m128i cb
, __m128i y
)
281 memset(&b
, 0, sizeof(b
));
284 y
= ghash(this->h
, y
, b
);
286 t
= _mm_xor_si128(cb
, this->key
->schedule
[0]);
287 for (round
= 1; round
< this->key
->rounds
; round
++)
289 t
= _mm_aesenc_si128(t
, this->key
->schedule
[round
]);
291 t
= _mm_aesenclast_si128(t
, this->key
->schedule
[this->key
->rounds
]);
292 b
= _mm_xor_si128(t
, b
);
294 memcpy(out
, &b
, rem
);
300 * Generic GCM encryption/ICV generation
302 static void encrypt_gcm(private_aesni_gcm_t
*this,
303 size_t len
, u_char
*in
, u_char
*out
, u_char
*iv
,
304 size_t alen
, u_char
*assoc
, u_char
*icv
)
306 __m128i d
, t
, y
, j
, cb
, *bi
, *bo
;
307 u_int round
, blocks
, rem
, i
;
309 j
= create_j(this, iv
);
310 y
= icv_header(this, assoc
, alen
);
311 blocks
= len
/ AES_BLOCK_SIZE
;
312 rem
= len
% AES_BLOCK_SIZE
;
316 cb
= increment_be(j
);
317 for (i
= 0; i
< blocks
; i
++)
319 d
= _mm_loadu_si128(bi
+ i
);
320 t
= _mm_xor_si128(cb
, this->key
->schedule
[0]);
321 for (round
= 1; round
< this->key
->rounds
; round
++)
323 t
= _mm_aesenc_si128(t
, this->key
->schedule
[round
]);
325 t
= _mm_aesenclast_si128(t
, this->key
->schedule
[this->key
->rounds
]);
326 t
= _mm_xor_si128(t
, d
);
327 _mm_storeu_si128(bo
+ i
, t
);
329 y
= ghash(this->h
, y
, t
);
331 cb
= increment_be(cb
);
336 y
= encrypt_gcm_rem(this, rem
, bi
+ blocks
, bo
+ blocks
, cb
, y
);
338 y
= icv_tailer(this, y
, alen
, len
);
339 icv_crypt(this, y
, j
, icv
);
343 * Generic GCM decryption/ICV generation
345 static void decrypt_gcm(private_aesni_gcm_t
*this,
346 size_t len
, u_char
*in
, u_char
*out
, u_char
*iv
,
347 size_t alen
, u_char
*assoc
, u_char
*icv
)
349 __m128i d
, t
, y
, j
, cb
, *bi
, *bo
;
350 u_int round
, blocks
, rem
, i
;
352 j
= create_j(this, iv
);
353 y
= icv_header(this, assoc
, alen
);
354 blocks
= len
/ AES_BLOCK_SIZE
;
355 rem
= len
% AES_BLOCK_SIZE
;
359 cb
= increment_be(j
);
360 for (i
= 0; i
< blocks
; i
++)
362 d
= _mm_loadu_si128(bi
+ i
);
364 y
= ghash(this->h
, y
, d
);
366 t
= _mm_xor_si128(cb
, this->key
->schedule
[0]);
367 for (round
= 1; round
< this->key
->rounds
; round
++)
369 t
= _mm_aesenc_si128(t
, this->key
->schedule
[round
]);
371 t
= _mm_aesenclast_si128(t
, this->key
->schedule
[this->key
->rounds
]);
372 t
= _mm_xor_si128(t
, d
);
373 _mm_storeu_si128(bo
+ i
, t
);
375 cb
= increment_be(cb
);
380 y
= decrypt_gcm_rem(this, rem
, bi
+ blocks
, bo
+ blocks
, cb
, y
);
382 y
= icv_tailer(this, y
, alen
, len
);
383 icv_crypt(this, y
, j
, icv
);
386 METHOD(aead_t
, encrypt
, bool,
387 private_aesni_gcm_t
*this, chunk_t plain
, chunk_t assoc
, chunk_t iv
,
392 if (!this->key
|| iv
.len
!= IV_SIZE
)
399 *encr
= chunk_alloc(plain
.len
+ this->icv_size
);
402 this->encrypt(this, plain
.len
, plain
.ptr
, out
, iv
.ptr
,
403 assoc
.len
, assoc
.ptr
, out
+ plain
.len
);
407 METHOD(aead_t
, decrypt
, bool,
408 private_aesni_gcm_t
*this, chunk_t encr
, chunk_t assoc
, chunk_t iv
,
411 u_char
*out
, icv
[this->icv_size
];
413 if (!this->key
|| iv
.len
!= IV_SIZE
|| encr
.len
< this->icv_size
)
417 encr
.len
-= this->icv_size
;
421 *plain
= chunk_alloc(encr
.len
);
424 this->decrypt(this, encr
.len
, encr
.ptr
, out
, iv
.ptr
,
425 assoc
.len
, assoc
.ptr
, icv
);
426 return memeq_const(icv
, encr
.ptr
+ encr
.len
, this->icv_size
);
429 METHOD(aead_t
, get_block_size
, size_t,
430 private_aesni_gcm_t
*this)
435 METHOD(aead_t
, get_icv_size
, size_t,
436 private_aesni_gcm_t
*this)
438 return this->icv_size
;
441 METHOD(aead_t
, get_iv_size
, size_t,
442 private_aesni_gcm_t
*this)
447 METHOD(aead_t
, get_iv_gen
, iv_gen_t
*,
448 private_aesni_gcm_t
*this)
453 METHOD(aead_t
, get_key_size
, size_t,
454 private_aesni_gcm_t
*this)
456 return this->key_size
+ SALT_SIZE
;
459 METHOD(aead_t
, set_key
, bool,
460 private_aesni_gcm_t
*this, chunk_t key
)
465 if (key
.len
!= this->key_size
+ SALT_SIZE
)
470 memcpy(this->salt
, key
.ptr
+ key
.len
- SALT_SIZE
, SALT_SIZE
);
471 key
.len
-= SALT_SIZE
;
473 DESTROY_IF(this->key
);
474 this->key
= aesni_key_create(TRUE
, key
);
476 h
= _mm_xor_si128(_mm_setzero_si128(), this->key
->schedule
[0]);
477 for (round
= 1; round
< this->key
->rounds
; round
++)
479 h
= _mm_aesenc_si128(h
, this->key
->schedule
[round
]);
481 h
= _mm_aesenclast_si128(h
, this->key
->schedule
[this->key
->rounds
]);
483 this->h
= swap128(h
);
488 METHOD(aead_t
, destroy
, void,
489 private_aesni_gcm_t
*this)
491 DESTROY_IF(this->key
);
492 memwipe(&this->h
, sizeof(this->h
));
493 this->iv_gen
->destroy(this->iv_gen
);
500 aesni_gcm_t
*aesni_gcm_create(encryption_algorithm_t algo
,
501 size_t key_size
, size_t salt_size
)
503 private_aesni_gcm_t
*this;
518 if (salt_size
&& salt_size
!= SALT_SIZE
)
520 /* currently not supported */
525 case ENCR_AES_GCM_ICV8
:
529 case ENCR_AES_GCM_ICV12
:
533 case ENCR_AES_GCM_ICV16
:
546 .get_block_size
= _get_block_size
,
547 .get_icv_size
= _get_icv_size
,
548 .get_iv_size
= _get_iv_size
,
549 .get_iv_gen
= _get_iv_gen
,
550 .get_key_size
= _get_key_size
,
555 .key_size
= key_size
,
556 .iv_gen
= iv_gen_seq_create(),
557 .icv_size
= icv_size
,
558 .encrypt
= encrypt_gcm
,
559 .decrypt
= decrypt_gcm
,
562 return &this->public;