1 /*
2  * The MORUS-1280 Authenticated-Encryption Algorithm
3  *
4  * Copyright (c) 2016-2018 Ondrej Mosnacek <omosnacek@gmail.com>
5  * Copyright (C) 2017-2018 Red Hat, Inc. All rights reserved.
6  *
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)
10  * any later version.
11  */
12 
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>
24 
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)
29 
30 struct morus1280_block {
31 	u64 words[MORUS_BLOCK_WORDS];
32 };
33 
34 union morus1280_block_in {
35 	__le64 words[MORUS_BLOCK_WORDS];
36 	u8 bytes[MORUS1280_BLOCK_SIZE];
37 };
38 
39 struct morus1280_state {
40 	struct morus1280_block s[MORUS_STATE_BLOCKS];
41 };
42 
43 struct morus1280_ctx {
44 	struct morus1280_block key;
45 };
46 
47 struct morus1280_ops {
48 	int (*skcipher_walk_init)(struct skcipher_walk *walk,
49 				  struct aead_request *req, bool atomic);
50 
51 	void (*crypt_chunk)(struct morus1280_state *state,
52 			    u8 *dst, const u8 *src, unsigned int size);
53 };
54 
55 static const struct morus1280_block crypto_morus1280_const[1] = {
56 	{ .words = {
57 		U64_C(0x0d08050302010100),
58 		U64_C(0x6279e99059372215),
59 		U64_C(0xf12fc26d55183ddb),
60 		U64_C(0xdd28b57342311120),
61 	} },
62 };
63 
crypto_morus1280_round(struct morus1280_block * b0,struct morus1280_block * b1,struct morus1280_block * b2,struct morus1280_block * b3,struct morus1280_block * b4,const struct morus1280_block * m,unsigned int b,unsigned int w)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)
71 {
72 	unsigned int i;
73 	struct morus1280_block tmp;
74 
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);
80 	}
81 
82 	tmp = *b3;
83 	for (i = 0; i < MORUS_BLOCK_WORDS; i++)
84 		b3->words[(i + w) % MORUS_BLOCK_WORDS] = tmp.words[i];
85 }
86 
crypto_morus1280_update(struct morus1280_state * state,const struct morus1280_block * m)87 static void crypto_morus1280_update(struct morus1280_state *state,
88 				    const struct morus1280_block *m)
89 {
90 	static const struct morus1280_block z = {};
91 
92 	struct morus1280_block *s = state->s;
93 
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);
99 }
100 
crypto_morus1280_load_a(struct morus1280_block * dst,const u8 * src)101 static void crypto_morus1280_load_a(struct morus1280_block *dst, const u8 *src)
102 {
103 	unsigned int i;
104 	for (i = 0; i < MORUS_BLOCK_WORDS; i++) {
105 		dst->words[i] = le64_to_cpu(*(const __le64 *)src);
106 		src += MORUS1280_WORD_SIZE;
107 	}
108 }
109 
crypto_morus1280_load_u(struct morus1280_block * dst,const u8 * src)110 static void crypto_morus1280_load_u(struct morus1280_block *dst, const u8 *src)
111 {
112 	unsigned int i;
113 	for (i = 0; i < MORUS_BLOCK_WORDS; i++) {
114 		dst->words[i] = get_unaligned_le64(src);
115 		src += MORUS1280_WORD_SIZE;
116 	}
117 }
118 
crypto_morus1280_load(struct morus1280_block * dst,const u8 * src)119 static void crypto_morus1280_load(struct morus1280_block *dst, const u8 *src)
120 {
121 	if (MORUS1280_ALIGNED(src))
122 		crypto_morus1280_load_a(dst, src);
123 	else
124 		crypto_morus1280_load_u(dst, src);
125 }
126 
crypto_morus1280_store_a(u8 * dst,const struct morus1280_block * src)127 static void crypto_morus1280_store_a(u8 *dst, const struct morus1280_block *src)
128 {
129 	unsigned int i;
130 	for (i = 0; i < MORUS_BLOCK_WORDS; i++) {
131 		*(__le64 *)dst = cpu_to_le64(src->words[i]);
132 		dst += MORUS1280_WORD_SIZE;
133 	}
134 }
135 
crypto_morus1280_store_u(u8 * dst,const struct morus1280_block * src)136 static void crypto_morus1280_store_u(u8 *dst, const struct morus1280_block *src)
137 {
138 	unsigned int i;
139 	for (i = 0; i < MORUS_BLOCK_WORDS; i++) {
140 		put_unaligned_le64(src->words[i], dst);
141 		dst += MORUS1280_WORD_SIZE;
142 	}
143 }
144 
crypto_morus1280_store(u8 * dst,const struct morus1280_block * src)145 static void crypto_morus1280_store(u8 *dst, const struct morus1280_block *src)
146 {
147 	if (MORUS1280_ALIGNED(dst))
148 		crypto_morus1280_store_a(dst, src);
149 	else
150 		crypto_morus1280_store_u(dst, src);
151 }
152 
crypto_morus1280_ad(struct morus1280_state * state,const u8 * src,unsigned int size)153 static void crypto_morus1280_ad(struct morus1280_state *state, const u8 *src,
154 				unsigned int size)
155 {
156 	struct morus1280_block m;
157 
158 	if (MORUS1280_ALIGNED(src)) {
159 		while (size >= MORUS1280_BLOCK_SIZE) {
160 			crypto_morus1280_load_a(&m, src);
161 			crypto_morus1280_update(state, &m);
162 
163 			size -= MORUS1280_BLOCK_SIZE;
164 			src += MORUS1280_BLOCK_SIZE;
165 		}
166 	} else {
167 		while (size >= MORUS1280_BLOCK_SIZE) {
168 			crypto_morus1280_load_u(&m, src);
169 			crypto_morus1280_update(state, &m);
170 
171 			size -= MORUS1280_BLOCK_SIZE;
172 			src += MORUS1280_BLOCK_SIZE;
173 		}
174 	}
175 }
176 
crypto_morus1280_core(const struct morus1280_state * state,struct morus1280_block * blk)177 static void crypto_morus1280_core(const struct morus1280_state *state,
178 				  struct morus1280_block *blk)
179 {
180 	unsigned int i;
181 
182 	for (i = 0; i < MORUS_BLOCK_WORDS; i++)
183 		blk->words[(i + 3) % MORUS_BLOCK_WORDS] ^= state->s[1].words[i];
184 
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];
188 	}
189 }
190 
crypto_morus1280_encrypt_chunk(struct morus1280_state * state,u8 * dst,const u8 * src,unsigned int size)191 static void crypto_morus1280_encrypt_chunk(struct morus1280_state *state,
192 					   u8 *dst, const u8 *src,
193 					   unsigned int size)
194 {
195 	struct morus1280_block c, m;
196 
197 	if (MORUS1280_ALIGNED(src) && MORUS1280_ALIGNED(dst)) {
198 		while (size >= MORUS1280_BLOCK_SIZE) {
199 			crypto_morus1280_load_a(&m, src);
200 			c = m;
201 			crypto_morus1280_core(state, &c);
202 			crypto_morus1280_store_a(dst, &c);
203 			crypto_morus1280_update(state, &m);
204 
205 			src += MORUS1280_BLOCK_SIZE;
206 			dst += MORUS1280_BLOCK_SIZE;
207 			size -= MORUS1280_BLOCK_SIZE;
208 		}
209 	} else {
210 		while (size >= MORUS1280_BLOCK_SIZE) {
211 			crypto_morus1280_load_u(&m, src);
212 			c = m;
213 			crypto_morus1280_core(state, &c);
214 			crypto_morus1280_store_u(dst, &c);
215 			crypto_morus1280_update(state, &m);
216 
217 			src += MORUS1280_BLOCK_SIZE;
218 			dst += MORUS1280_BLOCK_SIZE;
219 			size -= MORUS1280_BLOCK_SIZE;
220 		}
221 	}
222 
223 	if (size > 0) {
224 		union morus1280_block_in tail;
225 
226 		memcpy(tail.bytes, src, size);
227 		memset(tail.bytes + size, 0, MORUS1280_BLOCK_SIZE - size);
228 
229 		crypto_morus1280_load_a(&m, tail.bytes);
230 		c = m;
231 		crypto_morus1280_core(state, &c);
232 		crypto_morus1280_store_a(tail.bytes, &c);
233 		crypto_morus1280_update(state, &m);
234 
235 		memcpy(dst, tail.bytes, size);
236 	}
237 }
238 
crypto_morus1280_decrypt_chunk(struct morus1280_state * state,u8 * dst,const u8 * src,unsigned int size)239 static void crypto_morus1280_decrypt_chunk(struct morus1280_state *state,
240 					   u8 *dst, const u8 *src,
241 					   unsigned int size)
242 {
243 	struct morus1280_block m;
244 
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);
251 
252 			src += MORUS1280_BLOCK_SIZE;
253 			dst += MORUS1280_BLOCK_SIZE;
254 			size -= MORUS1280_BLOCK_SIZE;
255 		}
256 	} else {
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);
262 
263 			src += MORUS1280_BLOCK_SIZE;
264 			dst += MORUS1280_BLOCK_SIZE;
265 			size -= MORUS1280_BLOCK_SIZE;
266 		}
267 	}
268 
269 	if (size > 0) {
270 		union morus1280_block_in tail;
271 
272 		memcpy(tail.bytes, src, size);
273 		memset(tail.bytes + size, 0, MORUS1280_BLOCK_SIZE - size);
274 
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);
281 
282 		memcpy(dst, tail.bytes, size);
283 	}
284 }
285 
crypto_morus1280_init(struct morus1280_state * state,const struct morus1280_block * key,const u8 * iv)286 static void crypto_morus1280_init(struct morus1280_state *state,
287 				  const struct morus1280_block *key,
288 				  const u8 *iv)
289 {
290 	static const struct morus1280_block z = {};
291 
292 	union morus1280_block_in tmp;
293 	unsigned int i;
294 
295 	memcpy(tmp.bytes, iv, MORUS_NONCE_SIZE);
296 	memset(tmp.bytes + MORUS_NONCE_SIZE, 0,
297 	       MORUS1280_BLOCK_SIZE - MORUS_NONCE_SIZE);
298 
299 	crypto_morus1280_load(&state->s[0], tmp.bytes);
300 	state->s[1] = *key;
301 	for (i = 0; i < MORUS_BLOCK_WORDS; i++)
302 		state->s[2].words[i] = U64_C(0xFFFFFFFFFFFFFFFF);
303 	state->s[3] = z;
304 	state->s[4] = crypto_morus1280_const[0];
305 
306 	for (i = 0; i < 16; i++)
307 		crypto_morus1280_update(state, &z);
308 
309 	for (i = 0; i < MORUS_BLOCK_WORDS; i++)
310 		state->s[1].words[i] ^= key->words[i];
311 }
312 
crypto_morus1280_process_ad(struct morus1280_state * state,struct scatterlist * sg_src,unsigned int assoclen)313 static void crypto_morus1280_process_ad(struct morus1280_state *state,
314 					struct scatterlist *sg_src,
315 					unsigned int assoclen)
316 {
317 	struct scatter_walk walk;
318 	struct morus1280_block m;
319 	union morus1280_block_in buf;
320 	unsigned int pos = 0;
321 
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;
328 
329 		if (pos + size >= MORUS1280_BLOCK_SIZE) {
330 			if (pos > 0) {
331 				unsigned int fill = MORUS1280_BLOCK_SIZE - pos;
332 				memcpy(buf.bytes + pos, src, fill);
333 
334 				crypto_morus1280_load_a(&m, buf.bytes);
335 				crypto_morus1280_update(state, &m);
336 
337 				pos = 0;
338 				left -= fill;
339 				src += fill;
340 			}
341 
342 			crypto_morus1280_ad(state, src, left);
343 			src += left & ~(MORUS1280_BLOCK_SIZE - 1);
344 			left &= MORUS1280_BLOCK_SIZE - 1;
345 		}
346 
347 		memcpy(buf.bytes + pos, src, left);
348 
349 		pos += left;
350 		assoclen -= size;
351 		scatterwalk_unmap(mapped);
352 		scatterwalk_advance(&walk, size);
353 		scatterwalk_done(&walk, 0, assoclen);
354 	}
355 
356 	if (pos > 0) {
357 		memset(buf.bytes + pos, 0, MORUS1280_BLOCK_SIZE - pos);
358 
359 		crypto_morus1280_load_a(&m, buf.bytes);
360 		crypto_morus1280_update(state, &m);
361 	}
362 }
363 
crypto_morus1280_process_crypt(struct morus1280_state * state,struct aead_request * req,const struct morus1280_ops * ops)364 static void crypto_morus1280_process_crypt(struct morus1280_state *state,
365 					   struct aead_request *req,
366 					   const struct morus1280_ops *ops)
367 {
368 	struct skcipher_walk walk;
369 
370 	ops->skcipher_walk_init(&walk, req, false);
371 
372 	while (walk.nbytes) {
373 		unsigned int nbytes = walk.nbytes;
374 
375 		if (nbytes < walk.total)
376 			nbytes = round_down(nbytes, walk.stride);
377 
378 		ops->crypt_chunk(state, walk.dst.virt.addr, walk.src.virt.addr,
379 				 nbytes);
380 
381 		skcipher_walk_done(&walk, walk.nbytes - nbytes);
382 	}
383 }
384 
crypto_morus1280_final(struct morus1280_state * state,struct morus1280_block * tag_xor,u64 assoclen,u64 cryptlen)385 static void crypto_morus1280_final(struct morus1280_state *state,
386 				   struct morus1280_block *tag_xor,
387 				   u64 assoclen, u64 cryptlen)
388 {
389 	struct morus1280_block tmp;
390 	unsigned int i;
391 
392 	tmp.words[0] = assoclen * 8;
393 	tmp.words[1] = cryptlen * 8;
394 	tmp.words[2] = 0;
395 	tmp.words[3] = 0;
396 
397 	for (i = 0; i < MORUS_BLOCK_WORDS; i++)
398 		state->s[4].words[i] ^= state->s[0].words[i];
399 
400 	for (i = 0; i < 10; i++)
401 		crypto_morus1280_update(state, &tmp);
402 
403 	crypto_morus1280_core(state, tag_xor);
404 }
405 
crypto_morus1280_setkey(struct crypto_aead * aead,const u8 * key,unsigned int keylen)406 static int crypto_morus1280_setkey(struct crypto_aead *aead, const u8 *key,
407 				   unsigned int keylen)
408 {
409 	struct morus1280_ctx *ctx = crypto_aead_ctx(aead);
410 	union morus1280_block_in tmp;
411 
412 	if (keylen == MORUS1280_BLOCK_SIZE)
413 		crypto_morus1280_load(&ctx->key, key);
414 	else if (keylen == MORUS1280_BLOCK_SIZE / 2) {
415 		memcpy(tmp.bytes, key, keylen);
416 		memcpy(tmp.bytes + keylen, key, keylen);
417 
418 		crypto_morus1280_load(&ctx->key, tmp.bytes);
419 	} else {
420 		crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
421 		return -EINVAL;
422 	}
423 
424 	return 0;
425 }
426 
crypto_morus1280_setauthsize(struct crypto_aead * tfm,unsigned int authsize)427 static int crypto_morus1280_setauthsize(struct crypto_aead *tfm,
428 					unsigned int authsize)
429 {
430 	return (authsize <= MORUS_MAX_AUTH_SIZE) ? 0 : -EINVAL;
431 }
432 
crypto_morus1280_crypt(struct aead_request * req,struct morus1280_block * tag_xor,unsigned int cryptlen,const struct morus1280_ops * ops)433 static void crypto_morus1280_crypt(struct aead_request *req,
434 				   struct morus1280_block *tag_xor,
435 				   unsigned int cryptlen,
436 				   const struct morus1280_ops *ops)
437 {
438 	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
439 	struct morus1280_ctx *ctx = crypto_aead_ctx(tfm);
440 	struct morus1280_state state;
441 
442 	crypto_morus1280_init(&state, &ctx->key, req->iv);
443 	crypto_morus1280_process_ad(&state, req->src, req->assoclen);
444 	crypto_morus1280_process_crypt(&state, req, ops);
445 	crypto_morus1280_final(&state, tag_xor, req->assoclen, cryptlen);
446 }
447 
crypto_morus1280_encrypt(struct aead_request * req)448 static int crypto_morus1280_encrypt(struct aead_request *req)
449 {
450 	static const struct morus1280_ops ops = {
451 		.skcipher_walk_init = skcipher_walk_aead_encrypt,
452 		.crypt_chunk = crypto_morus1280_encrypt_chunk,
453 	};
454 
455 	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
456 	struct morus1280_block tag = {};
457 	union morus1280_block_in tag_out;
458 	unsigned int authsize = crypto_aead_authsize(tfm);
459 	unsigned int cryptlen = req->cryptlen;
460 
461 	crypto_morus1280_crypt(req, &tag, cryptlen, &ops);
462 	crypto_morus1280_store(tag_out.bytes, &tag);
463 
464 	scatterwalk_map_and_copy(tag_out.bytes, req->dst,
465 				 req->assoclen + cryptlen, authsize, 1);
466 	return 0;
467 }
468 
crypto_morus1280_decrypt(struct aead_request * req)469 static int crypto_morus1280_decrypt(struct aead_request *req)
470 {
471 	static const struct morus1280_ops ops = {
472 		.skcipher_walk_init = skcipher_walk_aead_decrypt,
473 		.crypt_chunk = crypto_morus1280_decrypt_chunk,
474 	};
475 	static const u8 zeros[MORUS1280_BLOCK_SIZE] = {};
476 
477 	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
478 	union morus1280_block_in tag_in;
479 	struct morus1280_block tag;
480 	unsigned int authsize = crypto_aead_authsize(tfm);
481 	unsigned int cryptlen = req->cryptlen - authsize;
482 
483 	scatterwalk_map_and_copy(tag_in.bytes, req->src,
484 				 req->assoclen + cryptlen, authsize, 0);
485 
486 	crypto_morus1280_load(&tag, tag_in.bytes);
487 	crypto_morus1280_crypt(req, &tag, cryptlen, &ops);
488 	crypto_morus1280_store(tag_in.bytes, &tag);
489 
490 	return crypto_memneq(tag_in.bytes, zeros, authsize) ? -EBADMSG : 0;
491 }
492 
crypto_morus1280_init_tfm(struct crypto_aead * tfm)493 static int crypto_morus1280_init_tfm(struct crypto_aead *tfm)
494 {
495 	return 0;
496 }
497 
crypto_morus1280_exit_tfm(struct crypto_aead * tfm)498 static void crypto_morus1280_exit_tfm(struct crypto_aead *tfm)
499 {
500 }
501 
502 static struct aead_alg crypto_morus1280_alg = {
503 	.setkey = crypto_morus1280_setkey,
504 	.setauthsize = crypto_morus1280_setauthsize,
505 	.encrypt = crypto_morus1280_encrypt,
506 	.decrypt = crypto_morus1280_decrypt,
507 	.init = crypto_morus1280_init_tfm,
508 	.exit = crypto_morus1280_exit_tfm,
509 
510 	.ivsize = MORUS_NONCE_SIZE,
511 	.maxauthsize = MORUS_MAX_AUTH_SIZE,
512 	.chunksize = MORUS1280_BLOCK_SIZE,
513 
514 	.base = {
515 		.cra_blocksize = 1,
516 		.cra_ctxsize = sizeof(struct morus1280_ctx),
517 		.cra_alignmask = 0,
518 
519 		.cra_priority = 100,
520 
521 		.cra_name = "morus1280",
522 		.cra_driver_name = "morus1280-generic",
523 
524 		.cra_module = THIS_MODULE,
525 	}
526 };
527 
528 
crypto_morus1280_module_init(void)529 static int __init crypto_morus1280_module_init(void)
530 {
531 	return crypto_register_aead(&crypto_morus1280_alg);
532 }
533 
crypto_morus1280_module_exit(void)534 static void __exit crypto_morus1280_module_exit(void)
535 {
536 	crypto_unregister_aead(&crypto_morus1280_alg);
537 }
538 
539 module_init(crypto_morus1280_module_init);
540 module_exit(crypto_morus1280_module_exit);
541 
542 MODULE_LICENSE("GPL");
543 MODULE_AUTHOR("Ondrej Mosnacek <omosnacek@gmail.com>");
544 MODULE_DESCRIPTION("MORUS-1280 AEAD algorithm");
545 MODULE_ALIAS_CRYPTO("morus1280");
546 MODULE_ALIAS_CRYPTO("morus1280-generic");
547