All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jussi Kivilinna <jussi.kivilinna@iki.fi>
To: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: linux-arm@lists.infradead.org, linux-crypto@vger.kernel.org,
	nico@linaro.org, catalin.marinas@arm.com, steve.capper@arm.com
Subject: Re: [RFC PATCH 2/2] arm64: add support for AES using ARMv8 Crypto Extensions
Date: Sat, 14 Sep 2013 11:08:13 +0300	[thread overview]
Message-ID: <5234196D.9050101@iki.fi> (raw)
In-Reply-To: <1379084886-1178-3-git-send-email-ard.biesheuvel@linaro.org>

On 13.09.2013 18:08, Ard Biesheuvel wrote:
> This adds ARMv8 Crypto Extensions based implemenations of
> AES in CBC, CTR and XTS mode.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
..snip..
> +static int xts_set_key(struct crypto_tfm *tfm, const u8 *in_key,
> +		       unsigned int key_len)
> +{
> +	struct crypto_aes_xts_ctx *ctx = crypto_tfm_ctx(tfm);
> +	u32 *flags = &tfm->crt_flags;
> +	int ret;
> +
> +	ret = crypto_aes_expand_key(&ctx->key1, in_key, key_len/2);
> +	if (!ret)
> +		ret = crypto_aes_expand_key(&ctx->key2, &in_key[key_len/2],
> +					    key_len/2);

Use checkpatch.

> +	if (!ret)
> +		return 0;
> +
> +	*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
> +	return -EINVAL;
> +}
> +
> +static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
> +		       struct scatterlist *src, unsigned int nbytes)
> +{
> +	struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
> +	int err, first, rounds = 6 + ctx->key_length/4;
> +	struct blkcipher_walk walk;
> +	unsigned int blocks;
> +
> +	blkcipher_walk_init(&walk, dst, src, nbytes);
> +	err = blkcipher_walk_virt(desc, &walk);
> +
> +	kernel_neon_begin();

Is sleeping allowed within kernel_neon_begin/end block? If not, you need to
clear CRYPTO_TFM_REQ_MAY_SLEEP on desc->flags. Otherwise blkcipher_walk_done
might sleep.

> +	for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
> +		aesce_cbc_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
> +				  (u8*)ctx->key_enc, rounds, blocks, walk.iv,
> +				  first);
> +
> +		err = blkcipher_walk_done(desc, &walk, blocks * AES_BLOCK_SIZE);
> +	}
> +	kernel_neon_end();
> +
> +	/* non-integral sizes are not supported in CBC */
> +	if (unlikely(walk.nbytes))
> +		err = -EINVAL;

I think blkcipher_walk_done already does this check by comparing against
alg.cra_blocksize.

> +
> +	return err;
> +}
..snip..
> +
> +static int ctr_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
> +		       struct scatterlist *src, unsigned int nbytes)
> +{
> +	struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
> +	int err, first, rounds = 6 + ctx->key_length/4;
> +	struct blkcipher_walk walk;
> +	u8 ctr[AES_BLOCK_SIZE];
> +
> +	blkcipher_walk_init(&walk, dst, src, nbytes);
> +	err = blkcipher_walk_virt(desc, &walk);
> +
> +	memcpy(ctr, walk.iv, AES_BLOCK_SIZE);
> +
> +	kernel_neon_begin();
> +	for (first = 1; (nbytes = walk.nbytes); first = 0) {
> +		aesce_ctr_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
> +				  (u8*)ctx->key_enc, rounds, nbytes, ctr, first);
> +
> +		err = blkcipher_walk_done(desc, &walk, 0);
> +
> +		/* non-integral block *must* be the last one */
> +		if (unlikely(walk.nbytes && (nbytes & (AES_BLOCK_SIZE-1)))) {
> +			err = -EINVAL;

Other CTR implementations do not have this.. not needed?

> +			break;
> +		}
> +	}
..snip..
> +static struct crypto_alg aesce_cbc_algs[] = { {
> +	.cra_name		= "__cbc-aes-aesce",
> +	.cra_driver_name	= "__driver-cbc-aes-aesce",
> +	.cra_priority		= 0,
> +	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
> +	.cra_blocksize		= AES_BLOCK_SIZE,
> +	.cra_ctxsize		= sizeof(struct crypto_aes_ctx),
> +	.cra_alignmask		= 0,
> +	.cra_type		= &crypto_blkcipher_type,
> +	.cra_module		= THIS_MODULE,
> +	.cra_u = {
> +		.blkcipher = {
> +			.min_keysize	= AES_MIN_KEY_SIZE,
> +			.max_keysize	= AES_MAX_KEY_SIZE,
> +			.ivsize		= AES_BLOCK_SIZE,
> +			.setkey		= crypto_aes_set_key,
> +			.encrypt	= cbc_encrypt,
> +			.decrypt	= cbc_decrypt,
> +		},
> +	},
> +}, {
> +	.cra_name		= "__ctr-aes-aesce",
> +	.cra_driver_name	= "__driver-ctr-aes-aesce",
> +	.cra_priority		= 0,
> +	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
> +	.cra_blocksize		= AES_BLOCK_SIZE,

CTR mode is stream cipher, cra_blocksize must be set to 1.

This should have been picked up by in-kernel run-time tests, check
CONFIG_CRYPTO_MANAGER_DISABLE_TESTS (and CONFIG_CRYPTO_TEST/tcrypt
module).

> +	.cra_ctxsize		= sizeof(struct crypto_aes_ctx),
> +	.cra_alignmask		= 0,
> +	.cra_type		= &crypto_blkcipher_type,
> +	.cra_module		= THIS_MODULE,
> +	.cra_u = {
> +		.blkcipher = {
> +			.min_keysize	= AES_MIN_KEY_SIZE,
> +			.max_keysize	= AES_MAX_KEY_SIZE,
> +			.ivsize		= AES_BLOCK_SIZE,
> +			.setkey		= crypto_aes_set_key,
> +			.encrypt	= ctr_encrypt,
> +			.decrypt	= ctr_encrypt,
> +		},
> +	},
> +}, {
> +	.cra_name		= "__xts-aes-aesce",
> +	.cra_driver_name	= "__driver-xts-aes-aesce",
> +	.cra_priority		= 0,
> +	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
> +	.cra_blocksize		= AES_BLOCK_SIZE,
> +	.cra_ctxsize		= sizeof(struct crypto_aes_xts_ctx),
> +	.cra_alignmask		= 0,
> +	.cra_type		= &crypto_blkcipher_type,
> +	.cra_module		= THIS_MODULE,
> +	.cra_u = {
> +		.blkcipher = {
> +			.min_keysize	= 2*AES_MIN_KEY_SIZE,
> +			.max_keysize	= 2*AES_MAX_KEY_SIZE,
> +			.ivsize		= AES_BLOCK_SIZE,
> +			.setkey		= xts_set_key,
> +			.encrypt	= xts_encrypt,
> +			.decrypt	= xts_decrypt,
> +		},
> +	},
> +}, {
> +	.cra_name		= "cbc(aes)",
> +	.cra_driver_name	= "cbc-aes-aesce",
> +	.cra_priority		= 200,
> +	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
> +	.cra_blocksize		= AES_BLOCK_SIZE,
> +	.cra_ctxsize		= sizeof(struct async_helper_ctx),
> +	.cra_alignmask		= 0,
> +	.cra_type		= &crypto_ablkcipher_type,
> +	.cra_module		= THIS_MODULE,
> +	.cra_init		= ablk_init,
> +	.cra_exit		= ablk_exit,
> +	.cra_u = {
> +		.ablkcipher = {
> +			.min_keysize	= AES_MIN_KEY_SIZE,
> +			.max_keysize	= AES_MAX_KEY_SIZE,
> +			.ivsize		= AES_BLOCK_SIZE,
> +			.setkey		= ablk_set_key,
> +			.encrypt	= ablk_encrypt,
> +			.decrypt	= ablk_decrypt,
> +		}
> +	}
> +}, {
> +	.cra_name		= "ctr(aes)",
> +	.cra_driver_name	= "ctr-aes-aesce",
> +	.cra_priority		= 200,
> +	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
> +	.cra_blocksize		= AES_BLOCK_SIZE,

cra_blocksize = 1

> +	.cra_ctxsize		= sizeof(struct async_helper_ctx),
> +	.cra_alignmask		= 0,
..snip..
> +ENTRY(aesce_xts_encrypt)
> +	tst		w7, #1				// first call?
> +	beq		.Lencmore
> +
> +	ld1		{v0.16b}, [x6]
> +	load_round_keys	w4, x2
> +	encrypt_block	v3.16b, v0.16b, w4		// first tweak
> +	load_round_keys	w4, x3
> +	ldr		q4, .Lxts_mul_x
> +	b		.Lencfirst
> +.Lencmore:
> +	NEXT_TWEAK	(v3, v4, v8)
> +.Lencfirst:
> +	subs		x5, x5, #16
> +.Lencloop:
> +	ld1		{v1.16b}, [x1], #16
> +	eor		v0.16b, v1.16b, v3.16b
> +	encrypt_block	v2.16b, v0.16b, w4
> +	eor		v2.16b, v2.16b, v3.16b
> +	st1		{v2.16b}, [x0], #16
> +	beq		.Lencout
> +
> +	NEXT_TWEAK	(v3, v4, v8)
> +	subs		x5, x5, #16
> +	bpl		.Lencloop
> +
> +	sub		x0, x0, #16
> +	add		x5, x5, #16
> +	mov		x2, x0
> +.Lencsteal:
> +	ldrb		w6, [x1], #1
> +	ldrb		w7, [x2, #-16]
> +	strb		w6, [x2, #-16]
> +	strb		w7, [x2], #1
> +	subs		x5, x5, #1
> +	bne		.Lencsteal

Cipher text stealing here is dead-code, since alg.cra_blocksize is set
to 16 bytes.

Currently other XTS implementations do not have CTS either so this is
not really needed anyway atm (crypto/xts.c: "sector sizes which are not
a multiple of 16 bytes are, however currently unsupported").

-Jussi

  reply	other threads:[~2013-09-14  8:08 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-13 15:08 [RFC PATCH 0/2] AES in CBC/CTR/XTS modes using ARMv8 Crypto Extensions Ard Biesheuvel
2013-09-13 15:08 ` [RFC PATCH 1/2] crypto: move ablk_helper out of arch/x86 Ard Biesheuvel
2013-09-14  7:26   ` Jussi Kivilinna
2013-09-13 15:08 ` [RFC PATCH 2/2] arm64: add support for AES using ARMv8 Crypto Extensions Ard Biesheuvel
2013-09-14  8:08   ` Jussi Kivilinna [this message]
2013-09-14 13:30     ` Ard Biesheuvel
2013-09-14 14:11       ` Jussi Kivilinna
2013-09-14 15:18         ` Russell King - ARM Linux
  -- strict thread matches above, loose matches on Subject: below --
2013-09-13 15:40 [RFC PATCH 0/2] AES in CBC/CTR/XTS modes " Ard Biesheuvel
2013-09-13 15:40 ` [RFC PATCH 2/2] arm64: add support for AES " Ard Biesheuvel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5234196D.9050101@iki.fi \
    --to=jussi.kivilinna@iki.fi \
    --cc=ard.biesheuvel@linaro.org \
    --cc=catalin.marinas@arm.com \
    --cc=linux-arm@lists.infradead.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=nico@linaro.org \
    --cc=steve.capper@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.