2 * The MORUS-1280 Authenticated-Encryption Algorithm
4 * Copyright (c) 2016-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 <asm/unaligned.h>
14 #include <crypto/algapi.h>
15 #include <crypto/internal/aead.h>
16 #include <crypto/internal/skcipher.h>
17 #include <crypto/morus_common.h>
18 #include <crypto/scatterwalk.h>
19 #include <linux/err.h>
20 #include <linux/init.h>
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/scatterlist.h>
25 #define MORUS1280_WORD_SIZE 8
26 #define MORUS1280_BLOCK_SIZE (MORUS_BLOCK_WORDS * MORUS1280_WORD_SIZE)
27 #define MORUS1280_BLOCK_ALIGN (__alignof__(__le64))
28 #define MORUS1280_ALIGNED(p) IS_ALIGNED((uintptr_t)p, MORUS1280_BLOCK_ALIGN)
30 struct morus1280_block
{
31 u64 words
[MORUS_BLOCK_WORDS
];
34 union morus1280_block_in
{
35 __le64 words
[MORUS_BLOCK_WORDS
];
36 u8 bytes
[MORUS1280_BLOCK_SIZE
];
39 struct morus1280_state
{
40 struct morus1280_block s
[MORUS_STATE_BLOCKS
];
43 struct morus1280_ctx
{
44 struct morus1280_block key
;
47 struct morus1280_ops
{
48 int (*skcipher_walk_init
)(struct skcipher_walk
*walk
,
49 struct aead_request
*req
, bool atomic
);
51 void (*crypt_chunk
)(struct morus1280_state
*state
,
52 u8
*dst
, const u8
*src
, unsigned int size
);
55 static const struct morus1280_block crypto_morus1280_const
[1] = {
57 U64_C(0x0d08050302010100),
58 U64_C(0x6279e99059372215),
59 U64_C(0xf12fc26d55183ddb),
60 U64_C(0xdd28b57342311120),
64 static void crypto_morus1280_round(struct morus1280_block
*b0
,
65 struct morus1280_block
*b1
,
66 struct morus1280_block
*b2
,
67 struct morus1280_block
*b3
,
68 struct morus1280_block
*b4
,
69 const struct morus1280_block
*m
,
70 unsigned int b
, unsigned int w
)
73 struct morus1280_block tmp
;
75 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++) {
76 b0
->words
[i
] ^= b1
->words
[i
] & b2
->words
[i
];
77 b0
->words
[i
] ^= b3
->words
[i
];
78 b0
->words
[i
] ^= m
->words
[i
];
79 b0
->words
[i
] = rol64(b0
->words
[i
], b
);
83 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++)
84 b3
->words
[(i
+ w
) % MORUS_BLOCK_WORDS
] = tmp
.words
[i
];
87 static void crypto_morus1280_update(struct morus1280_state
*state
,
88 const struct morus1280_block
*m
)
90 static const struct morus1280_block z
= {};
92 struct morus1280_block
*s
= state
->s
;
94 crypto_morus1280_round(&s
[0], &s
[1], &s
[2], &s
[3], &s
[4], &z
, 13, 1);
95 crypto_morus1280_round(&s
[1], &s
[2], &s
[3], &s
[4], &s
[0], m
, 46, 2);
96 crypto_morus1280_round(&s
[2], &s
[3], &s
[4], &s
[0], &s
[1], m
, 38, 3);
97 crypto_morus1280_round(&s
[3], &s
[4], &s
[0], &s
[1], &s
[2], m
, 7, 2);
98 crypto_morus1280_round(&s
[4], &s
[0], &s
[1], &s
[2], &s
[3], m
, 4, 1);
101 static void crypto_morus1280_load_a(struct morus1280_block
*dst
, const u8
*src
)
104 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++) {
105 dst
->words
[i
] = le64_to_cpu(*(const __le64
*)src
);
106 src
+= MORUS1280_WORD_SIZE
;
110 static void crypto_morus1280_load_u(struct morus1280_block
*dst
, const u8
*src
)
113 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++) {
114 dst
->words
[i
] = get_unaligned_le64(src
);
115 src
+= MORUS1280_WORD_SIZE
;
119 static void crypto_morus1280_load(struct morus1280_block
*dst
, const u8
*src
)
121 if (MORUS1280_ALIGNED(src
))
122 crypto_morus1280_load_a(dst
, src
);
124 crypto_morus1280_load_u(dst
, src
);
127 static void crypto_morus1280_store_a(u8
*dst
, const struct morus1280_block
*src
)
130 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++) {
131 *(__le64
*)dst
= cpu_to_le64(src
->words
[i
]);
132 dst
+= MORUS1280_WORD_SIZE
;
136 static void crypto_morus1280_store_u(u8
*dst
, const struct morus1280_block
*src
)
139 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++) {
140 put_unaligned_le64(src
->words
[i
], dst
);
141 dst
+= MORUS1280_WORD_SIZE
;
145 static void crypto_morus1280_store(u8
*dst
, const struct morus1280_block
*src
)
147 if (MORUS1280_ALIGNED(dst
))
148 crypto_morus1280_store_a(dst
, src
);
150 crypto_morus1280_store_u(dst
, src
);
153 static void crypto_morus1280_ad(struct morus1280_state
*state
, const u8
*src
,
156 struct morus1280_block m
;
158 if (MORUS1280_ALIGNED(src
)) {
159 while (size
>= MORUS1280_BLOCK_SIZE
) {
160 crypto_morus1280_load_a(&m
, src
);
161 crypto_morus1280_update(state
, &m
);
163 size
-= MORUS1280_BLOCK_SIZE
;
164 src
+= MORUS1280_BLOCK_SIZE
;
167 while (size
>= MORUS1280_BLOCK_SIZE
) {
168 crypto_morus1280_load_u(&m
, src
);
169 crypto_morus1280_update(state
, &m
);
171 size
-= MORUS1280_BLOCK_SIZE
;
172 src
+= MORUS1280_BLOCK_SIZE
;
177 static void crypto_morus1280_core(const struct morus1280_state
*state
,
178 struct morus1280_block
*blk
)
182 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++)
183 blk
->words
[(i
+ 3) % MORUS_BLOCK_WORDS
] ^= state
->s
[1].words
[i
];
185 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++) {
186 blk
->words
[i
] ^= state
->s
[0].words
[i
];
187 blk
->words
[i
] ^= state
->s
[2].words
[i
] & state
->s
[3].words
[i
];
191 static void crypto_morus1280_encrypt_chunk(struct morus1280_state
*state
,
192 u8
*dst
, const u8
*src
,
195 struct morus1280_block c
, m
;
197 if (MORUS1280_ALIGNED(src
) && MORUS1280_ALIGNED(dst
)) {
198 while (size
>= MORUS1280_BLOCK_SIZE
) {
199 crypto_morus1280_load_a(&m
, src
);
201 crypto_morus1280_core(state
, &c
);
202 crypto_morus1280_store_a(dst
, &c
);
203 crypto_morus1280_update(state
, &m
);
205 src
+= MORUS1280_BLOCK_SIZE
;
206 dst
+= MORUS1280_BLOCK_SIZE
;
207 size
-= MORUS1280_BLOCK_SIZE
;
210 while (size
>= MORUS1280_BLOCK_SIZE
) {
211 crypto_morus1280_load_u(&m
, src
);
213 crypto_morus1280_core(state
, &c
);
214 crypto_morus1280_store_u(dst
, &c
);
215 crypto_morus1280_update(state
, &m
);
217 src
+= MORUS1280_BLOCK_SIZE
;
218 dst
+= MORUS1280_BLOCK_SIZE
;
219 size
-= MORUS1280_BLOCK_SIZE
;
224 union morus1280_block_in tail
;
226 memcpy(tail
.bytes
, src
, size
);
227 memset(tail
.bytes
+ size
, 0, MORUS1280_BLOCK_SIZE
- size
);
229 crypto_morus1280_load_a(&m
, tail
.bytes
);
231 crypto_morus1280_core(state
, &c
);
232 crypto_morus1280_store_a(tail
.bytes
, &c
);
233 crypto_morus1280_update(state
, &m
);
235 memcpy(dst
, tail
.bytes
, size
);
239 static void crypto_morus1280_decrypt_chunk(struct morus1280_state
*state
,
240 u8
*dst
, const u8
*src
,
243 struct morus1280_block m
;
245 if (MORUS1280_ALIGNED(src
) && MORUS1280_ALIGNED(dst
)) {
246 while (size
>= MORUS1280_BLOCK_SIZE
) {
247 crypto_morus1280_load_a(&m
, src
);
248 crypto_morus1280_core(state
, &m
);
249 crypto_morus1280_store_a(dst
, &m
);
250 crypto_morus1280_update(state
, &m
);
252 src
+= MORUS1280_BLOCK_SIZE
;
253 dst
+= MORUS1280_BLOCK_SIZE
;
254 size
-= MORUS1280_BLOCK_SIZE
;
257 while (size
>= MORUS1280_BLOCK_SIZE
) {
258 crypto_morus1280_load_u(&m
, src
);
259 crypto_morus1280_core(state
, &m
);
260 crypto_morus1280_store_u(dst
, &m
);
261 crypto_morus1280_update(state
, &m
);
263 src
+= MORUS1280_BLOCK_SIZE
;
264 dst
+= MORUS1280_BLOCK_SIZE
;
265 size
-= MORUS1280_BLOCK_SIZE
;
270 union morus1280_block_in tail
;
272 memcpy(tail
.bytes
, src
, size
);
273 memset(tail
.bytes
+ size
, 0, MORUS1280_BLOCK_SIZE
- size
);
275 crypto_morus1280_load_a(&m
, tail
.bytes
);
276 crypto_morus1280_core(state
, &m
);
277 crypto_morus1280_store_a(tail
.bytes
, &m
);
278 memset(tail
.bytes
+ size
, 0, MORUS1280_BLOCK_SIZE
- size
);
279 crypto_morus1280_load_a(&m
, tail
.bytes
);
280 crypto_morus1280_update(state
, &m
);
282 memcpy(dst
, tail
.bytes
, size
);
286 static void crypto_morus1280_init(struct morus1280_state
*state
,
287 const struct morus1280_block
*key
,
290 static const struct morus1280_block z
= {};
292 union morus1280_block_in tmp
;
295 memcpy(tmp
.bytes
, iv
, MORUS_NONCE_SIZE
);
296 memset(tmp
.bytes
+ MORUS_NONCE_SIZE
, 0,
297 MORUS1280_BLOCK_SIZE
- MORUS_NONCE_SIZE
);
299 crypto_morus1280_load(&state
->s
[0], tmp
.bytes
);
301 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++)
302 state
->s
[2].words
[i
] = U64_C(0xFFFFFFFFFFFFFFFF);
304 state
->s
[4] = crypto_morus1280_const
[0];
306 for (i
= 0; i
< 16; i
++)
307 crypto_morus1280_update(state
, &z
);
309 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++)
310 state
->s
[1].words
[i
] ^= key
->words
[i
];
313 static void crypto_morus1280_process_ad(struct morus1280_state
*state
,
314 struct scatterlist
*sg_src
,
315 unsigned int assoclen
)
317 struct scatter_walk walk
;
318 struct morus1280_block m
;
319 union morus1280_block_in buf
;
320 unsigned int pos
= 0;
322 scatterwalk_start(&walk
, sg_src
);
323 while (assoclen
!= 0) {
324 unsigned int size
= scatterwalk_clamp(&walk
, assoclen
);
325 unsigned int left
= size
;
326 void *mapped
= scatterwalk_map(&walk
);
327 const u8
*src
= (const u8
*)mapped
;
329 if (pos
+ size
>= MORUS1280_BLOCK_SIZE
) {
331 unsigned int fill
= MORUS1280_BLOCK_SIZE
- pos
;
332 memcpy(buf
.bytes
+ pos
, src
, fill
);
334 crypto_morus1280_load_a(&m
, buf
.bytes
);
335 crypto_morus1280_update(state
, &m
);
342 crypto_morus1280_ad(state
, src
, left
);
343 src
+= left
& ~(MORUS1280_BLOCK_SIZE
- 1);
344 left
&= MORUS1280_BLOCK_SIZE
- 1;
347 memcpy(buf
.bytes
+ pos
, src
, left
);
351 scatterwalk_unmap(mapped
);
352 scatterwalk_advance(&walk
, size
);
353 scatterwalk_done(&walk
, 0, assoclen
);
357 memset(buf
.bytes
+ pos
, 0, MORUS1280_BLOCK_SIZE
- pos
);
359 crypto_morus1280_load_a(&m
, buf
.bytes
);
360 crypto_morus1280_update(state
, &m
);
364 static void crypto_morus1280_process_crypt(struct morus1280_state
*state
,
365 struct aead_request
*req
,
366 const struct morus1280_ops
*ops
)
368 struct skcipher_walk walk
;
372 ops
->skcipher_walk_init(&walk
, req
, false);
374 while (walk
.nbytes
) {
375 src
= walk
.src
.virt
.addr
;
376 dst
= walk
.dst
.virt
.addr
;
378 ops
->crypt_chunk(state
, dst
, src
, walk
.nbytes
);
380 skcipher_walk_done(&walk
, 0);
384 static void crypto_morus1280_final(struct morus1280_state
*state
,
385 struct morus1280_block
*tag_xor
,
386 u64 assoclen
, u64 cryptlen
)
388 struct morus1280_block tmp
;
391 tmp
.words
[0] = assoclen
* 8;
392 tmp
.words
[1] = cryptlen
* 8;
396 for (i
= 0; i
< MORUS_BLOCK_WORDS
; i
++)
397 state
->s
[4].words
[i
] ^= state
->s
[0].words
[i
];
399 for (i
= 0; i
< 10; i
++)
400 crypto_morus1280_update(state
, &tmp
);
402 crypto_morus1280_core(state
, tag_xor
);
405 static int crypto_morus1280_setkey(struct crypto_aead
*aead
, const u8
*key
,
408 struct morus1280_ctx
*ctx
= crypto_aead_ctx(aead
);
409 union morus1280_block_in tmp
;
411 if (keylen
== MORUS1280_BLOCK_SIZE
)
412 crypto_morus1280_load(&ctx
->key
, key
);
413 else if (keylen
== MORUS1280_BLOCK_SIZE
/ 2) {
414 memcpy(tmp
.bytes
, key
, keylen
);
415 memcpy(tmp
.bytes
+ keylen
, key
, keylen
);
417 crypto_morus1280_load(&ctx
->key
, tmp
.bytes
);
419 crypto_aead_set_flags(aead
, CRYPTO_TFM_RES_BAD_KEY_LEN
);
426 static int crypto_morus1280_setauthsize(struct crypto_aead
*tfm
,
427 unsigned int authsize
)
429 return (authsize
<= MORUS_MAX_AUTH_SIZE
) ? 0 : -EINVAL
;
432 static void crypto_morus1280_crypt(struct aead_request
*req
,
433 struct morus1280_block
*tag_xor
,
434 unsigned int cryptlen
,
435 const struct morus1280_ops
*ops
)
437 struct crypto_aead
*tfm
= crypto_aead_reqtfm(req
);
438 struct morus1280_ctx
*ctx
= crypto_aead_ctx(tfm
);
439 struct morus1280_state state
;
441 crypto_morus1280_init(&state
, &ctx
->key
, req
->iv
);
442 crypto_morus1280_process_ad(&state
, req
->src
, req
->assoclen
);
443 crypto_morus1280_process_crypt(&state
, req
, ops
);
444 crypto_morus1280_final(&state
, tag_xor
, req
->assoclen
, cryptlen
);
447 static int crypto_morus1280_encrypt(struct aead_request
*req
)
449 static const struct morus1280_ops ops
= {
450 .skcipher_walk_init
= skcipher_walk_aead_encrypt
,
451 .crypt_chunk
= crypto_morus1280_encrypt_chunk
,
454 struct crypto_aead
*tfm
= crypto_aead_reqtfm(req
);
455 struct morus1280_block tag
= {};
456 union morus1280_block_in tag_out
;
457 unsigned int authsize
= crypto_aead_authsize(tfm
);
458 unsigned int cryptlen
= req
->cryptlen
;
460 crypto_morus1280_crypt(req
, &tag
, cryptlen
, &ops
);
461 crypto_morus1280_store(tag_out
.bytes
, &tag
);
463 scatterwalk_map_and_copy(tag_out
.bytes
, req
->dst
,
464 req
->assoclen
+ cryptlen
, authsize
, 1);
468 static int crypto_morus1280_decrypt(struct aead_request
*req
)
470 static const struct morus1280_ops ops
= {
471 .skcipher_walk_init
= skcipher_walk_aead_decrypt
,
472 .crypt_chunk
= crypto_morus1280_decrypt_chunk
,
474 static const u8 zeros
[MORUS1280_BLOCK_SIZE
] = {};
476 struct crypto_aead
*tfm
= crypto_aead_reqtfm(req
);
477 union morus1280_block_in tag_in
;
478 struct morus1280_block tag
;
479 unsigned int authsize
= crypto_aead_authsize(tfm
);
480 unsigned int cryptlen
= req
->cryptlen
- authsize
;
482 scatterwalk_map_and_copy(tag_in
.bytes
, req
->src
,
483 req
->assoclen
+ cryptlen
, authsize
, 0);
485 crypto_morus1280_load(&tag
, tag_in
.bytes
);
486 crypto_morus1280_crypt(req
, &tag
, cryptlen
, &ops
);
487 crypto_morus1280_store(tag_in
.bytes
, &tag
);
489 return crypto_memneq(tag_in
.bytes
, zeros
, authsize
) ? -EBADMSG
: 0;
492 static int crypto_morus1280_init_tfm(struct crypto_aead
*tfm
)
497 static void crypto_morus1280_exit_tfm(struct crypto_aead
*tfm
)
501 static struct aead_alg crypto_morus1280_alg
= {
502 .setkey
= crypto_morus1280_setkey
,
503 .setauthsize
= crypto_morus1280_setauthsize
,
504 .encrypt
= crypto_morus1280_encrypt
,
505 .decrypt
= crypto_morus1280_decrypt
,
506 .init
= crypto_morus1280_init_tfm
,
507 .exit
= crypto_morus1280_exit_tfm
,
509 .ivsize
= MORUS_NONCE_SIZE
,
510 .maxauthsize
= MORUS_MAX_AUTH_SIZE
,
511 .chunksize
= MORUS1280_BLOCK_SIZE
,
515 .cra_ctxsize
= sizeof(struct morus1280_ctx
),
520 .cra_name
= "morus1280",
521 .cra_driver_name
= "morus1280-generic",
523 .cra_module
= THIS_MODULE
,
528 static int __init
crypto_morus1280_module_init(void)
530 return crypto_register_aead(&crypto_morus1280_alg
);
533 static void __exit
crypto_morus1280_module_exit(void)
535 crypto_unregister_aead(&crypto_morus1280_alg
);
538 module_init(crypto_morus1280_module_init
);
539 module_exit(crypto_morus1280_module_exit
);
541 MODULE_LICENSE("GPL");
542 MODULE_AUTHOR("Ondrej Mosnacek <omosnacek@gmail.com>");
543 MODULE_DESCRIPTION("MORUS-1280 AEAD algorithm");
544 MODULE_ALIAS_CRYPTO("morus1280");
545 MODULE_ALIAS_CRYPTO("morus1280-generic");