2 * The AEGIS-128 Authenticated-Encryption Algorithm
4 * Copyright (c) 2017-2018 Ondrej Mosnacek <omosnacek@gmail.com>
5 * Copyright (C) 2017-2018 Red Hat, Inc. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
13 #include <crypto/algapi.h>
14 #include <crypto/internal/aead.h>
15 #include <crypto/internal/skcipher.h>
16 #include <crypto/scatterwalk.h>
17 #include <linux/err.h>
18 #include <linux/init.h>
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #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
;
40 int (*skcipher_walk_init
)(struct skcipher_walk
*walk
,
41 struct aead_request
*req
, bool atomic
);
43 void (*crypt_chunk
)(struct aegis_state
*state
, u8
*dst
,
44 const u8
*src
, unsigned int size
);
47 static void crypto_aegis128_update(struct aegis_state
*state
)
49 union aegis_block tmp
;
52 tmp
= state
->blocks
[AEGIS128_STATE_BLOCKS
- 1];
53 for (i
= AEGIS128_STATE_BLOCKS
- 1; i
> 0; i
--)
54 crypto_aegis_aesenc(&state
->blocks
[i
], &state
->blocks
[i
- 1],
56 crypto_aegis_aesenc(&state
->blocks
[0], &tmp
, &state
->blocks
[0]);
59 static void crypto_aegis128_update_a(struct aegis_state
*state
,
60 const union aegis_block
*msg
)
62 crypto_aegis128_update(state
);
63 crypto_aegis_block_xor(&state
->blocks
[0], msg
);
66 static void crypto_aegis128_update_u(struct aegis_state
*state
, const void *msg
)
68 crypto_aegis128_update(state
);
69 crypto_xor(state
->blocks
[0].bytes
, msg
, AEGIS_BLOCK_SIZE
);
72 static void crypto_aegis128_init(struct aegis_state
*state
,
73 const union aegis_block
*key
,
76 union aegis_block key_iv
;
80 crypto_xor(key_iv
.bytes
, iv
, AEGIS_BLOCK_SIZE
);
82 state
->blocks
[0] = key_iv
;
83 state
->blocks
[1] = crypto_aegis_const
[1];
84 state
->blocks
[2] = crypto_aegis_const
[0];
85 state
->blocks
[3] = *key
;
86 state
->blocks
[4] = *key
;
88 crypto_aegis_block_xor(&state
->blocks
[3], &crypto_aegis_const
[0]);
89 crypto_aegis_block_xor(&state
->blocks
[4], &crypto_aegis_const
[1]);
91 for (i
= 0; i
< 5; i
++) {
92 crypto_aegis128_update_a(state
, key
);
93 crypto_aegis128_update_a(state
, &key_iv
);
97 static void crypto_aegis128_ad(struct aegis_state
*state
,
98 const u8
*src
, unsigned int size
)
100 if (AEGIS_ALIGNED(src
)) {
101 const union aegis_block
*src_blk
=
102 (const union aegis_block
*)src
;
104 while (size
>= AEGIS_BLOCK_SIZE
) {
105 crypto_aegis128_update_a(state
, src_blk
);
107 size
-= AEGIS_BLOCK_SIZE
;
111 while (size
>= AEGIS_BLOCK_SIZE
) {
112 crypto_aegis128_update_u(state
, src
);
114 size
-= AEGIS_BLOCK_SIZE
;
115 src
+= AEGIS_BLOCK_SIZE
;
120 static void crypto_aegis128_encrypt_chunk(struct aegis_state
*state
, u8
*dst
,
121 const u8
*src
, unsigned int size
)
123 union aegis_block tmp
;
125 if (AEGIS_ALIGNED(src
) && AEGIS_ALIGNED(dst
)) {
126 while (size
>= AEGIS_BLOCK_SIZE
) {
127 union aegis_block
*dst_blk
=
128 (union aegis_block
*)dst
;
129 const union aegis_block
*src_blk
=
130 (const union aegis_block
*)src
;
132 tmp
= state
->blocks
[2];
133 crypto_aegis_block_and(&tmp
, &state
->blocks
[3]);
134 crypto_aegis_block_xor(&tmp
, &state
->blocks
[4]);
135 crypto_aegis_block_xor(&tmp
, &state
->blocks
[1]);
136 crypto_aegis_block_xor(&tmp
, src_blk
);
138 crypto_aegis128_update_a(state
, src_blk
);
142 size
-= AEGIS_BLOCK_SIZE
;
143 src
+= AEGIS_BLOCK_SIZE
;
144 dst
+= AEGIS_BLOCK_SIZE
;
147 while (size
>= AEGIS_BLOCK_SIZE
) {
148 tmp
= state
->blocks
[2];
149 crypto_aegis_block_and(&tmp
, &state
->blocks
[3]);
150 crypto_aegis_block_xor(&tmp
, &state
->blocks
[4]);
151 crypto_aegis_block_xor(&tmp
, &state
->blocks
[1]);
152 crypto_xor(tmp
.bytes
, src
, AEGIS_BLOCK_SIZE
);
154 crypto_aegis128_update_u(state
, src
);
156 memcpy(dst
, tmp
.bytes
, AEGIS_BLOCK_SIZE
);
158 size
-= AEGIS_BLOCK_SIZE
;
159 src
+= AEGIS_BLOCK_SIZE
;
160 dst
+= AEGIS_BLOCK_SIZE
;
165 union aegis_block msg
= {};
166 memcpy(msg
.bytes
, src
, size
);
168 tmp
= state
->blocks
[2];
169 crypto_aegis_block_and(&tmp
, &state
->blocks
[3]);
170 crypto_aegis_block_xor(&tmp
, &state
->blocks
[4]);
171 crypto_aegis_block_xor(&tmp
, &state
->blocks
[1]);
173 crypto_aegis128_update_a(state
, &msg
);
175 crypto_aegis_block_xor(&msg
, &tmp
);
177 memcpy(dst
, msg
.bytes
, size
);
181 static void crypto_aegis128_decrypt_chunk(struct aegis_state
*state
, u8
*dst
,
182 const u8
*src
, unsigned int size
)
184 union aegis_block tmp
;
186 if (AEGIS_ALIGNED(src
) && AEGIS_ALIGNED(dst
)) {
187 while (size
>= AEGIS_BLOCK_SIZE
) {
188 union aegis_block
*dst_blk
=
189 (union aegis_block
*)dst
;
190 const union aegis_block
*src_blk
=
191 (const union aegis_block
*)src
;
193 tmp
= state
->blocks
[2];
194 crypto_aegis_block_and(&tmp
, &state
->blocks
[3]);
195 crypto_aegis_block_xor(&tmp
, &state
->blocks
[4]);
196 crypto_aegis_block_xor(&tmp
, &state
->blocks
[1]);
197 crypto_aegis_block_xor(&tmp
, src_blk
);
199 crypto_aegis128_update_a(state
, &tmp
);
203 size
-= AEGIS_BLOCK_SIZE
;
204 src
+= AEGIS_BLOCK_SIZE
;
205 dst
+= AEGIS_BLOCK_SIZE
;
208 while (size
>= AEGIS_BLOCK_SIZE
) {
209 tmp
= state
->blocks
[2];
210 crypto_aegis_block_and(&tmp
, &state
->blocks
[3]);
211 crypto_aegis_block_xor(&tmp
, &state
->blocks
[4]);
212 crypto_aegis_block_xor(&tmp
, &state
->blocks
[1]);
213 crypto_xor(tmp
.bytes
, src
, AEGIS_BLOCK_SIZE
);
215 crypto_aegis128_update_a(state
, &tmp
);
217 memcpy(dst
, tmp
.bytes
, AEGIS_BLOCK_SIZE
);
219 size
-= AEGIS_BLOCK_SIZE
;
220 src
+= AEGIS_BLOCK_SIZE
;
221 dst
+= AEGIS_BLOCK_SIZE
;
226 union aegis_block msg
= {};
227 memcpy(msg
.bytes
, src
, size
);
229 tmp
= state
->blocks
[2];
230 crypto_aegis_block_and(&tmp
, &state
->blocks
[3]);
231 crypto_aegis_block_xor(&tmp
, &state
->blocks
[4]);
232 crypto_aegis_block_xor(&tmp
, &state
->blocks
[1]);
233 crypto_aegis_block_xor(&msg
, &tmp
);
235 memset(msg
.bytes
+ size
, 0, AEGIS_BLOCK_SIZE
- size
);
237 crypto_aegis128_update_a(state
, &msg
);
239 memcpy(dst
, msg
.bytes
, size
);
243 static void crypto_aegis128_process_ad(struct aegis_state
*state
,
244 struct scatterlist
*sg_src
,
245 unsigned int assoclen
)
247 struct scatter_walk walk
;
248 union aegis_block buf
;
249 unsigned int pos
= 0;
251 scatterwalk_start(&walk
, sg_src
);
252 while (assoclen
!= 0) {
253 unsigned int size
= scatterwalk_clamp(&walk
, assoclen
);
254 unsigned int left
= size
;
255 void *mapped
= scatterwalk_map(&walk
);
256 const u8
*src
= (const u8
*)mapped
;
258 if (pos
+ size
>= AEGIS_BLOCK_SIZE
) {
260 unsigned int fill
= AEGIS_BLOCK_SIZE
- pos
;
261 memcpy(buf
.bytes
+ pos
, src
, fill
);
262 crypto_aegis128_update_a(state
, &buf
);
268 crypto_aegis128_ad(state
, src
, left
);
269 src
+= left
& ~(AEGIS_BLOCK_SIZE
- 1);
270 left
&= AEGIS_BLOCK_SIZE
- 1;
273 memcpy(buf
.bytes
+ pos
, src
, left
);
277 scatterwalk_unmap(mapped
);
278 scatterwalk_advance(&walk
, size
);
279 scatterwalk_done(&walk
, 0, assoclen
);
283 memset(buf
.bytes
+ pos
, 0, AEGIS_BLOCK_SIZE
- pos
);
284 crypto_aegis128_update_a(state
, &buf
);
288 static void crypto_aegis128_process_crypt(struct aegis_state
*state
,
289 struct aead_request
*req
,
290 const struct aegis128_ops
*ops
)
292 struct skcipher_walk walk
;
294 unsigned int chunksize
;
296 ops
->skcipher_walk_init(&walk
, req
, false);
298 while (walk
.nbytes
) {
299 src
= walk
.src
.virt
.addr
;
300 dst
= walk
.dst
.virt
.addr
;
301 chunksize
= walk
.nbytes
;
303 ops
->crypt_chunk(state
, dst
, src
, chunksize
);
305 skcipher_walk_done(&walk
, 0);
309 static void crypto_aegis128_final(struct aegis_state
*state
,
310 union aegis_block
*tag_xor
,
311 u64 assoclen
, u64 cryptlen
)
313 u64 assocbits
= assoclen
* 8;
314 u64 cryptbits
= cryptlen
* 8;
316 union aegis_block tmp
;
319 tmp
.words64
[0] = cpu_to_le64(assocbits
);
320 tmp
.words64
[1] = cpu_to_le64(cryptbits
);
322 crypto_aegis_block_xor(&tmp
, &state
->blocks
[3]);
324 for (i
= 0; i
< 7; i
++)
325 crypto_aegis128_update_a(state
, &tmp
);
327 for (i
= 0; i
< AEGIS128_STATE_BLOCKS
; i
++)
328 crypto_aegis_block_xor(tag_xor
, &state
->blocks
[i
]);
331 static int crypto_aegis128_setkey(struct crypto_aead
*aead
, const u8
*key
,
334 struct aegis_ctx
*ctx
= crypto_aead_ctx(aead
);
336 if (keylen
!= AEGIS128_KEY_SIZE
) {
337 crypto_aead_set_flags(aead
, CRYPTO_TFM_RES_BAD_KEY_LEN
);
341 memcpy(ctx
->key
.bytes
, key
, AEGIS128_KEY_SIZE
);
345 static int crypto_aegis128_setauthsize(struct crypto_aead
*tfm
,
346 unsigned int authsize
)
348 if (authsize
> AEGIS128_MAX_AUTH_SIZE
)
350 if (authsize
< AEGIS128_MIN_AUTH_SIZE
)
355 static void crypto_aegis128_crypt(struct aead_request
*req
,
356 union aegis_block
*tag_xor
,
357 unsigned int cryptlen
,
358 const struct aegis128_ops
*ops
)
360 struct crypto_aead
*tfm
= crypto_aead_reqtfm(req
);
361 struct aegis_ctx
*ctx
= crypto_aead_ctx(tfm
);
362 struct aegis_state state
;
364 crypto_aegis128_init(&state
, &ctx
->key
, req
->iv
);
365 crypto_aegis128_process_ad(&state
, req
->src
, req
->assoclen
);
366 crypto_aegis128_process_crypt(&state
, req
, ops
);
367 crypto_aegis128_final(&state
, tag_xor
, req
->assoclen
, cryptlen
);
370 static int crypto_aegis128_encrypt(struct aead_request
*req
)
372 static const struct aegis128_ops ops
= {
373 .skcipher_walk_init
= skcipher_walk_aead_encrypt
,
374 .crypt_chunk
= crypto_aegis128_encrypt_chunk
,
377 struct crypto_aead
*tfm
= crypto_aead_reqtfm(req
);
378 union aegis_block tag
= {};
379 unsigned int authsize
= crypto_aead_authsize(tfm
);
380 unsigned int cryptlen
= req
->cryptlen
;
382 crypto_aegis128_crypt(req
, &tag
, cryptlen
, &ops
);
384 scatterwalk_map_and_copy(tag
.bytes
, req
->dst
, req
->assoclen
+ cryptlen
,
389 static int crypto_aegis128_decrypt(struct aead_request
*req
)
391 static const struct aegis128_ops ops
= {
392 .skcipher_walk_init
= skcipher_walk_aead_decrypt
,
393 .crypt_chunk
= crypto_aegis128_decrypt_chunk
,
395 static const u8 zeros
[AEGIS128_MAX_AUTH_SIZE
] = {};
397 struct crypto_aead
*tfm
= crypto_aead_reqtfm(req
);
398 union aegis_block tag
;
399 unsigned int authsize
= crypto_aead_authsize(tfm
);
400 unsigned int cryptlen
= req
->cryptlen
- authsize
;
402 scatterwalk_map_and_copy(tag
.bytes
, req
->src
, req
->assoclen
+ cryptlen
,
405 crypto_aegis128_crypt(req
, &tag
, cryptlen
, &ops
);
407 return crypto_memneq(tag
.bytes
, zeros
, authsize
) ? -EBADMSG
: 0;
410 static int crypto_aegis128_init_tfm(struct crypto_aead
*tfm
)
415 static void crypto_aegis128_exit_tfm(struct crypto_aead
*tfm
)
419 static struct aead_alg crypto_aegis128_alg
= {
420 .setkey
= crypto_aegis128_setkey
,
421 .setauthsize
= crypto_aegis128_setauthsize
,
422 .encrypt
= crypto_aegis128_encrypt
,
423 .decrypt
= crypto_aegis128_decrypt
,
424 .init
= crypto_aegis128_init_tfm
,
425 .exit
= crypto_aegis128_exit_tfm
,
427 .ivsize
= AEGIS128_NONCE_SIZE
,
428 .maxauthsize
= AEGIS128_MAX_AUTH_SIZE
,
429 .chunksize
= AEGIS_BLOCK_SIZE
,
433 .cra_ctxsize
= sizeof(struct aegis_ctx
),
438 .cra_name
= "aegis128",
439 .cra_driver_name
= "aegis128-generic",
441 .cra_module
= THIS_MODULE
,
445 static int __init
crypto_aegis128_module_init(void)
447 return crypto_register_aead(&crypto_aegis128_alg
);
450 static void __exit
crypto_aegis128_module_exit(void)
452 crypto_unregister_aead(&crypto_aegis128_alg
);
455 module_init(crypto_aegis128_module_init
);
456 module_exit(crypto_aegis128_module_exit
);
458 MODULE_LICENSE("GPL");
459 MODULE_AUTHOR("Ondrej Mosnacek <omosnacek@gmail.com>");
460 MODULE_DESCRIPTION("AEGIS-128 AEAD algorithm");
461 MODULE_ALIAS_CRYPTO("aegis128");
462 MODULE_ALIAS_CRYPTO("aegis128-generic");