Revision eb72d5207008db54c659fd34f341672decc306ae authored by Charles Keepax on 19 September 2023, 11:03:20 UTC, committed by Linus Torvalds on 23 September 2023, 18:10:23 UTC
The code was accidentally mixing new and old style macros, update the
macros used to remove an unused function warning whilst building with
no PM enabled in the config.

Fixes: ace6d1448138 ("mfd: cs42l43: Add support for cs42l43 core driver")
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://lore.kernel.org/all/20230822114914.340359-1-ckeepax@opensource.cirrus.com/
Reviewed-by: Nathan Chancellor <nathan@kernel.org>
Tested-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Lee Jones <lee@kernel.org>
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 93397d3
Raw File
aria_generic.c
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Cryptographic API.
 *
 * ARIA Cipher Algorithm.
 *
 * Documentation of ARIA can be found in RFC 5794.
 * Copyright (c) 2022 Taehee Yoo <ap420073@gmail.com>
 *
 * Information for ARIA
 *     http://210.104.33.10/ARIA/index-e.html (English)
 *     http://seed.kisa.or.kr/ (Korean)
 *
 * Public domain version is distributed above.
 */

#include <crypto/aria.h>

static const u32 key_rc[20] = {
	0x517cc1b7, 0x27220a94, 0xfe13abe8, 0xfa9a6ee0,
	0x6db14acc, 0x9e21c820, 0xff28b1d5, 0xef5de2b0,
	0xdb92371d, 0x2126e970, 0x03249775, 0x04e8c90e,
	0x517cc1b7, 0x27220a94, 0xfe13abe8, 0xfa9a6ee0,
	0x6db14acc, 0x9e21c820, 0xff28b1d5, 0xef5de2b0
};

static void aria_set_encrypt_key(struct aria_ctx *ctx, const u8 *in_key,
				 unsigned int key_len)
{
	const __be32 *key = (const __be32 *)in_key;
	u32 w0[4], w1[4], w2[4], w3[4];
	u32 reg0, reg1, reg2, reg3;
	const u32 *ck;
	int rkidx = 0;

	ck = &key_rc[(key_len - 16) / 2];

	w0[0] = be32_to_cpu(key[0]);
	w0[1] = be32_to_cpu(key[1]);
	w0[2] = be32_to_cpu(key[2]);
	w0[3] = be32_to_cpu(key[3]);

	reg0 = w0[0] ^ ck[0];
	reg1 = w0[1] ^ ck[1];
	reg2 = w0[2] ^ ck[2];
	reg3 = w0[3] ^ ck[3];

	aria_subst_diff_odd(&reg0, &reg1, &reg2, &reg3);

	if (key_len > 16) {
		w1[0] = be32_to_cpu(key[4]);
		w1[1] = be32_to_cpu(key[5]);
		if (key_len > 24) {
			w1[2] = be32_to_cpu(key[6]);
			w1[3] = be32_to_cpu(key[7]);
		} else {
			w1[2] = 0;
			w1[3] = 0;
		}
	} else {
		w1[0] = 0;
		w1[1] = 0;
		w1[2] = 0;
		w1[3] = 0;
	}

	w1[0] ^= reg0;
	w1[1] ^= reg1;
	w1[2] ^= reg2;
	w1[3] ^= reg3;

	reg0 = w1[0];
	reg1 = w1[1];
	reg2 = w1[2];
	reg3 = w1[3];

	reg0 ^= ck[4];
	reg1 ^= ck[5];
	reg2 ^= ck[6];
	reg3 ^= ck[7];

	aria_subst_diff_even(&reg0, &reg1, &reg2, &reg3);

	reg0 ^= w0[0];
	reg1 ^= w0[1];
	reg2 ^= w0[2];
	reg3 ^= w0[3];

	w2[0] = reg0;
	w2[1] = reg1;
	w2[2] = reg2;
	w2[3] = reg3;

	reg0 ^= ck[8];
	reg1 ^= ck[9];
	reg2 ^= ck[10];
	reg3 ^= ck[11];

	aria_subst_diff_odd(&reg0, &reg1, &reg2, &reg3);

	w3[0] = reg0 ^ w1[0];
	w3[1] = reg1 ^ w1[1];
	w3[2] = reg2 ^ w1[2];
	w3[3] = reg3 ^ w1[3];

	aria_gsrk(ctx->enc_key[rkidx], w0, w1, 19);
	rkidx++;
	aria_gsrk(ctx->enc_key[rkidx], w1, w2, 19);
	rkidx++;
	aria_gsrk(ctx->enc_key[rkidx], w2, w3, 19);
	rkidx++;
	aria_gsrk(ctx->enc_key[rkidx], w3, w0, 19);

	rkidx++;
	aria_gsrk(ctx->enc_key[rkidx], w0, w1, 31);
	rkidx++;
	aria_gsrk(ctx->enc_key[rkidx], w1, w2, 31);
	rkidx++;
	aria_gsrk(ctx->enc_key[rkidx], w2, w3, 31);
	rkidx++;
	aria_gsrk(ctx->enc_key[rkidx], w3, w0, 31);

	rkidx++;
	aria_gsrk(ctx->enc_key[rkidx], w0, w1, 67);
	rkidx++;
	aria_gsrk(ctx->enc_key[rkidx], w1, w2, 67);
	rkidx++;
	aria_gsrk(ctx->enc_key[rkidx], w2, w3, 67);
	rkidx++;
	aria_gsrk(ctx->enc_key[rkidx], w3, w0, 67);

	rkidx++;
	aria_gsrk(ctx->enc_key[rkidx], w0, w1, 97);
	if (key_len > 16) {
		rkidx++;
		aria_gsrk(ctx->enc_key[rkidx], w1, w2, 97);
		rkidx++;
		aria_gsrk(ctx->enc_key[rkidx], w2, w3, 97);

		if (key_len > 24) {
			rkidx++;
			aria_gsrk(ctx->enc_key[rkidx], w3, w0, 97);

			rkidx++;
			aria_gsrk(ctx->enc_key[rkidx], w0, w1, 109);
		}
	}
}

static void aria_set_decrypt_key(struct aria_ctx *ctx)
{
	int i;

	for (i = 0; i < 4; i++) {
		ctx->dec_key[0][i] = ctx->enc_key[ctx->rounds][i];
		ctx->dec_key[ctx->rounds][i] = ctx->enc_key[0][i];
	}

	for (i = 1; i < ctx->rounds; i++) {
		ctx->dec_key[i][0] = aria_m(ctx->enc_key[ctx->rounds - i][0]);
		ctx->dec_key[i][1] = aria_m(ctx->enc_key[ctx->rounds - i][1]);
		ctx->dec_key[i][2] = aria_m(ctx->enc_key[ctx->rounds - i][2]);
		ctx->dec_key[i][3] = aria_m(ctx->enc_key[ctx->rounds - i][3]);

		aria_diff_word(&ctx->dec_key[i][0], &ctx->dec_key[i][1],
			       &ctx->dec_key[i][2], &ctx->dec_key[i][3]);
		aria_diff_byte(&ctx->dec_key[i][1],
			       &ctx->dec_key[i][2], &ctx->dec_key[i][3]);
		aria_diff_word(&ctx->dec_key[i][0], &ctx->dec_key[i][1],
			       &ctx->dec_key[i][2], &ctx->dec_key[i][3]);
	}
}

int aria_set_key(struct crypto_tfm *tfm, const u8 *in_key, unsigned int key_len)
{
	struct aria_ctx *ctx = crypto_tfm_ctx(tfm);

	if (key_len != 16 && key_len != 24 && key_len != 32)
		return -EINVAL;

	BUILD_BUG_ON(sizeof(ctx->enc_key) != 272);
	BUILD_BUG_ON(sizeof(ctx->dec_key) != 272);
	BUILD_BUG_ON(sizeof(int) != sizeof(ctx->rounds));

	ctx->key_length = key_len;
	ctx->rounds = (key_len + 32) / 4;

	aria_set_encrypt_key(ctx, in_key, key_len);
	aria_set_decrypt_key(ctx);

	return 0;
}
EXPORT_SYMBOL_GPL(aria_set_key);

static void __aria_crypt(struct aria_ctx *ctx, u8 *out, const u8 *in,
			 u32 key[][ARIA_RD_KEY_WORDS])
{
	const __be32 *src = (const __be32 *)in;
	__be32 *dst = (__be32 *)out;
	u32 reg0, reg1, reg2, reg3;
	int rounds, rkidx = 0;

	rounds = ctx->rounds;

	reg0 = be32_to_cpu(src[0]);
	reg1 = be32_to_cpu(src[1]);
	reg2 = be32_to_cpu(src[2]);
	reg3 = be32_to_cpu(src[3]);

	aria_add_round_key(key[rkidx], &reg0, &reg1, &reg2, &reg3);
	rkidx++;

	aria_subst_diff_odd(&reg0, &reg1, &reg2, &reg3);
	aria_add_round_key(key[rkidx], &reg0, &reg1, &reg2, &reg3);
	rkidx++;

	while ((rounds -= 2) > 0) {
		aria_subst_diff_even(&reg0, &reg1, &reg2, &reg3);
		aria_add_round_key(key[rkidx], &reg0, &reg1, &reg2, &reg3);
		rkidx++;

		aria_subst_diff_odd(&reg0, &reg1, &reg2, &reg3);
		aria_add_round_key(key[rkidx], &reg0, &reg1, &reg2, &reg3);
		rkidx++;
	}

	reg0 = key[rkidx][0] ^ make_u32((u8)(x1[get_u8(reg0, 0)]),
					(u8)(x2[get_u8(reg0, 1)] >> 8),
					(u8)(s1[get_u8(reg0, 2)]),
					(u8)(s2[get_u8(reg0, 3)]));
	reg1 = key[rkidx][1] ^ make_u32((u8)(x1[get_u8(reg1, 0)]),
					(u8)(x2[get_u8(reg1, 1)] >> 8),
					(u8)(s1[get_u8(reg1, 2)]),
					(u8)(s2[get_u8(reg1, 3)]));
	reg2 = key[rkidx][2] ^ make_u32((u8)(x1[get_u8(reg2, 0)]),
					(u8)(x2[get_u8(reg2, 1)] >> 8),
					(u8)(s1[get_u8(reg2, 2)]),
					(u8)(s2[get_u8(reg2, 3)]));
	reg3 = key[rkidx][3] ^ make_u32((u8)(x1[get_u8(reg3, 0)]),
					(u8)(x2[get_u8(reg3, 1)] >> 8),
					(u8)(s1[get_u8(reg3, 2)]),
					(u8)(s2[get_u8(reg3, 3)]));

	dst[0] = cpu_to_be32(reg0);
	dst[1] = cpu_to_be32(reg1);
	dst[2] = cpu_to_be32(reg2);
	dst[3] = cpu_to_be32(reg3);
}

void aria_encrypt(void *_ctx, u8 *out, const u8 *in)
{
	struct aria_ctx *ctx = (struct aria_ctx *)_ctx;

	__aria_crypt(ctx, out, in, ctx->enc_key);
}
EXPORT_SYMBOL_GPL(aria_encrypt);

void aria_decrypt(void *_ctx, u8 *out, const u8 *in)
{
	struct aria_ctx *ctx = (struct aria_ctx *)_ctx;

	__aria_crypt(ctx, out, in, ctx->dec_key);
}
EXPORT_SYMBOL_GPL(aria_decrypt);

static void __aria_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
	struct aria_ctx *ctx = crypto_tfm_ctx(tfm);

	__aria_crypt(ctx, out, in, ctx->enc_key);
}

static void __aria_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
	struct aria_ctx *ctx = crypto_tfm_ctx(tfm);

	__aria_crypt(ctx, out, in, ctx->dec_key);
}

static struct crypto_alg aria_alg = {
	.cra_name		=	"aria",
	.cra_driver_name	=	"aria-generic",
	.cra_priority		=	100,
	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
	.cra_blocksize		=	ARIA_BLOCK_SIZE,
	.cra_ctxsize		=	sizeof(struct aria_ctx),
	.cra_alignmask		=	3,
	.cra_module		=	THIS_MODULE,
	.cra_u			=	{
		.cipher = {
			.cia_min_keysize	=	ARIA_MIN_KEY_SIZE,
			.cia_max_keysize	=	ARIA_MAX_KEY_SIZE,
			.cia_setkey		=	aria_set_key,
			.cia_encrypt		=	__aria_encrypt,
			.cia_decrypt		=	__aria_decrypt
		}
	}
};

static int __init aria_init(void)
{
	return crypto_register_alg(&aria_alg);
}

static void __exit aria_fini(void)
{
	crypto_unregister_alg(&aria_alg);
}

subsys_initcall(aria_init);
module_exit(aria_fini);

MODULE_DESCRIPTION("ARIA Cipher Algorithm");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Taehee Yoo <ap420073@gmail.com>");
MODULE_ALIAS_CRYPTO("aria");
MODULE_ALIAS_CRYPTO("aria-generic");
back to top