Re: [PATCH v3 2/3] s390/crypto: Rework protected key AES for true asynch support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, May 06, 2025 at 04:02:41PM +0200, Harald Freudenberger wrote:
>
> > > +			rc = paes_convert_key(ctx);
> > 
> > At first I thought this was racy, but then I realised that it is not
> > because only the crypto_engine thread gets called with maysleep ==
> > true.  Since there is only one crypto_engine thread this is safe.
> > 
> > I think this is not really obvious though and worthy of a comment to
> > explain the reliance on the single crypto engine thread.
> > 
> 
> This is racy but the code can handle that. The cpacf instruction
> refuses to do any operations if the converted key material (the "protected"
> key)
> is invalid. So it is in fact thinkable and possible to replace an fresh
> protected key with an older (in the meantime invalid) protected key. As the
> cpacf instruction detects this, refuses to operate with an invalid key and
> the calling code triggers a (re-)conversion this does no harm. So it
> is racy but may only lead to additional conversions but never to invalid
> data on en- or decrypted.

Perhaps add this as a comment in the code?

> I am struggling with that. The thing is how to keep this information.
> I extended the request context with a bool field telling me that there
> is/was a request pushed to the engine and thus all following crypto
> operations on this request need to go via engine.
> BUT ... the request context is not initial zeroized and there is no
> init() for a request and thus one does not know on invocation of the
> skcipher encrypt or decrypt function if the value of the bool field
> is taken for serious or needs initialization. Same would happen if
> there is a counter instead - how to initially set the counter value
> to 0? Any hints on this are welcome.

I think the easiest would be to copy how simd + cryptd does it.
In simd we have the same problem of a fallback path through async
cryptd, and we need to keep using that fallback once we start until
it fully drains.

So right after entering encrypt/decrypt, you check whether the
fallback is in use, and if it is, just do that and that's it.
Otherwise continue as usual:

static int simd_skcipher_encrypt(struct skcipher_request *req)
{
	...

	if (!crypto_simd_usable() ||
	    (in_atomic() && cryptd_skcipher_queued(ctx->cryptd_tfm)))
		Take fallback path
	else
		Continue on normal path

So for paes this would look like:

static int paes_skcipher_encrypt(struct skcipher_request *req)
{
	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);

	if (paes_skcipher_queued(tfm))
		return paes_skcipher_fallback(req);

	Continue on normal path

Where paes_skcipher_queued(tfm) is just a simple ref count of the
number of entries queued by that tfm onto the fallback path.  IOW
every time you enqueue something you increase the refcount and
every time you dequeue something you decrease it too.

Cheers,
-- 
Email: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt




[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]
  Powered by Linux