Re: [PATCH v2 3/4] crypto: inside-secure - only update the result buffer when provided

2017-12-01 Thread Kamil Konieczny
Hi Herbert,

On 01.12.2017 11:36, Herbert Xu wrote:
> On Fri, Dec 01, 2017 at 11:18:30AM +0100, Kamil Konieczny wrote:
>>
>> Herbert, is it possible for every init/update that areq->result can be NULL,
>> and only for final/update/digit user set it to actual memory ?
>> testmgr.c can check if hash update writes into areq->result and if yes, 
>> then test fails ?
> 
> Yes we should modify testmgr to check that.

I can write patch for it. Should it WARN_ON or treat it as error ?

-- 
Best regards,
Kamil Konieczny
Samsung R&D Institute Poland



Re: [PATCH v2 3/4] crypto: inside-secure - only update the result buffer when provided

2017-12-01 Thread Antoine Tenart
On Fri, Dec 01, 2017 at 11:43:18AM +0100, Kamil Konieczny wrote:
> On 01.12.2017 11:24, Antoine Tenart wrote:
> > 
> > Yes the last_req flag is set for the last request, so when
> > digest/finup/final are called. But no we can't copy the result into the
> > state based on this as an user might want to perform multiple updates,
> > then export the context, to import it again before sending more updates.
> 
> IMHO set them to false in hash update and init, set finish false and last_req 
> true
> for hash final, and set both true for hash finup and digest.
> 
> As Herbert tells in https://www.spinics.net/lists/linux-crypto/msg28658.html
> you should support scenario export + update/finup, so basically export is 
> reading
> state but it do not halt your hash driver.

Except if you import another state in the meantime.

Antoine

-- 
Antoine Ténart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


Re: [PATCH v2 3/4] crypto: inside-secure - only update the result buffer when provided

2017-12-01 Thread Antoine Tenart
Hi Herbert,

On Fri, Dec 01, 2017 at 09:35:52PM +1100, Herbert Xu wrote:
> On Fri, Dec 01, 2017 at 09:11:57AM +0100, Antoine Tenart wrote:
> >
> > I agree this should not be the case.
> > 
> > But:
> > - Other drivers are doing this check (grep "if (!req->result)" or
> >   "if (req->result)" to see some of them).
> > - I see at least one commit fixing the exact same issue I'm facing here,
> >   393897c5156a415533ff85aa381458840417b032:
> > 
> > crypto: ccp - Check for caller result area before using it
> > 
> > For a hash operation, the caller doesn't have to supply a result
> > area on every call so don't use it / update it if it hasn't
> > been supplied.
> > 
> > I'm not entirely sure what was the code path that leads to this, I'll
> > reproduce the issue and try to understand what is going on (I clearly
> > recall having this crash though).
> 
> That's different.  In that case an unconditional copy is made
> regardless of whether the operation is final or update.  That's
> why a check is required.
> 
> If the operation is finup/final/digest then req->result must be
> set and you don't need to check it.

Ah, I didn't understand your point then. Of course ->result should be
allocated for finup/final/digest. The function where I fix this is
called regardless of the operation that was performed, so it can be an
update() as well.

Thanks,
Antoine

-- 
Antoine Ténart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


Re: [PATCH v2 3/4] crypto: inside-secure - only update the result buffer when provided

2017-12-01 Thread Kamil Konieczny
Hi Antoine,

On 01.12.2017 11:24, Antoine Tenart wrote:
> Hi Kamil,
> 
> On Fri, Dec 01, 2017 at 11:18:30AM +0100, Kamil Konieczny wrote:
>> On 01.12.2017 09:11, Antoine Tenart wrote:
>>> - Other drivers are doing this check (grep "if (!req->result)" or
>>>   "if (req->result)" to see some of them).
>>> - I see at least one commit fixing the exact same issue I'm facing here,
>>>   393897c5156a415533ff85aa381458840417b032:
>>>
>>> crypto: ccp - Check for caller result area before using it
>>>
>>> For a hash operation, the caller doesn't have to supply a result
>>> area on every call so don't use it / update it if it hasn't
>>> been supplied.
>>
>> Do you set last_req true for digest/finup/final ? If yes,
>> then you need to copy result only when it is true,
>>
>>  if (sreq->last_req) {
>>  result_sz = crypto_ahash_digestsize(ahash);
>>  memcpy(sreq->state, areq->result, result_sz);
>>  }
> 
> Yes the last_req flag is set for the last request, so when
> digest/finup/final are called. But no we can't copy the result into the
> state based on this as an user might want to perform multiple updates,
> then export the context, to import it again before sending more updates.

IMHO set them to false in hash update and init, set finish false and last_req 
true
for hash final, and set both true for hash finup and digest.

As Herbert tells in https://www.spinics.net/lists/linux-crypto/msg28658.html
you should support scenario export + update/finup, so basically export is 
reading
state but it do not halt your hash driver.

-- 
Best regards,
Kamil Konieczny
Samsung R&D Institute Poland



Re: [PATCH v2 3/4] crypto: inside-secure - only update the result buffer when provided

2017-12-01 Thread Herbert Xu
On Fri, Dec 01, 2017 at 11:18:30AM +0100, Kamil Konieczny wrote:
>
> Herbert, is it possible for every init/update that areq->result can be NULL,
> and only for final/update/digit user set it to actual memory ?
> testmgr.c can check if hash update writes into areq->result and if yes, 
> then test fails ?

Yes we should modify testmgr to check that.

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


Re: [PATCH v2 3/4] crypto: inside-secure - only update the result buffer when provided

2017-12-01 Thread Herbert Xu
On Fri, Dec 01, 2017 at 09:11:57AM +0100, Antoine Tenart wrote:
>
> I agree this should not be the case.
> 
> But:
> - Other drivers are doing this check (grep "if (!req->result)" or
>   "if (req->result)" to see some of them).
> - I see at least one commit fixing the exact same issue I'm facing here,
>   393897c5156a415533ff85aa381458840417b032:
> 
> crypto: ccp - Check for caller result area before using it
> 
> For a hash operation, the caller doesn't have to supply a result
> area on every call so don't use it / update it if it hasn't
> been supplied.
> 
> I'm not entirely sure what was the code path that leads to this, I'll
> reproduce the issue and try to understand what is going on (I clearly
> recall having this crash though).

That's different.  In that case an unconditional copy is made
regardless of whether the operation is final or update.  That's
why a check is required.

If the operation is finup/final/digest then req->result must be
set and you don't need to check it.

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


Re: [PATCH v2 3/4] crypto: inside-secure - only update the result buffer when provided

2017-12-01 Thread Antoine Tenart
Hi Kamil,

On Fri, Dec 01, 2017 at 11:18:30AM +0100, Kamil Konieczny wrote:
> On 01.12.2017 09:11, Antoine Tenart wrote:
> > - Other drivers are doing this check (grep "if (!req->result)" or
> >   "if (req->result)" to see some of them).
> > - I see at least one commit fixing the exact same issue I'm facing here,
> >   393897c5156a415533ff85aa381458840417b032:
> > 
> > crypto: ccp - Check for caller result area before using it
> > 
> > For a hash operation, the caller doesn't have to supply a result
> > area on every call so don't use it / update it if it hasn't
> > been supplied.
> 
> Do you set last_req true for digest/finup/final ? If yes,
> then you need to copy result only when it is true,
> 
>   if (sreq->last_req) {
>   result_sz = crypto_ahash_digestsize(ahash);
>   memcpy(sreq->state, areq->result, result_sz);
>   }

Yes the last_req flag is set for the last request, so when
digest/finup/final are called. But no we can't copy the result into the
state based on this as an user might want to perform multiple updates,
then export the context, to import it again before sending more updates.

Antoine

-- 
Antoine Ténart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


Re: [PATCH v2 3/4] crypto: inside-secure - only update the result buffer when provided

2017-12-01 Thread Kamil Konieczny
Hi All,

On 01.12.2017 09:11, Antoine Tenart wrote:
> Hi Herbert,
> 
> On Fri, Dec 01, 2017 at 11:31:09AM +1100, Herbert Xu wrote:
>> On Thu, Nov 30, 2017 at 10:19:26AM +0100, Kamil Konieczny wrote:
>>>
>>> can the driver get request for final/finup/digest with null req->result ?
>>> If yes (?), such checks can be done before any hardware processing, saving 
>>> time,
>>> for example:
>>
>> This should not be possible through any user-space facing API.
>>
>> If a kernel API user did this then they're just shooting themselves
>> in the foot.
>>
>> So unless there is a valida call path that leads to this then I
>> would say that there is nothing to fix.
> 
> I agree this should not be the case.
> 
> But:
> - Other drivers are doing this check (grep "if (!req->result)" or
>   "if (req->result)" to see some of them).
> - I see at least one commit fixing the exact same issue I'm facing here,
>   393897c5156a415533ff85aa381458840417b032:
> 
> crypto: ccp - Check for caller result area before using it
> 
> For a hash operation, the caller doesn't have to supply a result
> area on every call so don't use it / update it if it hasn't
> been supplied.

Herbert, is it possible for every init/update that areq->result can be NULL,
and only for final/update/digit user set it to actual memory ?
testmgr.c can check if hash update writes into areq->result and if yes, 
then test fails ?

As I understand this, when crypto api user allocates ahash_request, 
crypto allocates memory for itself _plus_ for driver's context. This allocated
ahash_request is "handle" for all subsequent updates/export/import, 
and for last final/finup, so I do not need to copy hash state into areq->result,
but keep it whole time in context, in your code in sreq:

struct safexcel_ahash_req *sreq = ahash_request_ctx(areq);

so here sreq is async hash request context.

Do you set last_req true for digest/finup/final ? If yes,
then you need to copy result only when it is true,

if (sreq->last_req) {
result_sz = crypto_ahash_digestsize(ahash);
memcpy(sreq->state, areq->result, result_sz);
}

I do not read all your code though, so I can be wrong here.
 
> I'm not entirely sure what was the code path that leads to this, I'll
> reproduce the issue and try to understand what is going on (I clearly
> recall having this crash though).
> 
> The crypto API does not enforce this somehow, and this should probably
> be fixed. That might break some users. But it was seen as a valid use
> for some, so we should probably fix this in previous versions of the
> driver anyway.

-- 
Best regards,
Kamil Konieczny
Samsung R&D Institute Poland



Re: [PATCH v2 3/4] crypto: inside-secure - only update the result buffer when provided

2017-12-01 Thread Antoine Tenart
Hi Herbert,

On Fri, Dec 01, 2017 at 11:31:09AM +1100, Herbert Xu wrote:
> On Thu, Nov 30, 2017 at 10:19:26AM +0100, Kamil Konieczny wrote:
> >
> > can the driver get request for final/finup/digest with null req->result ?
> > If yes (?), such checks can be done before any hardware processing, saving 
> > time,
> > for example:
> 
> This should not be possible through any user-space facing API.
> 
> If a kernel API user did this then they're just shooting themselves
> in the foot.
> 
> So unless there is a valida call path that leads to this then I
> would say that there is nothing to fix.

I agree this should not be the case.

But:
- Other drivers are doing this check (grep "if (!req->result)" or
  "if (req->result)" to see some of them).
- I see at least one commit fixing the exact same issue I'm facing here,
  393897c5156a415533ff85aa381458840417b032:

crypto: ccp - Check for caller result area before using it

For a hash operation, the caller doesn't have to supply a result
area on every call so don't use it / update it if it hasn't
been supplied.

I'm not entirely sure what was the code path that leads to this, I'll
reproduce the issue and try to understand what is going on (I clearly
recall having this crash though).

The crypto API does not enforce this somehow, and this should probably
be fixed. That might break some users. But it was seen as a valid use
for some, so we should probably fix this in previous versions of the
driver anyway.

Thanks!
Antoine

-- 
Antoine Ténart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


Re: [PATCH v2 3/4] crypto: inside-secure - only update the result buffer when provided

2017-11-30 Thread Herbert Xu
On Thu, Nov 30, 2017 at 10:19:26AM +0100, Kamil Konieczny wrote:
>
> can the driver get request for final/finup/digest with null req->result ?
> If yes (?), such checks can be done before any hardware processing, saving 
> time,
> for example:

This should not be possible through any user-space facing API.

If a kernel API user did this then they're just shooting themselves
in the foot.

So unless there is a valida call path that leads to this then I
would say that there is nothing to fix.

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


Re: [PATCH v2 3/4] crypto: inside-secure - only update the result buffer when provided

2017-11-30 Thread Antoine Tenart
Hi Kamil,

On Thu, Nov 30, 2017 at 03:10:28PM +0100, Kamil Konieczny wrote:
> On 30.11.2017 13:41, Antoine Tenart wrote:
> > 
> > No, if we do this we'll lose the ability to export the current state.
> 
> So maybe save it into request context:
> 
>   result_sz = crypto_ahash_digestsize(ahash);
>   ctx = ahash_request_ctx(areq);
> 
>   if (sreq->finish)
>   memcpy(sreq->state, areq->result, result_sz);
>   else
>   memcpy(sreq->state, ctx->state, result_sz);

Storing the digest into a driver own buffer could improve the export
ability in some *very rare* cases. If so I would suggest not to deal
with the kind of test you proposed, but to have your own buffer used
each time.

Anyway, this has nothing to do with the fix I'm proposing here, as it
would change the driver's logic, and would solve a complete different
(rare) issue.

The proposal here is to have a simple fix (which is similar to what can
be found in some other drivers), that can easily be backported to avoid
NULL pointer dereferences in older versions of the kernel.

Thanks,
Antoine

-- 
Antoine Ténart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


Re: [PATCH v2 3/4] crypto: inside-secure - only update the result buffer when provided

2017-11-30 Thread Kamil Konieczny

On 30.11.2017 13:41, Antoine Tenart wrote:
> On Thu, Nov 30, 2017 at 12:52:42PM +0100, Kamil Konieczny wrote:
>> On 30.11.2017 10:29, Antoine Tenart wrote:
>>> On Thu, Nov 30, 2017 at 10:19:26AM +0100, Kamil Konieczny wrote:

 can the driver get request for final/finup/digest with null req->result ?
>>>
>>> I don't think that can happen. But having an update called without
>>> req->result provided is a valid call (though it's not well documented).

Yes, this field may be unset until finup/final.
One more to watch out is that in final, you can have areq->nsize != 0 so
you should not use  areq->nsize nor areq->src

>> so maybe:
>>
>>  if (sreq->finish) {
>>  result_sz = crypto_ahash_digestsize(ahash);
>>  memcpy(sreq->state, areq->result, result_sz);
>>  }
> 
> No, if we do this we'll lose the ability to export the current state.

So maybe save it into request context:

result_sz = crypto_ahash_digestsize(ahash);
ctx = ahash_request_ctx(areq);

if (sreq->finish)
memcpy(sreq->state, areq->result, result_sz);
else
memcpy(sreq->state, ctx->state, result_sz);


-- 
Best regards,
Kamil Konieczny
Samsung R&D Institute Poland



Re: [PATCH v2 3/4] crypto: inside-secure - only update the result buffer when provided

2017-11-30 Thread Antoine Tenart
On Thu, Nov 30, 2017 at 12:52:42PM +0100, Kamil Konieczny wrote:
> On 30.11.2017 10:29, Antoine Tenart wrote:
> > On Thu, Nov 30, 2017 at 10:19:26AM +0100, Kamil Konieczny wrote:
> >> can the driver get request for final/finup/digest with null req->result ?
> > 
> > I don't think that can happen. But having an update called without
> > req->result provided is a valid call (though it's not well documented).
> 
> so maybe:
> 
>   if (sreq->finish) {
>   result_sz = crypto_ahash_digestsize(ahash);
>   memcpy(sreq->state, areq->result, result_sz);
>   }

No, if we do this we'll lose the ability to export the current state.

Thanks,
Antoine

-- 
Antoine Ténart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


Re: [PATCH v2 3/4] crypto: inside-secure - only update the result buffer when provided

2017-11-30 Thread Kamil Konieczny
Hi Antoine,

On 30.11.2017 10:29, Antoine Tenart wrote:
> Hi Kamil,
> 
> On Thu, Nov 30, 2017 at 10:19:26AM +0100, Kamil Konieczny wrote:
>> On 28.11.2017 16:42, Antoine Tenart wrote:
>>> The patch fixes the ahash support by only updating the result buffer
>>> when provided. Otherwise the driver could crash with NULL pointer
>>> exceptions, because the ahash caller isn't required to supply a result
>>> buffer on all calls.
>>
>> Can you point to bug crush report ?
> 
> Do you want the crash dump? (It'll only be a "normal" NULL pointer
> dereference).

Ah I see, in this case not.

>>> Fixes: 1b44c5a60c13 ("crypto: inside-secure - add SafeXcel EIP197 crypto 
>>> engine driver")
>>> Signed-off-by: Antoine Tenart 
>>> ---
>>>  drivers/crypto/inside-secure/safexcel_hash.c | 7 ++-
>>>  1 file changed, 6 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/crypto/inside-secure/safexcel_hash.c 
>>> b/drivers/crypto/inside-secure/safexcel_hash.c
>>> index 6135c9f5742c..424f4c5d4d25 100644
>>> --- a/drivers/crypto/inside-secure/safexcel_hash.c
>>> +++ b/drivers/crypto/inside-secure/safexcel_hash.c
>>> @@ -150,7 +150,12 @@ static int safexcel_handle_req_result(struct 
>>> safexcel_crypto_priv *priv, int rin
>>>  
>>> if (sreq->finish)
>>> result_sz = crypto_ahash_digestsize(ahash);
>>> -   memcpy(sreq->state, areq->result, result_sz);
>> [...]
>> can the driver get request for final/finup/digest with null req->result ?
> 
> I don't think that can happen. But having an update called without
> req->result provided is a valid call (though it's not well documented).

so maybe:

if (sreq->finish) {
result_sz = crypto_ahash_digestsize(ahash);
memcpy(sreq->state, areq->result, result_sz);
}

-- 
Best regards,
Kamil Konieczny
Samsung R&D Institute Poland



Re: [PATCH v2 3/4] crypto: inside-secure - only update the result buffer when provided

2017-11-30 Thread Antoine Tenart
Hi Kamil,

On Thu, Nov 30, 2017 at 10:19:26AM +0100, Kamil Konieczny wrote:
> On 28.11.2017 16:42, Antoine Tenart wrote:
> > The patch fixes the ahash support by only updating the result buffer
> > when provided. Otherwise the driver could crash with NULL pointer
> > exceptions, because the ahash caller isn't required to supply a result
> > buffer on all calls.
> 
> Can you point to bug crush report ?

Do you want the crash dump? (It'll only be a "normal" NULL pointer
dereference).

> > Fixes: 1b44c5a60c13 ("crypto: inside-secure - add SafeXcel EIP197 crypto 
> > engine driver")
> > Signed-off-by: Antoine Tenart 
> > ---
> >  drivers/crypto/inside-secure/safexcel_hash.c | 7 ++-
> >  1 file changed, 6 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/crypto/inside-secure/safexcel_hash.c 
> > b/drivers/crypto/inside-secure/safexcel_hash.c
> > index 6135c9f5742c..424f4c5d4d25 100644
> > --- a/drivers/crypto/inside-secure/safexcel_hash.c
> > +++ b/drivers/crypto/inside-secure/safexcel_hash.c
> > @@ -150,7 +150,12 @@ static int safexcel_handle_req_result(struct 
> > safexcel_crypto_priv *priv, int rin
> >  
> > if (sreq->finish)
> > result_sz = crypto_ahash_digestsize(ahash);
> > -   memcpy(sreq->state, areq->result, result_sz);
> > +
> > +   /* The called isn't required to supply a result buffer. Updated it only
> > +* when provided.
> > +*/
> > +   if (areq->result)
> > +   memcpy(sreq->state, areq->result, result_sz);
> >  
> > dma_unmap_sg(priv->dev, areq->src,
> >  sg_nents_for_len(areq->src, areq->nbytes), DMA_TO_DEVICE);
> > 
> 
> can the driver get request for final/finup/digest with null req->result ?

I don't think that can happen. But having an update called without
req->result provided is a valid call (though it's not well documented).

Thanks,
Antoine

-- 
Antoine Ténart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


Re: [PATCH v2 3/4] crypto: inside-secure - only update the result buffer when provided

2017-11-30 Thread Kamil Konieczny
Hi Antoine,

On 28.11.2017 16:42, Antoine Tenart wrote:
> The patch fixes the ahash support by only updating the result buffer
> when provided. Otherwise the driver could crash with NULL pointer
> exceptions, because the ahash caller isn't required to supply a result
> buffer on all calls.

Can you point to bug crush report ?

> Fixes: 1b44c5a60c13 ("crypto: inside-secure - add SafeXcel EIP197 crypto 
> engine driver")
> Signed-off-by: Antoine Tenart 
> ---
>  drivers/crypto/inside-secure/safexcel_hash.c | 7 ++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/crypto/inside-secure/safexcel_hash.c 
> b/drivers/crypto/inside-secure/safexcel_hash.c
> index 6135c9f5742c..424f4c5d4d25 100644
> --- a/drivers/crypto/inside-secure/safexcel_hash.c
> +++ b/drivers/crypto/inside-secure/safexcel_hash.c
> @@ -150,7 +150,12 @@ static int safexcel_handle_req_result(struct 
> safexcel_crypto_priv *priv, int rin
>  
>   if (sreq->finish)
>   result_sz = crypto_ahash_digestsize(ahash);
> - memcpy(sreq->state, areq->result, result_sz);
> +
> + /* The called isn't required to supply a result buffer. Updated it only
> +  * when provided.
> +  */
> + if (areq->result)
> + memcpy(sreq->state, areq->result, result_sz);
>  
>   dma_unmap_sg(priv->dev, areq->src,
>sg_nents_for_len(areq->src, areq->nbytes), DMA_TO_DEVICE);
> 

can the driver get request for final/finup/digest with null req->result ?
If yes (?), such checks can be done before any hardware processing, saving time,
for example:

int hash_final(struct ahash_request *areq)
{
if (!areq->result)
return -EINVAL;
/* normal processing here */
}


-- 
Best regards,
Kamil Konieczny
Samsung R&D Institute Poland