* [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.