All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] crypto: aesni - make driver-gcm-aes-aesni helper a proper aead alg
@ 2015-01-23 22:33 Tadeusz Struk
  2015-01-25  8:58 ` Stephan Mueller
  0 siblings, 1 reply; 8+ messages in thread
From: Tadeusz Struk @ 2015-01-23 22:33 UTC (permalink / raw)
  To: herbert; +Cc: smueller, linux-crypto

Changed the __driver-gcm-aes-aesni to be a proper aead algorithm.

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
 arch/x86/crypto/aesni-intel_glue.c |   53 ++++++++++++++++++++++++++----------
 1 file changed, 39 insertions(+), 14 deletions(-)

diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
index 947c6bf..5544ad9 100644
--- a/arch/x86/crypto/aesni-intel_glue.c
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -890,15 +890,12 @@ out_free_ablkcipher:
 	return ret;
 }
 
-static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key,
-						   unsigned int key_len)
+static int common_rfc4106_set_key(struct crypto_aead *aead, const u8 *key,
+				  unsigned int key_len)
 {
 	int ret = 0;
-	struct crypto_tfm *tfm = crypto_aead_tfm(parent);
-	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent);
-	struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
-	struct aesni_rfc4106_gcm_ctx *child_ctx =
-                                 aesni_rfc4106_gcm_ctx_get(cryptd_child);
+	struct crypto_tfm *tfm = crypto_aead_tfm(aead);
+	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(aead);
 	u8 *new_key_align, *new_key_mem = NULL;
 
 	if (key_len < 4) {
@@ -943,20 +940,29 @@ static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key,
 		goto exit;
 	}
 	ret = rfc4106_set_hash_subkey(ctx->hash_subkey, key, key_len);
-	memcpy(child_ctx, ctx, sizeof(*ctx));
 exit:
 	kfree(new_key_mem);
 	return ret;
 }
 
-/* This is the Integrity Check Value (aka the authentication tag length and can
- * be 8, 12 or 16 bytes long. */
-static int rfc4106_set_authsize(struct crypto_aead *parent,
-				unsigned int authsize)
+static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key,
+			   unsigned int key_len)
 {
 	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent);
 	struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
+	struct aesni_rfc4106_gcm_ctx *child_ctx =
+		aesni_rfc4106_gcm_ctx_get(cryptd_child);
+	int ret;
 
+	ret = common_rfc4106_set_key(parent, key, key_len);
+	if (!ret)
+		memcpy(child_ctx, ctx, sizeof(*ctx));
+	return ret;
+}
+
+static int common_rfc4106_set_authsize(struct crypto_aead *aead,
+				       unsigned int authsize)
+{
 	switch (authsize) {
 	case 8:
 	case 12:
@@ -965,11 +971,26 @@ static int rfc4106_set_authsize(struct crypto_aead *parent,
 	default:
 		return -EINVAL;
 	}
-	crypto_aead_crt(parent)->authsize = authsize;
-	crypto_aead_crt(cryptd_child)->authsize = authsize;
+	crypto_aead_crt(aead)->authsize = authsize;
 	return 0;
 }
 
+/* This is the Integrity Check Value (aka the authentication tag length and can
+ * be 8, 12 or 16 bytes long. */
+static int rfc4106_set_authsize(struct crypto_aead *parent,
+				unsigned int authsize)
+{
+	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent);
+	struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
+	int ret;
+
+	ret = common_rfc4106_set_authsize(parent, authsize);
+	if (!ret)
+		ret = common_rfc4106_set_authsize(cryptd_child, authsize);
+
+	return ret;
+}
+
 static int rfc4106_encrypt(struct aead_request *req)
 {
 	int ret;
@@ -1366,8 +1387,12 @@ static struct crypto_alg aesni_algs[] = { {
 	.cra_module		= THIS_MODULE,
 	.cra_u = {
 		.aead = {
+			.setkey		= common_rfc4106_set_key,
+			.setauthsize	= common_rfc4106_set_authsize,
 			.encrypt	= __driver_rfc4106_encrypt,
 			.decrypt	= __driver_rfc4106_decrypt,
+			.ivsize		= 8,
+			.maxauthsize	= 16,
 		},
 	},
 }, {

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] crypto: aesni - make driver-gcm-aes-aesni helper a proper aead alg
  2015-01-23 22:33 [PATCH] crypto: aesni - make driver-gcm-aes-aesni helper a proper aead alg Tadeusz Struk
@ 2015-01-25  8:58 ` Stephan Mueller
  2015-01-25 16:26   ` Tadeusz Struk
  0 siblings, 1 reply; 8+ messages in thread
From: Stephan Mueller @ 2015-01-25  8:58 UTC (permalink / raw)
  To: Tadeusz Struk; +Cc: herbert, linux-crypto

Am Freitag, 23. Januar 2015, 14:33:57 schrieb Tadeusz Struk:

Hi Tadeusz,

> Changed the __driver-gcm-aes-aesni to be a proper aead algorithm.
> 
> Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
> ---
>  arch/x86/crypto/aesni-intel_glue.c |   53
> ++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 14
> deletions(-)
> 
> diff --git a/arch/x86/crypto/aesni-intel_glue.c
> b/arch/x86/crypto/aesni-intel_glue.c index 947c6bf..5544ad9 100644
> --- a/arch/x86/crypto/aesni-intel_glue.c
> +++ b/arch/x86/crypto/aesni-intel_glue.c
> @@ -890,15 +890,12 @@ out_free_ablkcipher:
>  	return ret;
>  }
> 
> -static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key,
> -						   unsigned int key_len)
> +static int common_rfc4106_set_key(struct crypto_aead *aead, const u8 *key,
> +				  unsigned int key_len)
>  {
>  	int ret = 0;
> -	struct crypto_tfm *tfm = crypto_aead_tfm(parent);
> -	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent);
> -	struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
> -	struct aesni_rfc4106_gcm_ctx *child_ctx =
> -                                 aesni_rfc4106_gcm_ctx_get(cryptd_child);
> +	struct crypto_tfm *tfm = crypto_aead_tfm(aead);
> +	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(aead);
>  	u8 *new_key_align, *new_key_mem = NULL;
> 
>  	if (key_len < 4) {
> @@ -943,20 +940,29 @@ static int rfc4106_set_key(struct crypto_aead *parent,
> const u8 *key, goto exit;
>  	}
>  	ret = rfc4106_set_hash_subkey(ctx->hash_subkey, key, key_len);
> -	memcpy(child_ctx, ctx, sizeof(*ctx));
>  exit:
>  	kfree(new_key_mem);
>  	return ret;
>  }
> 
> -/* This is the Integrity Check Value (aka the authentication tag length and
> can - * be 8, 12 or 16 bytes long. */
> -static int rfc4106_set_authsize(struct crypto_aead *parent,
> -				unsigned int authsize)
> +static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key,
> +			   unsigned int key_len)
>  {
>  	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent);
>  	struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
> +	struct aesni_rfc4106_gcm_ctx *child_ctx =
> +		aesni_rfc4106_gcm_ctx_get(cryptd_child);
> +	int ret;
> 
> +	ret = common_rfc4106_set_key(parent, key, key_len);

Shouldn't that one be crypto_aead_setkey, i.e using the regular crypto API 
instead of internal calls?

> +	if (!ret)
> +		memcpy(child_ctx, ctx, sizeof(*ctx));
> +	return ret;
> +}
> +
> +static int common_rfc4106_set_authsize(struct crypto_aead *aead,
> +				       unsigned int authsize)
> +{
>  	switch (authsize) {
>  	case 8:
>  	case 12:
> @@ -965,11 +971,26 @@ static int rfc4106_set_authsize(struct crypto_aead
> *parent, default:
>  		return -EINVAL;
>  	}
> -	crypto_aead_crt(parent)->authsize = authsize;
> -	crypto_aead_crt(cryptd_child)->authsize = authsize;
> +	crypto_aead_crt(aead)->authsize = authsize;
>  	return 0;
>  }
> 
> +/* This is the Integrity Check Value (aka the authentication tag length and
> can + * be 8, 12 or 16 bytes long. */
> +static int rfc4106_set_authsize(struct crypto_aead *parent,
> +				unsigned int authsize)
> +{
> +	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent);
> +	struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
> +	int ret;
> +
> +	ret = common_rfc4106_set_authsize(parent, authsize);

Same here, shouldn't that one be crypto_aead_setauthsize?

> +	if (!ret)
> +		ret = common_rfc4106_set_authsize(cryptd_child, authsize);
> +
> +	return ret;
> +}
> +
>  static int rfc4106_encrypt(struct aead_request *req)
>  {
>  	int ret;
> @@ -1366,8 +1387,12 @@ static struct crypto_alg aesni_algs[] = { {
>  	.cra_module		= THIS_MODULE,
>  	.cra_u = {
>  		.aead = {
> +			.setkey		= common_rfc4106_set_key,
> +			.setauthsize	= common_rfc4106_set_authsize,
>  			.encrypt	= __driver_rfc4106_encrypt,
>  			.decrypt	= __driver_rfc4106_decrypt,
> +			.ivsize		= 8,
> +			.maxauthsize	= 16,
>  		},
>  	},
>  }, {
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


-- 
Ciao
Stephan

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] crypto: aesni - make driver-gcm-aes-aesni helper a proper aead alg
  2015-01-25  8:58 ` Stephan Mueller
@ 2015-01-25 16:26   ` Tadeusz Struk
  2015-01-26  0:10     ` Herbert Xu
  0 siblings, 1 reply; 8+ messages in thread
From: Tadeusz Struk @ 2015-01-25 16:26 UTC (permalink / raw)
  To: Stephan Mueller; +Cc: herbert, linux-crypto

Hi Stephan,
On 01/25/2015 12:58 AM, Stephan Mueller wrote:
>> +static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key,
>> > +			   unsigned int key_len)
>> >  {
>> >  	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent);
>> >  	struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
>> > +	struct aesni_rfc4106_gcm_ctx *child_ctx =
>> > +		aesni_rfc4106_gcm_ctx_get(cryptd_child);
>> > +	int ret;
>> > 
>> > +	ret = common_rfc4106_set_key(parent, key, key_len);
> Shouldn't that one be crypto_aead_setkey, i.e using the regular crypto API 
> instead of internal calls?
> 

No, I don't think so. I think that would create an infinite loop.

>> +static int rfc4106_set_authsize(struct crypto_aead *parent,
>> > +				unsigned int authsize)
>> > +{
>> > +	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent);
>> > +	struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
>> > +	int ret;
>> > +
>> > +	ret = common_rfc4106_set_authsize(parent, authsize);
> Same here, shouldn't that one be crypto_aead_setauthsize?
> 

Same here.

Thanks,
Tadeusz

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] crypto: aesni - make driver-gcm-aes-aesni helper a proper aead alg
  2015-01-25 16:26   ` Tadeusz Struk
@ 2015-01-26  0:10     ` Herbert Xu
  2015-01-26 16:58       ` Tadeusz Struk
  0 siblings, 1 reply; 8+ messages in thread
From: Herbert Xu @ 2015-01-26  0:10 UTC (permalink / raw)
  To: Tadeusz Struk; +Cc: Stephan Mueller, linux-crypto

On Sun, Jan 25, 2015 at 08:26:50AM -0800, Tadeusz Struk wrote:
> Hi Stephan,
> On 01/25/2015 12:58 AM, Stephan Mueller wrote:
> >> +static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key,
> >> > +			   unsigned int key_len)
> >> >  {
> >> >  	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent);
> >> >  	struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
> >> > +	struct aesni_rfc4106_gcm_ctx *child_ctx =
> >> > +		aesni_rfc4106_gcm_ctx_get(cryptd_child);
> >> > +	int ret;
> >> > 
> >> > +	ret = common_rfc4106_set_key(parent, key, key_len);
> > Shouldn't that one be crypto_aead_setkey, i.e using the regular crypto API 
> > instead of internal calls?
> 
> No, I don't think so. I think that would create an infinite loop.

So why does it work for ablk_helper but not for aead?

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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] crypto: aesni - make driver-gcm-aes-aesni helper a proper aead alg
  2015-01-26  0:10     ` Herbert Xu
@ 2015-01-26 16:58       ` Tadeusz Struk
  2015-01-26 19:20         ` Stephan Mueller
  0 siblings, 1 reply; 8+ messages in thread
From: Tadeusz Struk @ 2015-01-26 16:58 UTC (permalink / raw)
  To: Herbert Xu; +Cc: Stephan Mueller, linux-crypto

On 01/25/2015 04:10 PM, Herbert Xu wrote:
> On Sun, Jan 25, 2015 at 08:26:50AM -0800, Tadeusz Struk wrote:
>> > Hi Stephan,
>> > On 01/25/2015 12:58 AM, Stephan Mueller wrote:
>>>> > >> +static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key,
>>>>> > >> > +			   unsigned int key_len)
>>>>> > >> >  {
>>>>> > >> >  	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent);
>>>>> > >> >  	struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
>>>>> > >> > +	struct aesni_rfc4106_gcm_ctx *child_ctx =
>>>>> > >> > +		aesni_rfc4106_gcm_ctx_get(cryptd_child);
>>>>> > >> > +	int ret;
>>>>> > >> > 
>>>>> > >> > +	ret = common_rfc4106_set_key(parent, key, key_len);
>>> > > Shouldn't that one be crypto_aead_setkey, i.e using the regular crypto API 
>>> > > instead of internal calls?
>> > 
>> > No, I don't think so. I think that would create an infinite loop.
> So why does it work for ablk_helper but not for aead?

Here we have two instances of crypto_aead algorithm, one the
rfc4106(gcm(aes)), whose setkey points to rfc4106_set_key(), and the
internal helper __gcm-aes-aesni (wrapped in by the cryptd interface),
whose setkey points to common_rfc4106_set_key(). If we would call
crypto_aead_setkey() on the parent from rfc4106_set_key() then we would
invoke the same rfc4106_set_key() function. It would be ok to call the
crypto_aead_setkey() on the child, but what's the point?
What we really want to do is to setup the context (authsize and key) for
both the top level rfc4106(gcm(aes)) and the helper __gcm-aes-aesni. We
can do it by calling the internal function directly or by the regular
crypto API crypto_aead_setkey()/set_authsize() on the child, but I don't
see any difference or benefit of it.
Hope that make sense.
Thanks,
Tadeusz

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] crypto: aesni - make driver-gcm-aes-aesni helper a proper aead alg
  2015-01-26 16:58       ` Tadeusz Struk
@ 2015-01-26 19:20         ` Stephan Mueller
  2015-01-26 20:38           ` Tadeusz Struk
  0 siblings, 1 reply; 8+ messages in thread
From: Stephan Mueller @ 2015-01-26 19:20 UTC (permalink / raw)
  To: Tadeusz Struk; +Cc: Herbert Xu, linux-crypto

Am Montag, 26. Januar 2015, 08:58:33 schrieb Tadeusz Struk:

Hi Tadeusz,

> On 01/25/2015 04:10 PM, Herbert Xu wrote:
> > On Sun, Jan 25, 2015 at 08:26:50AM -0800, Tadeusz Struk wrote:
> >> > Hi Stephan,
> >> > 
> >> > On 01/25/2015 12:58 AM, Stephan Mueller wrote:
> >>>> > >> +static int rfc4106_set_key(struct crypto_aead *parent, const u8
> >>>> > >> *key,
> >>>> > >> 
> >>>>> > >> > +			   unsigned int key_len)
> >>>>> > >> > 
> >>>>> > >> >  {
> >>>>> > >> >  
> >>>>> > >> >  	struct aesni_rfc4106_gcm_ctx *ctx =
> >>>>> > >> >  	aesni_rfc4106_gcm_ctx_get(parent);
> >>>>> > >> >  	struct crypto_aead *cryptd_child =
> >>>>> > >> >  	cryptd_aead_child(ctx->cryptd_tfm);
> >>>>> > >> > 
> >>>>> > >> > +	struct aesni_rfc4106_gcm_ctx *child_ctx =
> >>>>> > >> > +		aesni_rfc4106_gcm_ctx_get(cryptd_child);
> >>>>> > >> > +	int ret;
> >>>>> > >> > 
> >>>>> > >> > +	ret = common_rfc4106_set_key(parent, key, key_len);
> >>> > > 
> >>> > > Shouldn't that one be crypto_aead_setkey, i.e using the regular
> >>> > > crypto API
> >>> > > instead of internal calls?
> >> > 
> >> > No, I don't think so. I think that would create an infinite loop.
> > 
> > So why does it work for ablk_helper but not for aead?
> 
> Here we have two instances of crypto_aead algorithm, one the
> rfc4106(gcm(aes)), whose setkey points to rfc4106_set_key(), and the
> internal helper __gcm-aes-aesni (wrapped in by the cryptd interface),
> whose setkey points to common_rfc4106_set_key(). If we would call
> crypto_aead_setkey() on the parent from rfc4106_set_key() then we would
> invoke the same rfc4106_set_key() function. It would be ok to call the
> crypto_aead_setkey() on the child, but what's the point?

The point is to maintain an onion style framework that is coherent. All other 
ciphers implement it (look at the generic gcm.c).

> What we really want to do is to setup the context (authsize and key) for
> both the top level rfc4106(gcm(aes)) and the helper __gcm-aes-aesni. We
> can do it by calling the internal function directly or by the regular
> crypto API crypto_aead_setkey()/set_authsize() on the child, but I don't
> see any difference or benefit of it.

Then, why do we register the internal __driver "cipher" at all. On the one 
hand, the kernel crypto API is used for some aspects but not for others. Hm...


> Hope that make sense.
> Thanks,
> Tadeusz
> --
> To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


-- 
Ciao
Stephan

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] crypto: aesni - make driver-gcm-aes-aesni helper a proper aead alg
  2015-01-26 19:20         ` Stephan Mueller
@ 2015-01-26 20:38           ` Tadeusz Struk
  0 siblings, 0 replies; 8+ messages in thread
From: Tadeusz Struk @ 2015-01-26 20:38 UTC (permalink / raw)
  To: Stephan Mueller; +Cc: Herbert Xu, linux-crypto

On 01/26/2015 11:20 AM, Stephan Mueller wrote:
>> > Here we have two instances of crypto_aead algorithm, one the
>> > rfc4106(gcm(aes)), whose setkey points to rfc4106_set_key(), and the
>> > internal helper __gcm-aes-aesni (wrapped in by the cryptd interface),
>> > whose setkey points to common_rfc4106_set_key(). If we would call
>> > crypto_aead_setkey() on the parent from rfc4106_set_key() then we would
>> > invoke the same rfc4106_set_key() function. It would be ok to call the
>> > crypto_aead_setkey() on the child, but what's the point?
> The point is to maintain an onion style framework that is coherent. All other 
> ciphers implement it (look at the generic gcm.c).
> 

Hi Stephan,
Ok, to keep it consistent is a good enough reason. I'll send v2 soon.
Thanks,
Tadeusz

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] crypto: aesni - make driver-gcm-aes-aesni helper a proper aead alg
@ 2015-02-06 18:25 Tadeusz Struk
  0 siblings, 0 replies; 8+ messages in thread
From: Tadeusz Struk @ 2015-02-06 18:25 UTC (permalink / raw)
  To: herbert; +Cc: adrian.hoban, linux-crypto, davem

Changed the __driver-gcm-aes-aesni to be a proper aead algorithm.
This required a valid setkey and setauthsize functions to be added and also
some changes to make sure that math context is not corrupted when the alg is
used directly.
Note that the __driver-gcm-aes-aesni should not be used directly by modules
that can use it in interrupt context as we don't have a good fallback mechanism
in this case.

Signed-off-by: Adrian Hoban <adrian.hoban@intel.com>
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
 arch/x86/crypto/aesni-intel_glue.c |  164 ++++++++++++++++++++++++------------
 1 file changed, 110 insertions(+), 54 deletions(-)

diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
index 947c6bf..6893f49 100644
--- a/arch/x86/crypto/aesni-intel_glue.c
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -890,15 +890,12 @@ out_free_ablkcipher:
 	return ret;
 }
 
-static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key,
-						   unsigned int key_len)
+static int common_rfc4106_set_key(struct crypto_aead *aead, const u8 *key,
+				  unsigned int key_len)
 {
 	int ret = 0;
-	struct crypto_tfm *tfm = crypto_aead_tfm(parent);
-	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent);
-	struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
-	struct aesni_rfc4106_gcm_ctx *child_ctx =
-                                 aesni_rfc4106_gcm_ctx_get(cryptd_child);
+	struct crypto_tfm *tfm = crypto_aead_tfm(aead);
+	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(aead);
 	u8 *new_key_align, *new_key_mem = NULL;
 
 	if (key_len < 4) {
@@ -943,20 +940,31 @@ static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key,
 		goto exit;
 	}
 	ret = rfc4106_set_hash_subkey(ctx->hash_subkey, key, key_len);
-	memcpy(child_ctx, ctx, sizeof(*ctx));
 exit:
 	kfree(new_key_mem);
 	return ret;
 }
 
-/* This is the Integrity Check Value (aka the authentication tag length and can
- * be 8, 12 or 16 bytes long. */
-static int rfc4106_set_authsize(struct crypto_aead *parent,
-				unsigned int authsize)
+static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key,
+			   unsigned int key_len)
 {
 	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent);
-	struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
+	struct crypto_aead *child = cryptd_aead_child(ctx->cryptd_tfm);
+	struct aesni_rfc4106_gcm_ctx *c_ctx = aesni_rfc4106_gcm_ctx_get(child);
+	struct cryptd_aead *cryptd_tfm = ctx->cryptd_tfm;
+	int ret;
 
+	ret = crypto_aead_setkey(child, key, key_len);
+	if (!ret) {
+		memcpy(ctx, c_ctx, sizeof(*ctx));
+		ctx->cryptd_tfm = cryptd_tfm;
+	}
+	return ret;
+}
+
+static int common_rfc4106_set_authsize(struct crypto_aead *aead,
+				       unsigned int authsize)
+{
 	switch (authsize) {
 	case 8:
 	case 12:
@@ -965,51 +973,23 @@ static int rfc4106_set_authsize(struct crypto_aead *parent,
 	default:
 		return -EINVAL;
 	}
-	crypto_aead_crt(parent)->authsize = authsize;
-	crypto_aead_crt(cryptd_child)->authsize = authsize;
+	crypto_aead_crt(aead)->authsize = authsize;
 	return 0;
 }
 
-static int rfc4106_encrypt(struct aead_request *req)
-{
-	int ret;
-	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
-	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm);
-
-	if (!irq_fpu_usable()) {
-		struct aead_request *cryptd_req =
-			(struct aead_request *) aead_request_ctx(req);
-		memcpy(cryptd_req, req, sizeof(*req));
-		aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
-		return crypto_aead_encrypt(cryptd_req);
-	} else {
-		struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
-		kernel_fpu_begin();
-		ret = cryptd_child->base.crt_aead.encrypt(req);
-		kernel_fpu_end();
-		return ret;
-	}
-}
-
-static int rfc4106_decrypt(struct aead_request *req)
+/* This is the Integrity Check Value (aka the authentication tag length and can
+ * be 8, 12 or 16 bytes long. */
+static int rfc4106_set_authsize(struct crypto_aead *parent,
+				unsigned int authsize)
 {
+	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent);
+	struct crypto_aead *child = cryptd_aead_child(ctx->cryptd_tfm);
 	int ret;
-	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
-	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm);
 
-	if (!irq_fpu_usable()) {
-		struct aead_request *cryptd_req =
-			(struct aead_request *) aead_request_ctx(req);
-		memcpy(cryptd_req, req, sizeof(*req));
-		aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
-		return crypto_aead_decrypt(cryptd_req);
-	} else {
-		struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
-		kernel_fpu_begin();
-		ret = cryptd_child->base.crt_aead.decrypt(req);
-		kernel_fpu_end();
-		return ret;
-	}
+	ret = crypto_aead_setauthsize(child, authsize);
+	if (!ret)
+		crypto_aead_crt(parent)->authsize = authsize;
+	return ret;
 }
 
 static int __driver_rfc4106_encrypt(struct aead_request *req)
@@ -1185,6 +1165,78 @@ static int __driver_rfc4106_decrypt(struct aead_request *req)
 	}
 	return retval;
 }
+
+static int rfc4106_encrypt(struct aead_request *req)
+{
+	int ret;
+	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
+	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm);
+
+	if (!irq_fpu_usable()) {
+		struct aead_request *cryptd_req =
+			(struct aead_request *) aead_request_ctx(req);
+
+		memcpy(cryptd_req, req, sizeof(*req));
+		aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
+		ret = crypto_aead_encrypt(cryptd_req);
+	} else {
+		kernel_fpu_begin();
+		ret = __driver_rfc4106_encrypt(req);
+		kernel_fpu_end();
+	}
+	return ret;
+}
+
+static int rfc4106_decrypt(struct aead_request *req)
+{
+	int ret;
+	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
+	struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm);
+
+	if (!irq_fpu_usable()) {
+		struct aead_request *cryptd_req =
+			(struct aead_request *) aead_request_ctx(req);
+
+		memcpy(cryptd_req, req, sizeof(*req));
+		aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
+		ret = crypto_aead_decrypt(cryptd_req);
+	} else {
+		kernel_fpu_begin();
+		ret = __driver_rfc4106_decrypt(req);
+		kernel_fpu_end();
+	}
+	return ret;
+}
+
+static int helper_rfc4106_encrypt(struct aead_request *req)
+{
+	int ret;
+
+	if (unlikely(!irq_fpu_usable())) {
+		WARN_ONCE(1, "__gcm-aes-aesni alg used in invalid context");
+		ret = -EINVAL;
+	} else {
+		kernel_fpu_begin();
+		ret = __driver_rfc4106_encrypt(req);
+		kernel_fpu_end();
+	}
+	return ret;
+}
+
+static int helper_rfc4106_decrypt(struct aead_request *req)
+{
+	int ret;
+
+	if (unlikely(!irq_fpu_usable())) {
+		WARN_ONCE(1, "__gcm-aes-aesni alg used in invalid context");
+		ret = -EINVAL;
+	} else {
+		kernel_fpu_begin();
+		ret = __driver_rfc4106_decrypt(req);
+		kernel_fpu_end();
+	}
+	return ret;
+}
 #endif
 
 static struct crypto_alg aesni_algs[] = { {
@@ -1366,8 +1418,12 @@ static struct crypto_alg aesni_algs[] = { {
 	.cra_module		= THIS_MODULE,
 	.cra_u = {
 		.aead = {
-			.encrypt	= __driver_rfc4106_encrypt,
-			.decrypt	= __driver_rfc4106_decrypt,
+			.setkey		= common_rfc4106_set_key,
+			.setauthsize	= common_rfc4106_set_authsize,
+			.encrypt	= helper_rfc4106_encrypt,
+			.decrypt	= helper_rfc4106_decrypt,
+			.ivsize		= 8,
+			.maxauthsize	= 16,
 		},
 	},
 }, {

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-02-06 18:29 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-23 22:33 [PATCH] crypto: aesni - make driver-gcm-aes-aesni helper a proper aead alg Tadeusz Struk
2015-01-25  8:58 ` Stephan Mueller
2015-01-25 16:26   ` Tadeusz Struk
2015-01-26  0:10     ` Herbert Xu
2015-01-26 16:58       ` Tadeusz Struk
2015-01-26 19:20         ` Stephan Mueller
2015-01-26 20:38           ` Tadeusz Struk
2015-02-06 18:25 Tadeusz Struk

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.