1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * The AEGIS-128 Authenticated-Encryption Algorithm
5 * Copyright (c) 2017-2018 Ondrej Mosnacek <omosnacek@gmail.com>
6 * Copyright (C) 2017-2018 Red Hat, Inc. All rights reserved.
9 #include <crypto/algapi.h>
10 #include <crypto/internal/aead.h>
11 #include <crypto/internal/simd.h>
12 #include <crypto/internal/skcipher.h>
13 #include <crypto/scatterwalk.h>
14 #include <linux/err.h>
15 #include <linux/init.h>
16 #include <linux/jump_label.h>
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/scatterlist.h>
25 #define AEGIS128_NONCE_SIZE 16
26 #define AEGIS128_STATE_BLOCKS 5
27 #define AEGIS128_KEY_SIZE 16
28 #define AEGIS128_MIN_AUTH_SIZE 8
29 #define AEGIS128_MAX_AUTH_SIZE 16
32 union aegis_block blocks
[AEGIS128_STATE_BLOCKS
];
36 union aegis_block key
;
39 static __ro_after_init
DEFINE_STATIC_KEY_FALSE(have_simd
);
41 static const union aegis_block crypto_aegis_const
[2] = {
43 cpu_to_le64(U64_C(0x0d08050302010100)),
44 cpu_to_le64(U64_C(0x6279e99059372215)),
47 cpu_to_le64(U64_C(0xf12fc26d55183ddb)),
48 cpu_to_le64(U64_C(0xdd28b57342311120)),
52 static bool aegis128_do_simd(void)
54 #ifdef CONFIG_CRYPTO_AEGIS128_SIMD
55 if (static_branch_likely(&have_simd
))
56 return crypto_simd_usable();
61 bool crypto_aegis128_have_simd(void);
62 void crypto_aegis128_update_simd(struct aegis_state
*state
, const void *msg
);
63 void crypto_aegis128_init_simd(struct aegis_state
*state
,
64 const union aegis_block
*key
,
66 void crypto_aegis128_encrypt_chunk_simd(struct aegis_state
*state
, u8
*dst
,
67 const u8
*src
, unsigned int size
);
68 void crypto_aegis128_decrypt_chunk_simd(struct aegis_state
*state
, u8
*dst
,
69 const u8
*src
, unsigned int size
);
70 void crypto_aegis128_final_simd(struct aegis_state
*state
,
71 union aegis_block
*tag_xor
,
72 u64 assoclen
, u64 cryptlen
);
74 static void crypto_aegis128_update(struct aegis_state
*state
)
76 union aegis_block tmp
;
79 tmp
= state
->blocks
[AEGIS128_STATE_BLOCKS
- 1];
80 for (i
= AEGIS128_STATE_BLOCKS
- 1; i
> 0; i
--)
81 crypto_aegis_aesenc(&state
->blocks
[i
], &state
->blocks
[i
- 1],
83 crypto_aegis_aesenc(&state
->blocks
[0], &tmp
, &state
->blocks
[0]);
86 static void crypto_aegis128_update_a(struct aegis_state
*state
,
87 const union aegis_block
*msg
)
89 if (aegis128_do_simd()) {
90 crypto_aegis128_update_simd(state
, msg
);
94 crypto_aegis128_update(state
);
95 crypto_aegis_block_xor(&state
->blocks
[0], msg
);
98 static void crypto_aegis128_update_u(struct aegis_state
*state
, const void *msg
)
100 if (aegis128_do_simd()) {
101 crypto_aegis128_update_simd(state
, msg
);
105 crypto_aegis128_update(state
);
106 crypto_xor(state
->blocks
[0].bytes
, msg
, AEGIS_BLOCK_SIZE
);
109 static void crypto_aegis128_init(struct aegis_state
*state
,
110 const union aegis_block
*key
,
113 union aegis_block key_iv
;
117 crypto_xor(key_iv
.bytes
, iv
, AEGIS_BLOCK_SIZE
);
119 state
->blocks
[0] = key_iv
;
120 state
->blocks
[1] = crypto_aegis_const
[1];
121 state
->blocks
[2] = crypto_aegis_const
[0];
122 state
->blocks
[3] = *key
;
123 state
->blocks
[4] = *key
;
125 crypto_aegis_block_xor(&state
->blocks
[3], &crypto_aegis_const
[0]);
126 crypto_aegis_block_xor(&state
->blocks
[4], &crypto_aegis_const
[1]);
128 for (i
= 0; i
< 5; i
++) {
129 crypto_aegis128_update_a(state
, key
);
130 crypto_aegis128_update_a(state
, &key_iv
);
134 static void crypto_aegis128_ad(struct aegis_state
*state
,
135 const u8
*src
, unsigned int size
)
137 if (AEGIS_ALIGNED(src
)) {
138 const union aegis_block
*src_blk
=
139 (const union aegis_block
*)src
;
141 while (size
>= AEGIS_BLOCK_SIZE
) {
142 crypto_aegis128_update_a(state
, src_blk
);
144 size
-= AEGIS_BLOCK_SIZE
;
148 while (size
>= AEGIS_BLOCK_SIZE
) {
149 crypto_aegis128_update_u(state
, src
);
151 size
-= AEGIS_BLOCK_SIZE
;
152 src
+= AEGIS_BLOCK_SIZE
;
157 static void crypto_aegis128_encrypt_chunk(struct aegis_state
*state
, u8
*dst
,
158 const u8
*src
, unsigned int size
)
160 union aegis_block tmp
;
162 if (AEGIS_ALIGNED(src
) && AEGIS_ALIGNED(dst
)) {
163 while (size
>= AEGIS_BLOCK_SIZE
) {
164 union aegis_block
*dst_blk
=
165 (union aegis_block
*)dst
;
166 const union aegis_block
*src_blk
=
167 (const union aegis_block
*)src
;
169 tmp
= state
->blocks
[2];
170 crypto_aegis_block_and(&tmp
, &state
->blocks
[3]);
171 crypto_aegis_block_xor(&tmp
, &state
->blocks
[4]);
172 crypto_aegis_block_xor(&tmp
, &state
->blocks
[1]);
173 crypto_aegis_block_xor(&tmp
, src_blk
);
175 crypto_aegis128_update_a(state
, src_blk
);
179 size
-= AEGIS_BLOCK_SIZE
;
180 src
+= AEGIS_BLOCK_SIZE
;
181 dst
+= AEGIS_BLOCK_SIZE
;
184 while (size
>= AEGIS_BLOCK_SIZE
) {
185 tmp
= state
->blocks
[2];
186 crypto_aegis_block_and(&tmp
, &state
->blocks
[3]);
187 crypto_aegis_block_xor(&tmp
, &state
->blocks
[4]);
188 crypto_aegis_block_xor(&tmp
, &state
->blocks
[1]);
189 crypto_xor(tmp
.bytes
, src
, AEGIS_BLOCK_SIZE
);
191 crypto_aegis128_update_u(state
, src
);
193 memcpy(dst
, tmp
.bytes
, AEGIS_BLOCK_SIZE
);
195 size
-= AEGIS_BLOCK_SIZE
;
196 src
+= AEGIS_BLOCK_SIZE
;
197 dst
+= AEGIS_BLOCK_SIZE
;
202 union aegis_block msg
= {};
203 memcpy(msg
.bytes
, src
, size
);
205 tmp
= state
->blocks
[2];
206 crypto_aegis_block_and(&tmp
, &state
->blocks
[3]);
207 crypto_aegis_block_xor(&tmp
, &state
->blocks
[4]);
208 crypto_aegis_block_xor(&tmp
, &state
->blocks
[1]);
210 crypto_aegis128_update_a(state
, &msg
);
212 crypto_aegis_block_xor(&msg
, &tmp
);
214 memcpy(dst
, msg
.bytes
, size
);
218 static void crypto_aegis128_decrypt_chunk(struct aegis_state
*state
, u8
*dst
,
219 const u8
*src
, unsigned int size
)
221 union aegis_block tmp
;
223 if (AEGIS_ALIGNED(src
) && AEGIS_ALIGNED(dst
)) {
224 while (size
>= AEGIS_BLOCK_SIZE
) {
225 union aegis_block
*dst_blk
=
226 (union aegis_block
*)dst
;
227 const union aegis_block
*src_blk
=
228 (const union aegis_block
*)src
;
230 tmp
= state
->blocks
[2];
231 crypto_aegis_block_and(&tmp
, &state
->blocks
[3]);
232 crypto_aegis_block_xor(&tmp
, &state
->blocks
[4]);
233 crypto_aegis_block_xor(&tmp
, &state
->blocks
[1]);
234 crypto_aegis_block_xor(&tmp
, src_blk
);
236 crypto_aegis128_update_a(state
, &tmp
);
240 size
-= AEGIS_BLOCK_SIZE
;
241 src
+= AEGIS_BLOCK_SIZE
;
242 dst
+= AEGIS_BLOCK_SIZE
;
245 while (size
>= AEGIS_BLOCK_SIZE
) {
246 tmp
= state
->blocks
[2];
247 crypto_aegis_block_and(&tmp
, &state
->blocks
[3]);
248 crypto_aegis_block_xor(&tmp
, &state
->blocks
[4]);
249 crypto_aegis_block_xor(&tmp
, &state
->blocks
[1]);
250 crypto_xor(tmp
.bytes
, src
, AEGIS_BLOCK_SIZE
);
252 crypto_aegis128_update_a(state
, &tmp
);
254 memcpy(dst
, tmp
.bytes
, AEGIS_BLOCK_SIZE
);
256 size
-= AEGIS_BLOCK_SIZE
;
257 src
+= AEGIS_BLOCK_SIZE
;
258 dst
+= AEGIS_BLOCK_SIZE
;
263 union aegis_block msg
= {};
264 memcpy(msg
.bytes
, src
, size
);
266 tmp
= state
->blocks
[2];
267 crypto_aegis_block_and(&tmp
, &state
->blocks
[3]);
268 crypto_aegis_block_xor(&tmp
, &state
->blocks
[4]);
269 crypto_aegis_block_xor(&tmp
, &state
->blocks
[1]);
270 crypto_aegis_block_xor(&msg
, &tmp
);
272 memset(msg
.bytes
+ size
, 0, AEGIS_BLOCK_SIZE
- size
);
274 crypto_aegis128_update_a(state
, &msg
);
276 memcpy(dst
, msg
.bytes
, size
);
280 static void crypto_aegis128_process_ad(struct aegis_state
*state
,
281 struct scatterlist
*sg_src
,
282 unsigned int assoclen
)
284 struct scatter_walk walk
;
285 union aegis_block buf
;
286 unsigned int pos
= 0;
288 scatterwalk_start(&walk
, sg_src
);
289 while (assoclen
!= 0) {
290 unsigned int size
= scatterwalk_clamp(&walk
, assoclen
);
291 unsigned int left
= size
;
292 void *mapped
= scatterwalk_map(&walk
);
293 const u8
*src
= (const u8
*)mapped
;
295 if (pos
+ size
>= AEGIS_BLOCK_SIZE
) {
297 unsigned int fill
= AEGIS_BLOCK_SIZE
- pos
;
298 memcpy(buf
.bytes
+ pos
, src
, fill
);
299 crypto_aegis128_update_a(state
, &buf
);
305 crypto_aegis128_ad(state
, src
, left
);
306 src
+= left
& ~(AEGIS_BLOCK_SIZE
- 1);
307 left
&= AEGIS_BLOCK_SIZE
- 1;
310 memcpy(buf
.bytes
+ pos
, src
, left
);
314 scatterwalk_unmap(mapped
);
315 scatterwalk_advance(&walk
, size
);
316 scatterwalk_done(&walk
, 0, assoclen
);
320 memset(buf
.bytes
+ pos
, 0, AEGIS_BLOCK_SIZE
- pos
);
321 crypto_aegis128_update_a(state
, &buf
);
325 static __always_inline
326 int crypto_aegis128_process_crypt(struct aegis_state
*state
,
327 struct aead_request
*req
,
328 struct skcipher_walk
*walk
,
329 void (*crypt
)(struct aegis_state
*state
,
330 u8
*dst
, const u8
*src
,
335 while (walk
->nbytes
) {
336 unsigned int nbytes
= walk
->nbytes
;
338 if (nbytes
< walk
->total
)
339 nbytes
= round_down(nbytes
, walk
->stride
);
341 crypt(state
, walk
->dst
.virt
.addr
, walk
->src
.virt
.addr
, nbytes
);
343 err
= skcipher_walk_done(walk
, walk
->nbytes
- nbytes
);
348 static void crypto_aegis128_final(struct aegis_state
*state
,
349 union aegis_block
*tag_xor
,
350 u64 assoclen
, u64 cryptlen
)
352 u64 assocbits
= assoclen
* 8;
353 u64 cryptbits
= cryptlen
* 8;
355 union aegis_block tmp
;
358 tmp
.words64
[0] = cpu_to_le64(assocbits
);
359 tmp
.words64
[1] = cpu_to_le64(cryptbits
);
361 crypto_aegis_block_xor(&tmp
, &state
->blocks
[3]);
363 for (i
= 0; i
< 7; i
++)
364 crypto_aegis128_update_a(state
, &tmp
);
366 for (i
= 0; i
< AEGIS128_STATE_BLOCKS
; i
++)
367 crypto_aegis_block_xor(tag_xor
, &state
->blocks
[i
]);
370 static int crypto_aegis128_setkey(struct crypto_aead
*aead
, const u8
*key
,
373 struct aegis_ctx
*ctx
= crypto_aead_ctx(aead
);
375 if (keylen
!= AEGIS128_KEY_SIZE
)
378 memcpy(ctx
->key
.bytes
, key
, AEGIS128_KEY_SIZE
);
382 static int crypto_aegis128_setauthsize(struct crypto_aead
*tfm
,
383 unsigned int authsize
)
385 if (authsize
> AEGIS128_MAX_AUTH_SIZE
)
387 if (authsize
< AEGIS128_MIN_AUTH_SIZE
)
392 static int crypto_aegis128_encrypt(struct aead_request
*req
)
394 struct crypto_aead
*tfm
= crypto_aead_reqtfm(req
);
395 union aegis_block tag
= {};
396 unsigned int authsize
= crypto_aead_authsize(tfm
);
397 struct aegis_ctx
*ctx
= crypto_aead_ctx(tfm
);
398 unsigned int cryptlen
= req
->cryptlen
;
399 struct skcipher_walk walk
;
400 struct aegis_state state
;
402 skcipher_walk_aead_encrypt(&walk
, req
, false);
403 if (aegis128_do_simd()) {
404 crypto_aegis128_init_simd(&state
, &ctx
->key
, req
->iv
);
405 crypto_aegis128_process_ad(&state
, req
->src
, req
->assoclen
);
406 crypto_aegis128_process_crypt(&state
, req
, &walk
,
407 crypto_aegis128_encrypt_chunk_simd
);
408 crypto_aegis128_final_simd(&state
, &tag
, req
->assoclen
,
411 crypto_aegis128_init(&state
, &ctx
->key
, req
->iv
);
412 crypto_aegis128_process_ad(&state
, req
->src
, req
->assoclen
);
413 crypto_aegis128_process_crypt(&state
, req
, &walk
,
414 crypto_aegis128_encrypt_chunk
);
415 crypto_aegis128_final(&state
, &tag
, req
->assoclen
, cryptlen
);
418 scatterwalk_map_and_copy(tag
.bytes
, req
->dst
, req
->assoclen
+ cryptlen
,
423 static int crypto_aegis128_decrypt(struct aead_request
*req
)
425 static const u8 zeros
[AEGIS128_MAX_AUTH_SIZE
] = {};
426 struct crypto_aead
*tfm
= crypto_aead_reqtfm(req
);
427 union aegis_block tag
;
428 unsigned int authsize
= crypto_aead_authsize(tfm
);
429 unsigned int cryptlen
= req
->cryptlen
- authsize
;
430 struct aegis_ctx
*ctx
= crypto_aead_ctx(tfm
);
431 struct skcipher_walk walk
;
432 struct aegis_state state
;
434 scatterwalk_map_and_copy(tag
.bytes
, req
->src
, req
->assoclen
+ cryptlen
,
437 skcipher_walk_aead_decrypt(&walk
, req
, false);
438 if (aegis128_do_simd()) {
439 crypto_aegis128_init_simd(&state
, &ctx
->key
, req
->iv
);
440 crypto_aegis128_process_ad(&state
, req
->src
, req
->assoclen
);
441 crypto_aegis128_process_crypt(&state
, req
, &walk
,
442 crypto_aegis128_decrypt_chunk_simd
);
443 crypto_aegis128_final_simd(&state
, &tag
, req
->assoclen
,
446 crypto_aegis128_init(&state
, &ctx
->key
, req
->iv
);
447 crypto_aegis128_process_ad(&state
, req
->src
, req
->assoclen
);
448 crypto_aegis128_process_crypt(&state
, req
, &walk
,
449 crypto_aegis128_decrypt_chunk
);
450 crypto_aegis128_final(&state
, &tag
, req
->assoclen
, cryptlen
);
453 return crypto_memneq(tag
.bytes
, zeros
, authsize
) ? -EBADMSG
: 0;
456 static struct aead_alg crypto_aegis128_alg
= {
457 .setkey
= crypto_aegis128_setkey
,
458 .setauthsize
= crypto_aegis128_setauthsize
,
459 .encrypt
= crypto_aegis128_encrypt
,
460 .decrypt
= crypto_aegis128_decrypt
,
462 .ivsize
= AEGIS128_NONCE_SIZE
,
463 .maxauthsize
= AEGIS128_MAX_AUTH_SIZE
,
464 .chunksize
= AEGIS_BLOCK_SIZE
,
468 .cra_ctxsize
= sizeof(struct aegis_ctx
),
473 .cra_name
= "aegis128",
474 .cra_driver_name
= "aegis128-generic",
476 .cra_module
= THIS_MODULE
,
480 static int __init
crypto_aegis128_module_init(void)
482 if (IS_ENABLED(CONFIG_CRYPTO_AEGIS128_SIMD
) &&
483 crypto_aegis128_have_simd())
484 static_branch_enable(&have_simd
);
486 return crypto_register_aead(&crypto_aegis128_alg
);
489 static void __exit
crypto_aegis128_module_exit(void)
491 crypto_unregister_aead(&crypto_aegis128_alg
);
494 subsys_initcall(crypto_aegis128_module_init
);
495 module_exit(crypto_aegis128_module_exit
);
497 MODULE_LICENSE("GPL");
498 MODULE_AUTHOR("Ondrej Mosnacek <omosnacek@gmail.com>");
499 MODULE_DESCRIPTION("AEGIS-128 AEAD algorithm");
500 MODULE_ALIAS_CRYPTO("aegis128");
501 MODULE_ALIAS_CRYPTO("aegis128-generic");