2022-05-06 21:11:02

by Cabiddu, Giovanni

[permalink] [raw]
Subject: [PATCH 10/12] crypto: qat - use memzero_explicit() for algs

Use memzero_explicit(), instead of a memset(.., 0, ..) in the
implementation of the algorithms, for buffers containing sensitive
information to ensure they are wiped out before free.

Cc: [email protected]
Signed-off-by: Giovanni Cabiddu <[email protected]>
Reviewed-by: Adam Guerin <[email protected]>
Reviewed-by: Wojciech Ziemba <[email protected]>
---
drivers/crypto/qat/qat_common/qat_algs.c | 20 +++++++++----------
drivers/crypto/qat/qat_common/qat_asym_algs.c | 20 +++++++++----------
2 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c
index 873533dc43a7..c42df18e02b2 100644
--- a/drivers/crypto/qat/qat_common/qat_algs.c
+++ b/drivers/crypto/qat/qat_common/qat_algs.c
@@ -637,12 +637,12 @@ static int qat_alg_aead_newkey(struct crypto_aead *tfm, const u8 *key,
return 0;

out_free_all:
- memset(ctx->dec_cd, 0, sizeof(struct qat_alg_cd));
+ memzero_explicit(ctx->dec_cd, sizeof(struct qat_alg_cd));
dma_free_coherent(dev, sizeof(struct qat_alg_cd),
ctx->dec_cd, ctx->dec_cd_paddr);
ctx->dec_cd = NULL;
out_free_enc:
- memset(ctx->enc_cd, 0, sizeof(struct qat_alg_cd));
+ memzero_explicit(ctx->enc_cd, sizeof(struct qat_alg_cd));
dma_free_coherent(dev, sizeof(struct qat_alg_cd),
ctx->enc_cd, ctx->enc_cd_paddr);
ctx->enc_cd = NULL;
@@ -1092,12 +1092,12 @@ static int qat_alg_skcipher_newkey(struct qat_alg_skcipher_ctx *ctx,
return 0;

out_free_all:
- memset(ctx->dec_cd, 0, sizeof(*ctx->dec_cd));
+ memzero_explicit(ctx->dec_cd, sizeof(*ctx->dec_cd));
dma_free_coherent(dev, sizeof(*ctx->dec_cd),
ctx->dec_cd, ctx->dec_cd_paddr);
ctx->dec_cd = NULL;
out_free_enc:
- memset(ctx->enc_cd, 0, sizeof(*ctx->enc_cd));
+ memzero_explicit(ctx->enc_cd, sizeof(*ctx->enc_cd));
dma_free_coherent(dev, sizeof(*ctx->enc_cd),
ctx->enc_cd, ctx->enc_cd_paddr);
ctx->enc_cd = NULL;
@@ -1359,12 +1359,12 @@ static void qat_alg_aead_exit(struct crypto_aead *tfm)

dev = &GET_DEV(inst->accel_dev);
if (ctx->enc_cd) {
- memset(ctx->enc_cd, 0, sizeof(struct qat_alg_cd));
+ memzero_explicit(ctx->enc_cd, sizeof(struct qat_alg_cd));
dma_free_coherent(dev, sizeof(struct qat_alg_cd),
ctx->enc_cd, ctx->enc_cd_paddr);
}
if (ctx->dec_cd) {
- memset(ctx->dec_cd, 0, sizeof(struct qat_alg_cd));
+ memzero_explicit(ctx->dec_cd, sizeof(struct qat_alg_cd));
dma_free_coherent(dev, sizeof(struct qat_alg_cd),
ctx->dec_cd, ctx->dec_cd_paddr);
}
@@ -1412,15 +1412,15 @@ static void qat_alg_skcipher_exit_tfm(struct crypto_skcipher *tfm)

dev = &GET_DEV(inst->accel_dev);
if (ctx->enc_cd) {
- memset(ctx->enc_cd, 0,
- sizeof(struct icp_qat_hw_cipher_algo_blk));
+ memzero_explicit(ctx->enc_cd,
+ sizeof(struct icp_qat_hw_cipher_algo_blk));
dma_free_coherent(dev,
sizeof(struct icp_qat_hw_cipher_algo_blk),
ctx->enc_cd, ctx->enc_cd_paddr);
}
if (ctx->dec_cd) {
- memset(ctx->dec_cd, 0,
- sizeof(struct icp_qat_hw_cipher_algo_blk));
+ memzero_explicit(ctx->dec_cd,
+ sizeof(struct icp_qat_hw_cipher_algo_blk));
dma_free_coherent(dev,
sizeof(struct icp_qat_hw_cipher_algo_blk),
ctx->dec_cd, ctx->dec_cd_paddr);
diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c b/drivers/crypto/qat/qat_common/qat_asym_algs.c
index b3badc5bd224..86c7d07435c8 100644
--- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
+++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
@@ -1087,19 +1087,19 @@ static void qat_rsa_setkey_crt(struct qat_rsa_ctx *ctx, struct rsa_key *rsa_key)
return;

free_dq:
- memset(ctx->dq, '\0', half_key_sz);
+ memzero_explicit(ctx->dq, half_key_sz);
dma_free_coherent(dev, half_key_sz, ctx->dq, ctx->dma_dq);
ctx->dq = NULL;
free_dp:
- memset(ctx->dp, '\0', half_key_sz);
+ memzero_explicit(ctx->dp, half_key_sz);
dma_free_coherent(dev, half_key_sz, ctx->dp, ctx->dma_dp);
ctx->dp = NULL;
free_q:
- memset(ctx->q, '\0', half_key_sz);
+ memzero_explicit(ctx->q, half_key_sz);
dma_free_coherent(dev, half_key_sz, ctx->q, ctx->dma_q);
ctx->q = NULL;
free_p:
- memset(ctx->p, '\0', half_key_sz);
+ memzero_explicit(ctx->p, half_key_sz);
dma_free_coherent(dev, half_key_sz, ctx->p, ctx->dma_p);
ctx->p = NULL;
err:
@@ -1116,27 +1116,27 @@ static void qat_rsa_clear_ctx(struct device *dev, struct qat_rsa_ctx *ctx)
if (ctx->e)
dma_free_coherent(dev, ctx->key_sz, ctx->e, ctx->dma_e);
if (ctx->d) {
- memset(ctx->d, '\0', ctx->key_sz);
+ memzero_explicit(ctx->d, ctx->key_sz);
dma_free_coherent(dev, ctx->key_sz, ctx->d, ctx->dma_d);
}
if (ctx->p) {
- memset(ctx->p, '\0', half_key_sz);
+ memzero_explicit(ctx->p, half_key_sz);
dma_free_coherent(dev, half_key_sz, ctx->p, ctx->dma_p);
}
if (ctx->q) {
- memset(ctx->q, '\0', half_key_sz);
+ memzero_explicit(ctx->q, half_key_sz);
dma_free_coherent(dev, half_key_sz, ctx->q, ctx->dma_q);
}
if (ctx->dp) {
- memset(ctx->dp, '\0', half_key_sz);
+ memzero_explicit(ctx->dp, half_key_sz);
dma_free_coherent(dev, half_key_sz, ctx->dp, ctx->dma_dp);
}
if (ctx->dq) {
- memset(ctx->dq, '\0', half_key_sz);
+ memzero_explicit(ctx->dq, half_key_sz);
dma_free_coherent(dev, half_key_sz, ctx->dq, ctx->dma_dq);
}
if (ctx->qinv) {
- memset(ctx->qinv, '\0', half_key_sz);
+ memzero_explicit(ctx->qinv, half_key_sz);
dma_free_coherent(dev, half_key_sz, ctx->qinv, ctx->dma_qinv);
}

--
2.35.1



2022-05-08 14:37:22

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH 10/12] crypto: qat - use memzero_explicit() for algs

On Fri, May 06, 2022 at 09:23:25AM +0100, Giovanni Cabiddu wrote:
> Use memzero_explicit(), instead of a memset(.., 0, ..) in the
> implementation of the algorithms, for buffers containing sensitive
> information to ensure they are wiped out before free.
>
> Cc: [email protected]
> Signed-off-by: Giovanni Cabiddu <[email protected]>
> Reviewed-by: Adam Guerin <[email protected]>
> Reviewed-by: Wojciech Ziemba <[email protected]>
> ---
> drivers/crypto/qat/qat_common/qat_algs.c | 20 +++++++++----------
> drivers/crypto/qat/qat_common/qat_asym_algs.c | 20 +++++++++----------
> 2 files changed, 20 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c
> index 873533dc43a7..c42df18e02b2 100644
> --- a/drivers/crypto/qat/qat_common/qat_algs.c
> +++ b/drivers/crypto/qat/qat_common/qat_algs.c
> @@ -637,12 +637,12 @@ static int qat_alg_aead_newkey(struct crypto_aead *tfm, const u8 *key,
> return 0;
>
> out_free_all:
> - memset(ctx->dec_cd, 0, sizeof(struct qat_alg_cd));
> + memzero_explicit(ctx->dec_cd, sizeof(struct qat_alg_cd));

This is for structure fields, why does memset() not work properly here?
The compiler should always call this, it doesn't know what
dma_free_coherent() does. You are referencing this pointer after the
memset() call so all should be working as intended here.

Because of this, I don't see why this change is needed. Do you have
reports of compilers not calling memset() for all of this properly?

thanks,

greg k-h

2022-05-09 04:25:29

by Cabiddu, Giovanni

[permalink] [raw]
Subject: Re: [PATCH 10/12] crypto: qat - use memzero_explicit() for algs

On Fri, May 06, 2022 at 11:22:39AM +0200, Greg KH wrote:
> On Fri, May 06, 2022 at 09:23:25AM +0100, Giovanni Cabiddu wrote:
> > Use memzero_explicit(), instead of a memset(.., 0, ..) in the
> > implementation of the algorithms, for buffers containing sensitive
> > information to ensure they are wiped out before free.
> >
> > Cc: [email protected]
> > Signed-off-by: Giovanni Cabiddu <[email protected]>
> > Reviewed-by: Adam Guerin <[email protected]>
> > Reviewed-by: Wojciech Ziemba <[email protected]>
> > ---
> > drivers/crypto/qat/qat_common/qat_algs.c | 20 +++++++++----------
> > drivers/crypto/qat/qat_common/qat_asym_algs.c | 20 +++++++++----------
> > 2 files changed, 20 insertions(+), 20 deletions(-)
> >
> > diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c
> > index 873533dc43a7..c42df18e02b2 100644
> > --- a/drivers/crypto/qat/qat_common/qat_algs.c
> > +++ b/drivers/crypto/qat/qat_common/qat_algs.c
> > @@ -637,12 +637,12 @@ static int qat_alg_aead_newkey(struct crypto_aead *tfm, const u8 *key,
> > return 0;
> >
> > out_free_all:
> > - memset(ctx->dec_cd, 0, sizeof(struct qat_alg_cd));
> > + memzero_explicit(ctx->dec_cd, sizeof(struct qat_alg_cd));
>
> This is for structure fields, why does memset() not work properly here?
> The compiler should always call this, it doesn't know what
> dma_free_coherent() does. You are referencing this pointer after the
> memset() call so all should be working as intended here.
>
> Because of this, I don't see why this change is needed. Do you have
> reports of compilers not calling memset() for all of this properly?
Apologies, I had a wrong assumption.
Based on a comment in the memzero_explicit() documentation I assumed it
should be always used to zero sensitive data.

* memzero_explicit - Fill a region of memory (e.g. sensitive
* keying data) with 0s.

I'm going to drop this patch.

Thanks,

--
Giovanni

2022-05-09 09:48:56

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH 10/12] crypto: qat - use memzero_explicit() for algs

On Fri, May 06, 2022 at 10:54:07AM +0100, Giovanni Cabiddu wrote:
> On Fri, May 06, 2022 at 11:22:39AM +0200, Greg KH wrote:
> > On Fri, May 06, 2022 at 09:23:25AM +0100, Giovanni Cabiddu wrote:
> > > Use memzero_explicit(), instead of a memset(.., 0, ..) in the
> > > implementation of the algorithms, for buffers containing sensitive
> > > information to ensure they are wiped out before free.
> > >
> > > Cc: [email protected]
> > > Signed-off-by: Giovanni Cabiddu <[email protected]>
> > > Reviewed-by: Adam Guerin <[email protected]>
> > > Reviewed-by: Wojciech Ziemba <[email protected]>
> > > ---
> > > drivers/crypto/qat/qat_common/qat_algs.c | 20 +++++++++----------
> > > drivers/crypto/qat/qat_common/qat_asym_algs.c | 20 +++++++++----------
> > > 2 files changed, 20 insertions(+), 20 deletions(-)
> > >
> > > diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c
> > > index 873533dc43a7..c42df18e02b2 100644
> > > --- a/drivers/crypto/qat/qat_common/qat_algs.c
> > > +++ b/drivers/crypto/qat/qat_common/qat_algs.c
> > > @@ -637,12 +637,12 @@ static int qat_alg_aead_newkey(struct crypto_aead *tfm, const u8 *key,
> > > return 0;
> > >
> > > out_free_all:
> > > - memset(ctx->dec_cd, 0, sizeof(struct qat_alg_cd));
> > > + memzero_explicit(ctx->dec_cd, sizeof(struct qat_alg_cd));
> >
> > This is for structure fields, why does memset() not work properly here?
> > The compiler should always call this, it doesn't know what
> > dma_free_coherent() does. You are referencing this pointer after the
> > memset() call so all should be working as intended here.
> >
> > Because of this, I don't see why this change is needed. Do you have
> > reports of compilers not calling memset() for all of this properly?
> Apologies, I had a wrong assumption.
> Based on a comment in the memzero_explicit() documentation I assumed it
> should be always used to zero sensitive data.
>
> * memzero_explicit - Fill a region of memory (e.g. sensitive
> * keying data) with 0s.

Yes, that's what it is for, when the compiler thinks it is "smarter than
you" for stack variables.

It's great for functions like this:
int foo(...)
{
struct key secret_key;

do something and set secret_key...

/* All done, clean up and return */
memset(&secret_key, 0, sizeof(secret_key));
return 0;
}

For that, some compilers now go "hey, they just want to set this to 0
and then never touch it again, that is pointless, let's not call
memset() at all!".

But when you call:
memset(foo->key, 0, sizeof(key));
do_something_with_foo(foo);

the compiler can NOT go and ignore the call to memset() as it does not
know what do_something_with_foo() does. Or at least it better not.

Try out this with a small example and look at the asm output for proof.

You aren't the first to be confused about this, I see this happening at
least once a month with a patch to change code like you did. Don't know
why it keeps coming up, is this a checkpatch() recommentation?

thanks,

greg k-h

2022-05-09 10:46:56

by Cabiddu, Giovanni

[permalink] [raw]
Subject: Re: [PATCH 10/12] crypto: qat - use memzero_explicit() for algs

On Fri, May 06, 2022 at 04:38:15PM +0200, Greg KH wrote:
> On Fri, May 06, 2022 at 10:54:07AM +0100, Giovanni Cabiddu wrote:
> > On Fri, May 06, 2022 at 11:22:39AM +0200, Greg KH wrote:
> > > On Fri, May 06, 2022 at 09:23:25AM +0100, Giovanni Cabiddu wrote:
> > > > Use memzero_explicit(), instead of a memset(.., 0, ..) in the
> > > > implementation of the algorithms, for buffers containing sensitive
> > > > information to ensure they are wiped out before free.
> > > >
> > > > Cc: [email protected]
> > > > Signed-off-by: Giovanni Cabiddu <[email protected]>
> > > > Reviewed-by: Adam Guerin <[email protected]>
> > > > Reviewed-by: Wojciech Ziemba <[email protected]>
> > > > ---
> > > > drivers/crypto/qat/qat_common/qat_algs.c | 20 +++++++++----------
> > > > drivers/crypto/qat/qat_common/qat_asym_algs.c | 20 +++++++++----------
> > > > 2 files changed, 20 insertions(+), 20 deletions(-)
> > > >
> > > > diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c
> > > > index 873533dc43a7..c42df18e02b2 100644
> > > > --- a/drivers/crypto/qat/qat_common/qat_algs.c
> > > > +++ b/drivers/crypto/qat/qat_common/qat_algs.c
> > > > @@ -637,12 +637,12 @@ static int qat_alg_aead_newkey(struct crypto_aead *tfm, const u8 *key,
> > > > return 0;
> > > >
> > > > out_free_all:
> > > > - memset(ctx->dec_cd, 0, sizeof(struct qat_alg_cd));
> > > > + memzero_explicit(ctx->dec_cd, sizeof(struct qat_alg_cd));
> > >
> > > This is for structure fields, why does memset() not work properly here?
> > > The compiler should always call this, it doesn't know what
> > > dma_free_coherent() does. You are referencing this pointer after the
> > > memset() call so all should be working as intended here.
> > >
> > > Because of this, I don't see why this change is needed. Do you have
> > > reports of compilers not calling memset() for all of this properly?
> > Apologies, I had a wrong assumption.
> > Based on a comment in the memzero_explicit() documentation I assumed it
> > should be always used to zero sensitive data.
> >
> > * memzero_explicit - Fill a region of memory (e.g. sensitive
> > * keying data) with 0s.
>
> Yes, that's what it is for, when the compiler thinks it is "smarter than
> you" for stack variables.
>
> It's great for functions like this:
> int foo(...)
> {
> struct key secret_key;
>
> do something and set secret_key...
>
> /* All done, clean up and return */
> memset(&secret_key, 0, sizeof(secret_key));
> return 0;
> }
>
> For that, some compilers now go "hey, they just want to set this to 0
> and then never touch it again, that is pointless, let's not call
> memset() at all!".
>
> But when you call:
> memset(foo->key, 0, sizeof(key));
> do_something_with_foo(foo);
>
> the compiler can NOT go and ignore the call to memset() as it does not
> know what do_something_with_foo() does. Or at least it better not.
>
> Try out this with a small example and look at the asm output for proof.
Thanks for the explanation. It is clear now.

>
> You aren't the first to be confused about this, I see this happening at
> least once a month with a patch to change code like you did. Don't know
> why it keeps coming up, is this a checkpatch() recommentation?
It is not a checkpatch recommendation.
I got that assumption looking at kfree_sensitive() which contains a call
to memzero_explicit(). This was introduced in 2020 by
8982ae527fbe ("mm/slab: use memzero_explicit() in kzfree()" when the
function was still called kzfree().
I assume now that the call to memzero_explicit() in kfree_sensitive() is
also redundant, unless I'm missing something.

Regards,

--
Giovanni

2022-05-09 10:54:26

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH 10/12] crypto: qat - use memzero_explicit() for algs

On Mon, May 09, 2022 at 09:50:58AM +0100, Giovanni Cabiddu wrote:
> On Fri, May 06, 2022 at 04:38:15PM +0200, Greg KH wrote:
> > On Fri, May 06, 2022 at 10:54:07AM +0100, Giovanni Cabiddu wrote:
> > > On Fri, May 06, 2022 at 11:22:39AM +0200, Greg KH wrote:
> > > > On Fri, May 06, 2022 at 09:23:25AM +0100, Giovanni Cabiddu wrote:
> > > > > Use memzero_explicit(), instead of a memset(.., 0, ..) in the
> > > > > implementation of the algorithms, for buffers containing sensitive
> > > > > information to ensure they are wiped out before free.
> > > > >
> > > > > Cc: [email protected]
> > > > > Signed-off-by: Giovanni Cabiddu <[email protected]>
> > > > > Reviewed-by: Adam Guerin <[email protected]>
> > > > > Reviewed-by: Wojciech Ziemba <[email protected]>
> > > > > ---
> > > > > drivers/crypto/qat/qat_common/qat_algs.c | 20 +++++++++----------
> > > > > drivers/crypto/qat/qat_common/qat_asym_algs.c | 20 +++++++++----------
> > > > > 2 files changed, 20 insertions(+), 20 deletions(-)
> > > > >
> > > > > diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c
> > > > > index 873533dc43a7..c42df18e02b2 100644
> > > > > --- a/drivers/crypto/qat/qat_common/qat_algs.c
> > > > > +++ b/drivers/crypto/qat/qat_common/qat_algs.c
> > > > > @@ -637,12 +637,12 @@ static int qat_alg_aead_newkey(struct crypto_aead *tfm, const u8 *key,
> > > > > return 0;
> > > > >
> > > > > out_free_all:
> > > > > - memset(ctx->dec_cd, 0, sizeof(struct qat_alg_cd));
> > > > > + memzero_explicit(ctx->dec_cd, sizeof(struct qat_alg_cd));
> > > >
> > > > This is for structure fields, why does memset() not work properly here?
> > > > The compiler should always call this, it doesn't know what
> > > > dma_free_coherent() does. You are referencing this pointer after the
> > > > memset() call so all should be working as intended here.
> > > >
> > > > Because of this, I don't see why this change is needed. Do you have
> > > > reports of compilers not calling memset() for all of this properly?
> > > Apologies, I had a wrong assumption.
> > > Based on a comment in the memzero_explicit() documentation I assumed it
> > > should be always used to zero sensitive data.
> > >
> > > * memzero_explicit - Fill a region of memory (e.g. sensitive
> > > * keying data) with 0s.
> >
> > Yes, that's what it is for, when the compiler thinks it is "smarter than
> > you" for stack variables.
> >
> > It's great for functions like this:
> > int foo(...)
> > {
> > struct key secret_key;
> >
> > do something and set secret_key...
> >
> > /* All done, clean up and return */
> > memset(&secret_key, 0, sizeof(secret_key));
> > return 0;
> > }
> >
> > For that, some compilers now go "hey, they just want to set this to 0
> > and then never touch it again, that is pointless, let's not call
> > memset() at all!".
> >
> > But when you call:
> > memset(foo->key, 0, sizeof(key));
> > do_something_with_foo(foo);
> >
> > the compiler can NOT go and ignore the call to memset() as it does not
> > know what do_something_with_foo() does. Or at least it better not.
> >
> > Try out this with a small example and look at the asm output for proof.
> Thanks for the explanation. It is clear now.
>
> >
> > You aren't the first to be confused about this, I see this happening at
> > least once a month with a patch to change code like you did. Don't know
> > why it keeps coming up, is this a checkpatch() recommentation?
> It is not a checkpatch recommendation.
> I got that assumption looking at kfree_sensitive() which contains a call
> to memzero_explicit(). This was introduced in 2020 by
> 8982ae527fbe ("mm/slab: use memzero_explicit() in kzfree()" when the
> function was still called kzfree().
> I assume now that the call to memzero_explicit() in kfree_sensitive() is
> also redundant, unless I'm missing something.

Maybe it is, it's hard to tell without running some build tests on
different compilers. Try it and see!

thanks,

greg k-h