1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * The MORUS-1280 Authenticated-Encryption Algorithm
5 * Copyright (c) 2016-2018 Ondrej Mosnacek <omosnacek@gmail.com>
6 * Copyright (C) 2017-2018 Red Hat, Inc. All rights reserved.
9 #include <asm/unaligned.h>
10 #include <crypto/algapi.h>
11 #include <crypto/internal/aead.h>
12 #include <crypto/internal/skcipher.h>
13 #include <crypto/morus_common.h>
14 #include <crypto/scatterwalk.h>
15 #include <linux/err.h>
16 #include <linux/init.h>
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/scatterlist.h>
21 #define MORUS1280_WORD_SIZE 8
22 #define MORUS1280_BLOCK_SIZE (MORUS_BLOCK_WORDS * MORUS1280_WORD_SIZE)
23 #define MORUS1280_BLOCK_ALIGN (__alignof__(__le64))
24 #define MORUS1280_ALIGNED(p) IS_ALIGNED((uintptr_t)p, MORUS1280_BLOCK_ALIGN)
26 struct morus1280_block
{
27 u64 words
[MORUS_BLOCK_WORDS
];
30 union morus1280_block_in
{
31 __le64 words
[MORUS_BLOCK_WORDS
];
32 u8 bytes
[MORUS1280_BLOCK_SIZE
];
35 struct morus1280_state
{
36 struct morus1280_block s
[MORUS_STATE_BLOCKS
];
39 struct morus1280_ctx
{
40 struct morus1280_block key
;
43 struct morus1280_ops
{
44 int (*skcipher_walk_init
)(struct skcipher_walk
*walk
,
45 struct aead_request
*req
, bool atomic
);
47 void (*crypt_chunk
)(struct morus1280_state
*state
,
48 u8
*dst
, const u8
*src
, unsigned int size
);
51 static const struct morus1280_block crypto_morus1280_const
[1] = {
53 U64_C(0x0d08050302010100),
54 U64_C(0x6279e99059372215),
55 U64_C(0xf12fc26d55183ddb),
56 U64_C(0xdd28b57342311120),
60 static void crypto_morus1280_round(struct morus1280_block
*b0
,
61 struct morus1280_block
*b1
,
62 struct morus1280_block
*b2
,
63 struct morus1280_block
*b3
,
64 struct morus1280_block
*b4
,
65 const struct morus1280_block
*m
,
66 unsigned int b
, unsigned int w
)
69 struct morus1280_block tmp
;
71 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++) {
72 b0
->words
[i
] ^= b1
->words
[i
] & b2
->words
[i
];
73 b0
->words
[i
] ^= b3
->words
[i
];
74 b0
->words
[i
] ^= m
->words
[i
];
75 b0
->words
[i
] = rol64(b0
->words
[i
], b
);
79 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++)
80 b3
->words
[(i
+ w
) % MORUS_BLOCK_WORDS
] = tmp
.words
[i
];
83 static void crypto_morus1280_update(struct morus1280_state
*state
,
84 const struct morus1280_block
*m
)
86 static const struct morus1280_block z
= {};
88 struct morus1280_block
*s
= state
->s
;
90 crypto_morus1280_round(&s
[0], &s
[1], &s
[2], &s
[3], &s
[4], &z
, 13, 1);
91 crypto_morus1280_round(&s
[1], &s
[2], &s
[3], &s
[4], &s
[0], m
, 46, 2);
92 crypto_morus1280_round(&s
[2], &s
[3], &s
[4], &s
[0], &s
[1], m
, 38, 3);
93 crypto_morus1280_round(&s
[3], &s
[4], &s
[0], &s
[1], &s
[2], m
, 7, 2);
94 crypto_morus1280_round(&s
[4], &s
[0], &s
[1], &s
[2], &s
[3], m
, 4, 1);
97 static void crypto_morus1280_load_a(struct morus1280_block
*dst
, const u8
*src
)
100 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++) {
101 dst
->words
[i
] = le64_to_cpu(*(const __le64
*)src
);
102 src
+= MORUS1280_WORD_SIZE
;
106 static void crypto_morus1280_load_u(struct morus1280_block
*dst
, const u8
*src
)
109 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++) {
110 dst
->words
[i
] = get_unaligned_le64(src
);
111 src
+= MORUS1280_WORD_SIZE
;
115 static void crypto_morus1280_load(struct morus1280_block
*dst
, const u8
*src
)
117 if (MORUS1280_ALIGNED(src
))
118 crypto_morus1280_load_a(dst
, src
);
120 crypto_morus1280_load_u(dst
, src
);
123 static void crypto_morus1280_store_a(u8
*dst
, const struct morus1280_block
*src
)
126 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++) {
127 *(__le64
*)dst
= cpu_to_le64(src
->words
[i
]);
128 dst
+= MORUS1280_WORD_SIZE
;
132 static void crypto_morus1280_store_u(u8
*dst
, const struct morus1280_block
*src
)
135 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++) {
136 put_unaligned_le64(src
->words
[i
], dst
);
137 dst
+= MORUS1280_WORD_SIZE
;
141 static void crypto_morus1280_store(u8
*dst
, const struct morus1280_block
*src
)
143 if (MORUS1280_ALIGNED(dst
))
144 crypto_morus1280_store_a(dst
, src
);
146 crypto_morus1280_store_u(dst
, src
);
149 static void crypto_morus1280_ad(struct morus1280_state
*state
, const u8
*src
,
152 struct morus1280_block m
;
154 if (MORUS1280_ALIGNED(src
)) {
155 while (size
>= MORUS1280_BLOCK_SIZE
) {
156 crypto_morus1280_load_a(&m
, src
);
157 crypto_morus1280_update(state
, &m
);
159 size
-= MORUS1280_BLOCK_SIZE
;
160 src
+= MORUS1280_BLOCK_SIZE
;
163 while (size
>= MORUS1280_BLOCK_SIZE
) {
164 crypto_morus1280_load_u(&m
, src
);
165 crypto_morus1280_update(state
, &m
);
167 size
-= MORUS1280_BLOCK_SIZE
;
168 src
+= MORUS1280_BLOCK_SIZE
;
173 static void crypto_morus1280_core(const struct morus1280_state
*state
,
174 struct morus1280_block
*blk
)
178 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++)
179 blk
->words
[(i
+ 3) % MORUS_BLOCK_WORDS
] ^= state
->s
[1].words
[i
];
181 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++) {
182 blk
->words
[i
] ^= state
->s
[0].words
[i
];
183 blk
->words
[i
] ^= state
->s
[2].words
[i
] & state
->s
[3].words
[i
];
187 static void crypto_morus1280_encrypt_chunk(struct morus1280_state
*state
,
188 u8
*dst
, const u8
*src
,
191 struct morus1280_block c
, m
;
193 if (MORUS1280_ALIGNED(src
) && MORUS1280_ALIGNED(dst
)) {
194 while (size
>= MORUS1280_BLOCK_SIZE
) {
195 crypto_morus1280_load_a(&m
, src
);
197 crypto_morus1280_core(state
, &c
);
198 crypto_morus1280_store_a(dst
, &c
);
199 crypto_morus1280_update(state
, &m
);
201 src
+= MORUS1280_BLOCK_SIZE
;
202 dst
+= MORUS1280_BLOCK_SIZE
;
203 size
-= MORUS1280_BLOCK_SIZE
;
206 while (size
>= MORUS1280_BLOCK_SIZE
) {
207 crypto_morus1280_load_u(&m
, src
);
209 crypto_morus1280_core(state
, &c
);
210 crypto_morus1280_store_u(dst
, &c
);
211 crypto_morus1280_update(state
, &m
);
213 src
+= MORUS1280_BLOCK_SIZE
;
214 dst
+= MORUS1280_BLOCK_SIZE
;
215 size
-= MORUS1280_BLOCK_SIZE
;
220 union morus1280_block_in tail
;
222 memcpy(tail
.bytes
, src
, size
);
223 memset(tail
.bytes
+ size
, 0, MORUS1280_BLOCK_SIZE
- size
);
225 crypto_morus1280_load_a(&m
, tail
.bytes
);
227 crypto_morus1280_core(state
, &c
);
228 crypto_morus1280_store_a(tail
.bytes
, &c
);
229 crypto_morus1280_update(state
, &m
);
231 memcpy(dst
, tail
.bytes
, size
);
235 static void crypto_morus1280_decrypt_chunk(struct morus1280_state
*state
,
236 u8
*dst
, const u8
*src
,
239 struct morus1280_block m
;
241 if (MORUS1280_ALIGNED(src
) && MORUS1280_ALIGNED(dst
)) {
242 while (size
>= MORUS1280_BLOCK_SIZE
) {
243 crypto_morus1280_load_a(&m
, src
);
244 crypto_morus1280_core(state
, &m
);
245 crypto_morus1280_store_a(dst
, &m
);
246 crypto_morus1280_update(state
, &m
);
248 src
+= MORUS1280_BLOCK_SIZE
;
249 dst
+= MORUS1280_BLOCK_SIZE
;
250 size
-= MORUS1280_BLOCK_SIZE
;
253 while (size
>= MORUS1280_BLOCK_SIZE
) {
254 crypto_morus1280_load_u(&m
, src
);
255 crypto_morus1280_core(state
, &m
);
256 crypto_morus1280_store_u(dst
, &m
);
257 crypto_morus1280_update(state
, &m
);
259 src
+= MORUS1280_BLOCK_SIZE
;
260 dst
+= MORUS1280_BLOCK_SIZE
;
261 size
-= MORUS1280_BLOCK_SIZE
;
266 union morus1280_block_in tail
;
268 memcpy(tail
.bytes
, src
, size
);
269 memset(tail
.bytes
+ size
, 0, MORUS1280_BLOCK_SIZE
- size
);
271 crypto_morus1280_load_a(&m
, tail
.bytes
);
272 crypto_morus1280_core(state
, &m
);
273 crypto_morus1280_store_a(tail
.bytes
, &m
);
274 memset(tail
.bytes
+ size
, 0, MORUS1280_BLOCK_SIZE
- size
);
275 crypto_morus1280_load_a(&m
, tail
.bytes
);
276 crypto_morus1280_update(state
, &m
);
278 memcpy(dst
, tail
.bytes
, size
);
282 static void crypto_morus1280_init(struct morus1280_state
*state
,
283 const struct morus1280_block
*key
,
286 static const struct morus1280_block z
= {};
288 union morus1280_block_in tmp
;
291 memcpy(tmp
.bytes
, iv
, MORUS_NONCE_SIZE
);
292 memset(tmp
.bytes
+ MORUS_NONCE_SIZE
, 0,
293 MORUS1280_BLOCK_SIZE
- MORUS_NONCE_SIZE
);
295 crypto_morus1280_load(&state
->s
[0], tmp
.bytes
);
297 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++)
298 state
->s
[2].words
[i
] = U64_C(0xFFFFFFFFFFFFFFFF);
300 state
->s
[4] = crypto_morus1280_const
[0];
302 for (i
= 0; i
< 16; i
++)
303 crypto_morus1280_update(state
, &z
);
305 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++)
306 state
->s
[1].words
[i
] ^= key
->words
[i
];
309 static void crypto_morus1280_process_ad(struct morus1280_state
*state
,
310 struct scatterlist
*sg_src
,
311 unsigned int assoclen
)
313 struct scatter_walk walk
;
314 struct morus1280_block m
;
315 union morus1280_block_in buf
;
316 unsigned int pos
= 0;
318 scatterwalk_start(&walk
, sg_src
);
319 while (assoclen
!= 0) {
320 unsigned int size
= scatterwalk_clamp(&walk
, assoclen
);
321 unsigned int left
= size
;
322 void *mapped
= scatterwalk_map(&walk
);
323 const u8
*src
= (const u8
*)mapped
;
325 if (pos
+ size
>= MORUS1280_BLOCK_SIZE
) {
327 unsigned int fill
= MORUS1280_BLOCK_SIZE
- pos
;
328 memcpy(buf
.bytes
+ pos
, src
, fill
);
330 crypto_morus1280_load_a(&m
, buf
.bytes
);
331 crypto_morus1280_update(state
, &m
);
338 crypto_morus1280_ad(state
, src
, left
);
339 src
+= left
& ~(MORUS1280_BLOCK_SIZE
- 1);
340 left
&= MORUS1280_BLOCK_SIZE
- 1;
343 memcpy(buf
.bytes
+ pos
, src
, left
);
347 scatterwalk_unmap(mapped
);
348 scatterwalk_advance(&walk
, size
);
349 scatterwalk_done(&walk
, 0, assoclen
);
353 memset(buf
.bytes
+ pos
, 0, MORUS1280_BLOCK_SIZE
- pos
);
355 crypto_morus1280_load_a(&m
, buf
.bytes
);
356 crypto_morus1280_update(state
, &m
);
360 static void crypto_morus1280_process_crypt(struct morus1280_state
*state
,
361 struct aead_request
*req
,
362 const struct morus1280_ops
*ops
)
364 struct skcipher_walk walk
;
366 ops
->skcipher_walk_init(&walk
, req
, false);
368 while (walk
.nbytes
) {
369 unsigned int nbytes
= walk
.nbytes
;
371 if (nbytes
< walk
.total
)
372 nbytes
= round_down(nbytes
, walk
.stride
);
374 ops
->crypt_chunk(state
, walk
.dst
.virt
.addr
, walk
.src
.virt
.addr
,
377 skcipher_walk_done(&walk
, walk
.nbytes
- nbytes
);
381 static void crypto_morus1280_final(struct morus1280_state
*state
,
382 struct morus1280_block
*tag_xor
,
383 u64 assoclen
, u64 cryptlen
)
385 struct morus1280_block tmp
;
388 tmp
.words
[0] = assoclen
* 8;
389 tmp
.words
[1] = cryptlen
* 8;
393 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++)
394 state
->s
[4].words
[i
] ^= state
->s
[0].words
[i
];
396 for (i
= 0; i
< 10; i
++)
397 crypto_morus1280_update(state
, &tmp
);
399 crypto_morus1280_core(state
, tag_xor
);
402 static int crypto_morus1280_setkey(struct crypto_aead
*aead
, const u8
*key
,
405 struct morus1280_ctx
*ctx
= crypto_aead_ctx(aead
);
406 union morus1280_block_in tmp
;
408 if (keylen
== MORUS1280_BLOCK_SIZE
)
409 crypto_morus1280_load(&ctx
->key
, key
);
410 else if (keylen
== MORUS1280_BLOCK_SIZE
/ 2) {
411 memcpy(tmp
.bytes
, key
, keylen
);
412 memcpy(tmp
.bytes
+ keylen
, key
, keylen
);
414 crypto_morus1280_load(&ctx
->key
, tmp
.bytes
);
416 crypto_aead_set_flags(aead
, CRYPTO_TFM_RES_BAD_KEY_LEN
);
423 static int crypto_morus1280_setauthsize(struct crypto_aead
*tfm
,
424 unsigned int authsize
)
426 return (authsize
<= MORUS_MAX_AUTH_SIZE
) ? 0 : -EINVAL
;
429 static void crypto_morus1280_crypt(struct aead_request
*req
,
430 struct morus1280_block
*tag_xor
,
431 unsigned int cryptlen
,
432 const struct morus1280_ops
*ops
)
434 struct crypto_aead
*tfm
= crypto_aead_reqtfm(req
);
435 struct morus1280_ctx
*ctx
= crypto_aead_ctx(tfm
);
436 struct morus1280_state state
;
438 crypto_morus1280_init(&state
, &ctx
->key
, req
->iv
);
439 crypto_morus1280_process_ad(&state
, req
->src
, req
->assoclen
);
440 crypto_morus1280_process_crypt(&state
, req
, ops
);
441 crypto_morus1280_final(&state
, tag_xor
, req
->assoclen
, cryptlen
);
444 static int crypto_morus1280_encrypt(struct aead_request
*req
)
446 static const struct morus1280_ops ops
= {
447 .skcipher_walk_init
= skcipher_walk_aead_encrypt
,
448 .crypt_chunk
= crypto_morus1280_encrypt_chunk
,
451 struct crypto_aead
*tfm
= crypto_aead_reqtfm(req
);
452 struct morus1280_block tag
= {};
453 union morus1280_block_in tag_out
;
454 unsigned int authsize
= crypto_aead_authsize(tfm
);
455 unsigned int cryptlen
= req
->cryptlen
;
457 crypto_morus1280_crypt(req
, &tag
, cryptlen
, &ops
);
458 crypto_morus1280_store(tag_out
.bytes
, &tag
);
460 scatterwalk_map_and_copy(tag_out
.bytes
, req
->dst
,
461 req
->assoclen
+ cryptlen
, authsize
, 1);
465 static int crypto_morus1280_decrypt(struct aead_request
*req
)
467 static const struct morus1280_ops ops
= {
468 .skcipher_walk_init
= skcipher_walk_aead_decrypt
,
469 .crypt_chunk
= crypto_morus1280_decrypt_chunk
,
471 static const u8 zeros
[MORUS1280_BLOCK_SIZE
] = {};
473 struct crypto_aead
*tfm
= crypto_aead_reqtfm(req
);
474 union morus1280_block_in tag_in
;
475 struct morus1280_block tag
;
476 unsigned int authsize
= crypto_aead_authsize(tfm
);
477 unsigned int cryptlen
= req
->cryptlen
- authsize
;
479 scatterwalk_map_and_copy(tag_in
.bytes
, req
->src
,
480 req
->assoclen
+ cryptlen
, authsize
, 0);
482 crypto_morus1280_load(&tag
, tag_in
.bytes
);
483 crypto_morus1280_crypt(req
, &tag
, cryptlen
, &ops
);
484 crypto_morus1280_store(tag_in
.bytes
, &tag
);
486 return crypto_memneq(tag_in
.bytes
, zeros
, authsize
) ? -EBADMSG
: 0;
489 static int crypto_morus1280_init_tfm(struct crypto_aead
*tfm
)
494 static void crypto_morus1280_exit_tfm(struct crypto_aead
*tfm
)
498 static struct aead_alg crypto_morus1280_alg
= {
499 .setkey
= crypto_morus1280_setkey
,
500 .setauthsize
= crypto_morus1280_setauthsize
,
501 .encrypt
= crypto_morus1280_encrypt
,
502 .decrypt
= crypto_morus1280_decrypt
,
503 .init
= crypto_morus1280_init_tfm
,
504 .exit
= crypto_morus1280_exit_tfm
,
506 .ivsize
= MORUS_NONCE_SIZE
,
507 .maxauthsize
= MORUS_MAX_AUTH_SIZE
,
508 .chunksize
= MORUS1280_BLOCK_SIZE
,
512 .cra_ctxsize
= sizeof(struct morus1280_ctx
),
517 .cra_name
= "morus1280",
518 .cra_driver_name
= "morus1280-generic",
520 .cra_module
= THIS_MODULE
,
525 static int __init
crypto_morus1280_module_init(void)
527 return crypto_register_aead(&crypto_morus1280_alg
);
530 static void __exit
crypto_morus1280_module_exit(void)
532 crypto_unregister_aead(&crypto_morus1280_alg
);
535 subsys_initcall(crypto_morus1280_module_init
);
536 module_exit(crypto_morus1280_module_exit
);
538 MODULE_LICENSE("GPL");
539 MODULE_AUTHOR("Ondrej Mosnacek <omosnacek@gmail.com>");
540 MODULE_DESCRIPTION("MORUS-1280 AEAD algorithm");
541 MODULE_ALIAS_CRYPTO("morus1280");
542 MODULE_ALIAS_CRYPTO("morus1280-generic");