Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec808bbe authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Herbert Xu
Browse files

crypto: arm64/aes-bs - implement non-SIMD fallback for AES-CTR



Of the various chaining modes implemented by the bit sliced AES driver,
only CTR is exposed as a synchronous cipher, and requires a fallback in
order to remain usable once we update the kernel mode NEON handling logic
to disallow nested use. So wire up the existing CTR fallback C code.

Signed-off-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 611d5324
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -89,6 +89,7 @@ config CRYPTO_AES_ARM64_BS
	depends on KERNEL_MODE_NEON
	depends on KERNEL_MODE_NEON
	select CRYPTO_BLKCIPHER
	select CRYPTO_BLKCIPHER
	select CRYPTO_AES_ARM64_NEON_BLK
	select CRYPTO_AES_ARM64_NEON_BLK
	select CRYPTO_AES_ARM64
	select CRYPTO_SIMD
	select CRYPTO_SIMD


endif
endif
+43 −5
Original line number Original line Diff line number Diff line
/*
/*
 * Bit sliced AES using NEON instructions
 * Bit sliced AES using NEON instructions
 *
 *
 * Copyright (C) 2016 Linaro Ltd <ard.biesheuvel@linaro.org>
 * Copyright (C) 2016 - 2017 Linaro Ltd <ard.biesheuvel@linaro.org>
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * it under the terms of the GNU General Public License version 2 as
@@ -9,12 +9,15 @@
 */
 */


#include <asm/neon.h>
#include <asm/neon.h>
#include <asm/simd.h>
#include <crypto/aes.h>
#include <crypto/aes.h>
#include <crypto/internal/simd.h>
#include <crypto/internal/simd.h>
#include <crypto/internal/skcipher.h>
#include <crypto/internal/skcipher.h>
#include <crypto/xts.h>
#include <crypto/xts.h>
#include <linux/module.h>
#include <linux/module.h>


#include "aes-ctr-fallback.h"

MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
MODULE_LICENSE("GPL v2");
MODULE_LICENSE("GPL v2");


@@ -58,6 +61,11 @@ struct aesbs_cbc_ctx {
	u32			enc[AES_MAX_KEYLENGTH_U32];
	u32			enc[AES_MAX_KEYLENGTH_U32];
};
};


struct aesbs_ctr_ctx {
	struct aesbs_ctx	key;		/* must be first member */
	struct crypto_aes_ctx	fallback;
};

struct aesbs_xts_ctx {
struct aesbs_xts_ctx {
	struct aesbs_ctx	key;
	struct aesbs_ctx	key;
	u32			twkey[AES_MAX_KEYLENGTH_U32];
	u32			twkey[AES_MAX_KEYLENGTH_U32];
@@ -196,6 +204,25 @@ static int cbc_decrypt(struct skcipher_request *req)
	return err;
	return err;
}
}


static int aesbs_ctr_setkey_sync(struct crypto_skcipher *tfm, const u8 *in_key,
				 unsigned int key_len)
{
	struct aesbs_ctr_ctx *ctx = crypto_skcipher_ctx(tfm);
	int err;

	err = crypto_aes_expand_key(&ctx->fallback, in_key, key_len);
	if (err)
		return err;

	ctx->key.rounds = 6 + key_len / 4;

	kernel_neon_begin();
	aesbs_convert_key(ctx->key.rk, ctx->fallback.key_enc, ctx->key.rounds);
	kernel_neon_end();

	return 0;
}

static int ctr_encrypt(struct skcipher_request *req)
static int ctr_encrypt(struct skcipher_request *req)
{
{
	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
@@ -259,6 +286,17 @@ static int aesbs_xts_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
	return aesbs_setkey(tfm, in_key, key_len);
	return aesbs_setkey(tfm, in_key, key_len);
}
}


static int ctr_encrypt_sync(struct skcipher_request *req)
{
	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
	struct aesbs_ctr_ctx *ctx = crypto_skcipher_ctx(tfm);

	if (!may_use_simd())
		return aes_ctr_encrypt_fallback(&ctx->fallback, req);

	return ctr_encrypt(req);
}

static int __xts_crypt(struct skcipher_request *req,
static int __xts_crypt(struct skcipher_request *req,
		       void (*fn)(u8 out[], u8 const in[], u8 const rk[],
		       void (*fn)(u8 out[], u8 const in[], u8 const rk[],
				  int rounds, int blocks, u8 iv[]))
				  int rounds, int blocks, u8 iv[]))
@@ -355,7 +393,7 @@ static struct skcipher_alg aes_algs[] = { {
	.base.cra_driver_name	= "ctr-aes-neonbs",
	.base.cra_driver_name	= "ctr-aes-neonbs",
	.base.cra_priority	= 250 - 1,
	.base.cra_priority	= 250 - 1,
	.base.cra_blocksize	= 1,
	.base.cra_blocksize	= 1,
	.base.cra_ctxsize	= sizeof(struct aesbs_ctx),
	.base.cra_ctxsize	= sizeof(struct aesbs_ctr_ctx),
	.base.cra_module	= THIS_MODULE,
	.base.cra_module	= THIS_MODULE,


	.min_keysize		= AES_MIN_KEY_SIZE,
	.min_keysize		= AES_MIN_KEY_SIZE,
@@ -363,9 +401,9 @@ static struct skcipher_alg aes_algs[] = { {
	.chunksize		= AES_BLOCK_SIZE,
	.chunksize		= AES_BLOCK_SIZE,
	.walksize		= 8 * AES_BLOCK_SIZE,
	.walksize		= 8 * AES_BLOCK_SIZE,
	.ivsize			= AES_BLOCK_SIZE,
	.ivsize			= AES_BLOCK_SIZE,
	.setkey			= aesbs_setkey,
	.setkey			= aesbs_ctr_setkey_sync,
	.encrypt		= ctr_encrypt,
	.encrypt		= ctr_encrypt_sync,
	.decrypt		= ctr_encrypt,
	.decrypt		= ctr_encrypt_sync,
}, {
}, {
	.base.cra_name		= "__xts(aes)",
	.base.cra_name		= "__xts(aes)",
	.base.cra_driver_name	= "__xts-aes-neonbs",
	.base.cra_driver_name	= "__xts-aes-neonbs",