Re: [PATCH v1 2/2] hw_random: timeriomem_rng: Allow setting RNG quality from platform data

2017-05-17 Thread PrasannaKumar Muralidharan
Hi Rick,

Minor comment below.

On 18 May 2017 at 03:59, Rick Altherr  wrote:
> When a hw_random device's quality is non-zero, it will automatically be
> used to fill the kernel's entropy pool.  Since timeriomem_rng is used by
> many different devices, the quality needs to be provided by platform
> data or device tree.
>
> Signed-off-by: Rick Altherr 
> ---
>
>  drivers/char/hw_random/timeriomem-rng.c | 7 +++
>  include/linux/timeriomem-rng.h  | 3 +++
>  2 files changed, 10 insertions(+)
>
> diff --git a/drivers/char/hw_random/timeriomem-rng.c 
> b/drivers/char/hw_random/timeriomem-rng.c
> index a0faa5f05deb..03ff5483d865 100644
> --- a/drivers/char/hw_random/timeriomem-rng.c
> +++ b/drivers/char/hw_random/timeriomem-rng.c
> @@ -151,8 +151,15 @@ static int timeriomem_rng_probe(struct platform_device 
> *pdev)
> dev_err(&pdev->dev, "missing period\n");
> return -EINVAL;
> }
> +
> +   if (!of_property_read_u32(pdev->dev.of_node,
> +   "quality", &i))
> +   priv->rng_ops.quality = i;
> +   else
> +   priv->rng_ops.quality = 0;
> } else {
> period = pdata->period;
> +   priv->rng_ops.quality = pdata->quality;
> }
>
> priv->period = ns_to_ktime(period * NSEC_PER_USEC);
> diff --git a/include/linux/timeriomem-rng.h b/include/linux/timeriomem-rng.h
> index 46eb27ddbfab..320f743bf06b 100644
> --- a/include/linux/timeriomem-rng.h
> +++ b/include/linux/timeriomem-rng.h
> @@ -13,4 +13,7 @@ struct timeriomem_rng_data {
>
> /* measures in usecs */
> unsigned intperiod;
> +
> +   /* bits of entropy per 1000 bits read */

Your dt-bindings patch says 'entropy per 1024 bits'. Please be consistent.

> +   unsigned intquality;
>  };
> --
> 2.13.0.303.g4ebf302169-goog
>

Regards,
PrasannaKumar


Re: [PATCH 0/7] crypto: aesni: provide generic gcm(aes)

2017-05-17 Thread Herbert Xu
On Fri, Apr 28, 2017 at 06:11:55PM +0200, Sabrina Dubroca wrote:
> The current aesni AES-GCM implementation only offers support for
> rfc4106(gcm(aes)).  This makes some things a little bit simpler
> (handling of associated data and authentication tag), but it means
> that non-IPsec users of gcm(aes) have to rely on
> gcm_base(ctr-aes-aesni,ghash-clmulni), which is much slower.
> 
> This patchset adds handling of all valid authentication tag lengths
> and of any associated data length to the assembly code, and exposes a
> generic gcm(aes) AEAD algorithm to the crypto API.
> 
> With these patches, performance of MACsec on a single core increases
> by 40% (from 4.5Gbps to around 6.3Gbps).

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


Re: [PATCH] crypto: arm64/sha - avoid non-standard inline asm tricks

2017-05-17 Thread Herbert Xu
On Wed, Apr 26, 2017 at 05:11:32PM +0100, Ard Biesheuvel wrote:
> Replace the inline asm which exports struct offsets as ELF symbols
> with proper const variables exposing the same values. This works
> around an issue with Clang which does not interpret the "i" (or "I")
> constraints in the same way as GCC.
> 
> Signed-off-by: Ard Biesheuvel 

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


Re: [PATCH 0/5] crypto: caampkc - extend RSA private key representation

2017-05-17 Thread Herbert Xu
On Tue, Apr 25, 2017 at 04:26:34PM +0300, Horia Geantă wrote:
> This patch set adds support for the second and third RSA private key
> representations and extends caampkc to use the fastest key when all related
> components are present in the private key.
> 
> Additionally a rsa tcrypt test has been added.

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


Re: [PATCH] crypto: ccp - Add a module author

2017-05-17 Thread Herbert Xu
On Tue, Apr 25, 2017 at 08:59:44AM -0500, Gary R Hook wrote:
> CC:  # 4.9.x+
> 
> Signed-off-by: Gary R Hook 

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


Re: [PATCH] crypto: sha512-mb - add some missing unlock on error

2017-05-17 Thread Herbert Xu
On Tue, Apr 25, 2017 at 12:18:54PM +0300, Dan Carpenter wrote:
> We recently added some new locking but missed the unlocks on these
> error paths in sha512_ctx_mgr_submit().
> 
> Fixes: c459bd7beda0 ("crypto: sha512-mb - Protect sha512 mb ctx mgr access")
> Signed-off-by: Dan Carpenter 

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


Re: [PATCH] crypto: tcrypt: don't disable irqs and wait

2017-05-17 Thread Herbert Xu
On Tue, Apr 25, 2017 at 11:25:40AM +0300, Gilad Ben-Yossef wrote:
> The tcrypt AEAD cycles speed tests disables irqs during the test, which is
> broken at the very least since commit
> '1425d2d17f7309c6 ("crypto: tcrypt - Fix AEAD speed tests")'
> adds a wait for completion as part of the test and probably since
> switching to the new AEAD API.
> 
> While the result of taking a cycle count diff may not mean much on SMP
> systems if the task migrates, it's good enough for tcrypt being the quick
> & dirty dev tool it is. It's also what all the other (i.e. hash) cycle
> speed tests do.
> 
> Signed-off-by: Gilad Ben-Yossef 
> Reported-by: Ofir Drang 

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


Re: [PATCH 2/4] crypto: drbg wait for crypto op not signal safe

2017-05-17 Thread Herbert Xu
On Thu, May 11, 2017 at 02:53:43PM +0300, Gilad Ben-Yossef wrote:
> drbg_kcapi_sym_ctr() was using wait_for_completion_interruptible() to
> wait for completion of async crypto op but if a signal occurs it
> may return before DMA ops of HW crypto provider finish, thus
> corrupting the output buffer.
> 
> Resolve this by using wait_for_completion() instead.
> 
> Reported-by: Eric Biggers 
> Signed-off-by: Gilad Ben-Yossef 
> CC: sta...@vger.kernel.org

This patch doesn't even compile.  Please test your work first.

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


Re: [PATCH 1/9] crypto: add hmac IPAD/OPAD constant

2017-05-17 Thread Herbert Xu
On Mon, Apr 24, 2017 at 04:16:21PM +0200, Corentin Labbe wrote:
> Many HMAC users directly use directly 0x36/0x5c values.
> It's better with crypto to use a name instead of directly some crypto
> constant.
> 
> This patch simply add HMAC_IPAD_VALUE/HMAC_OPAD_VALUE defines.
> 
> Signed-off-by: Corentin Labbe 
> ---
>  crypto/hmac.c | 4 ++--
>  include/crypto/hash.h | 3 +++
>  2 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/crypto/hmac.c b/crypto/hmac.c
> index 72e38c0..4a997ce 100644
> --- a/crypto/hmac.c
> +++ b/crypto/hmac.c
> @@ -74,8 +74,8 @@ static int hmac_setkey(struct crypto_shash *parent,
>   memcpy(opad, ipad, bs);
>  
>   for (i = 0; i < bs; i++) {
> - ipad[i] ^= 0x36;
> - opad[i] ^= 0x5c;
> + ipad[i] ^= HMAC_IPAD_VALUE;
> + opad[i] ^= HMAC_OPAD_VALUE;
>   }
>  
>   return crypto_shash_init(shash) ?:
> diff --git a/include/crypto/hash.h b/include/crypto/hash.h
> index b5727bc..0f51ff1 100644
> --- a/include/crypto/hash.h
> +++ b/include/crypto/hash.h
> @@ -922,4 +922,7 @@ static inline void shash_desc_zero(struct shash_desc 
> *desc)
>sizeof(*desc) + crypto_shash_descsize(desc->tfm));
>  }
>  
> +#define HMAC_IPAD_VALUE 0x36
> +#define HMAC_OPAD_VALUE 0x5c
> +
>  #endif   /* _CRYPTO_HASH_H */

I think this should go into a header file specific to hmac.  Since
I don't see an existing hmac header file you should create one for it.

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


Re: [PATCH] crypto: hifn_795x: Fix a handful of minor bugs spotted by eye

2017-05-17 Thread David Miller
From: Logan Gunthorpe 
Date: Wed, 17 May 2017 21:33:22 -0600

> 
> 
> On 17/05/17 09:26 PM, Herbert Xu wrote:
>> On Thu, May 18, 2017 at 11:25:06AM +0800, Herbert Xu wrote:
>>> On Fri, Apr 28, 2017 at 11:02:40AM -0600, Logan Gunthorpe wrote:
 * Cleaned up the formatting of ablkcipher_get arguments so it complies
   with kernel style
 * The offset in ablkcipher_get sould be added to the source, not the
   destination. We rename it to soffset for clarity.
 * dst++ should be dst=sg_next(dst)
 * We call kunmap_atomic earlier so we only have to do it once.
 * If ablkcipher_get fails, we should probably ensure the request
   completes with an error.
> 
>>> Please don't mix unrelated changes in the same patch.
> 
> Seriously? The patch is tiny and those are all incredibly minor changes.

Yes, seriously.

It is the only way to make your changes easy to review and audit.

Please do as Herbert is asking.


Re: [PATCH 1/5] crypto: tcrypt - include rsa test

2017-05-17 Thread Herbert Xu
On Tue, Apr 25, 2017 at 04:26:35PM +0300, Horia Geantă wrote:
> From: Radu Alexe 
> 
> Signed-off-by: Radu Alexe 
> Signed-off-by: Tudor Ambarus 
> Signed-off-by: Horia Geantă 

I think it's time to stop adding new algorithms to tcrypt as you
should be able to test any algorithm using name/type/mask.

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


Re: [PATCH] crypto: hifn_795x: Fix a handful of minor bugs spotted by eye

2017-05-17 Thread Logan Gunthorpe


On 17/05/17 09:26 PM, Herbert Xu wrote:
> On Thu, May 18, 2017 at 11:25:06AM +0800, Herbert Xu wrote:
>> On Fri, Apr 28, 2017 at 11:02:40AM -0600, Logan Gunthorpe wrote:
>>> * Cleaned up the formatting of ablkcipher_get arguments so it complies
>>>   with kernel style
>>> * The offset in ablkcipher_get sould be added to the source, not the
>>>   destination. We rename it to soffset for clarity.
>>> * dst++ should be dst=sg_next(dst)
>>> * We call kunmap_atomic earlier so we only have to do it once.
>>> * If ablkcipher_get fails, we should probably ensure the request
>>>   completes with an error.

>> Please don't mix unrelated changes in the same patch.

Seriously? The patch is tiny and those are all incredibly minor changes.

>> Also was this tested on actual hardware? This is an old driver so
>> it's probably best to just let it be.

No, I don't have that hardware. I sent this patch because you requested it.

> Of course we do want fix the offset issue so could you please send
> a new patch with just that fix?

Sorry, no, I honestly don't see that as worth my time. Feel free to drop
the patch or roll your own.

Logan


Re: [PATCH] crypto: hifn_795x: Fix a handful of minor bugs spotted by eye

2017-05-17 Thread Herbert Xu
On Thu, May 18, 2017 at 11:25:06AM +0800, Herbert Xu wrote:
> On Fri, Apr 28, 2017 at 11:02:40AM -0600, Logan Gunthorpe wrote:
> > * Cleaned up the formatting of ablkcipher_get arguments so it complies
> >   with kernel style
> > * The offset in ablkcipher_get sould be added to the source, not the
> >   destination. We rename it to soffset for clarity.
> > * dst++ should be dst=sg_next(dst)
> > * We call kunmap_atomic earlier so we only have to do it once.
> > * If ablkcipher_get fails, we should probably ensure the request
> >   completes with an error.
> 
> Please don't mix unrelated changes in the same patch.
> 
> Also was this tested on actual hardware? This is an old driver so
> it's probably best to just let it be.

Of course we do want fix the offset issue so could you please send
a new patch with just that 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] crypto: hifn_795x: Fix a handful of minor bugs spotted by eye

2017-05-17 Thread Herbert Xu
On Fri, Apr 28, 2017 at 11:02:40AM -0600, Logan Gunthorpe wrote:
> * Cleaned up the formatting of ablkcipher_get arguments so it complies
>   with kernel style
> * The offset in ablkcipher_get sould be added to the source, not the
>   destination. We rename it to soffset for clarity.
> * dst++ should be dst=sg_next(dst)
> * We call kunmap_atomic earlier so we only have to do it once.
> * If ablkcipher_get fails, we should probably ensure the request
>   completes with an error.

Please don't mix unrelated changes in the same patch.

Also was this tested on actual hardware? This is an old driver so
it's probably best to just let it be.

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


[PATCH v1 2/2] hw_random: timeriomem_rng: Allow setting RNG quality from platform data

2017-05-17 Thread Rick Altherr
When a hw_random device's quality is non-zero, it will automatically be
used to fill the kernel's entropy pool.  Since timeriomem_rng is used by
many different devices, the quality needs to be provided by platform
data or device tree.

Signed-off-by: Rick Altherr 
---

 drivers/char/hw_random/timeriomem-rng.c | 7 +++
 include/linux/timeriomem-rng.h  | 3 +++
 2 files changed, 10 insertions(+)

diff --git a/drivers/char/hw_random/timeriomem-rng.c 
b/drivers/char/hw_random/timeriomem-rng.c
index a0faa5f05deb..03ff5483d865 100644
--- a/drivers/char/hw_random/timeriomem-rng.c
+++ b/drivers/char/hw_random/timeriomem-rng.c
@@ -151,8 +151,15 @@ static int timeriomem_rng_probe(struct platform_device 
*pdev)
dev_err(&pdev->dev, "missing period\n");
return -EINVAL;
}
+
+   if (!of_property_read_u32(pdev->dev.of_node,
+   "quality", &i))
+   priv->rng_ops.quality = i;
+   else
+   priv->rng_ops.quality = 0;
} else {
period = pdata->period;
+   priv->rng_ops.quality = pdata->quality;
}
 
priv->period = ns_to_ktime(period * NSEC_PER_USEC);
diff --git a/include/linux/timeriomem-rng.h b/include/linux/timeriomem-rng.h
index 46eb27ddbfab..320f743bf06b 100644
--- a/include/linux/timeriomem-rng.h
+++ b/include/linux/timeriomem-rng.h
@@ -13,4 +13,7 @@ struct timeriomem_rng_data {
 
/* measures in usecs */
unsigned intperiod;
+
+   /* bits of entropy per 1000 bits read */
+   unsigned intquality;
 };
-- 
2.13.0.303.g4ebf302169-goog



[PATCH v1 1/2] dt-bindings: timeriomem_rng: Add entropy quality property

2017-05-17 Thread Rick Altherr
Signed-off-by: Rick Altherr 
---

 Documentation/devicetree/bindings/rng/timeriomem_rng.txt | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/rng/timeriomem_rng.txt 
b/Documentation/devicetree/bindings/rng/timeriomem_rng.txt
index 6616d15866a3..214940093b55 100644
--- a/Documentation/devicetree/bindings/rng/timeriomem_rng.txt
+++ b/Documentation/devicetree/bindings/rng/timeriomem_rng.txt
@@ -5,6 +5,13 @@ Required properties:
 - reg : base address to sample from
 - period : wait time in microseconds to use between samples
 
+Optional properties:
+- quality : estimated number of bits of true entropy per 1024 bits read from 
the
+rng.  Defaults to zero which causes the kernel's default quality to
+be used instead.  Note that the default quality is usually zero
+which disables using this rng to automatically fill the kernel's
+entropy pool.
+
 N.B. currently 'reg' must be four bytes wide and aligned
 
 Example:
-- 
2.13.0.303.g4ebf302169-goog



Re: [PATCH] crypto: x86/aes - Don't use %rbp as temporary register

2017-05-17 Thread Eric Biggers
On Wed, May 17, 2017 at 03:44:27PM -0500, Josh Poimboeuf wrote:
> On Tue, May 16, 2017 at 09:03:08PM -0700, Eric Biggers wrote:
> > From: Eric Biggers 
> > 
> > When using the "aes-asm" implementation of AES (*not* the AES-NI
> > implementation) on an x86_64, v4.12-rc1 kernel with lockdep enabled, the
> > following warning was reported, along with a long unwinder dump:
> > 
> > WARNING: kernel stack regs at c9643558 in kworker/u4:2:155 has 
> > bad 'bp' value 001c
> > 
> > The problem is that aes_enc_block() and aes_dec_block() use %rbp as a
> > temporary register, which breaks stack traces if an interrupt occurs.
> > 
> > Fix this by replacing %rbp with %r9, which was being used to hold the
> > saved value of %rbp.  This required rearranging the AES round macro
> > slightly since %r9d cannot be used as the target of a move from %ah-%dh.
> > 
> > Performance is essentially unchanged --- actually about 0.2% faster than
> > before.  Interestingly, I also measured aes-generic as being nearly 7%
> > faster than aes-asm, so perhaps aes-asm has outlived its usefulness...
> > 
> > Signed-off-by: Eric Biggers 
> 
> Reviewed-by: Josh Poimboeuf 
> 

Hmm, it looks like a number of other algorithms in arch/x86/crypto/ use %rbp (or
%ebp), e.g. blowfish, camellia, cast5, and aes-i586.  Presumably they have the
same problem.  I'm a little confused: do these all need to be fixed, and
when/why did this start being considered broken?

Eric


Re: [PATCH v4 1/3] Documentation/bindings: Document the SafeXel cryptographic engine driver

2017-05-17 Thread Rob Herring
On Thu, Apr 27, 2017 at 8:24 AM, Antoine Tenart
 wrote:
> The Inside Secure Safexcel cryptographic engine is found on some Marvell
> SoCs (7k/8k). Document the bindings used by its driver.
>
> Signed-off-by: Antoine Tenart 
> ---
>  .../bindings/crypto/inside-secure-safexcel.txt | 27 
> ++
>  1 file changed, 27 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/crypto/inside-secure-safexcel.txt

If you would like this reviewed, please re-send to the DT list.

Rob


Re: [PATCH] crypto: x86/aes - Don't use %rbp as temporary register

2017-05-17 Thread Josh Poimboeuf
On Tue, May 16, 2017 at 09:03:08PM -0700, Eric Biggers wrote:
> From: Eric Biggers 
> 
> When using the "aes-asm" implementation of AES (*not* the AES-NI
> implementation) on an x86_64, v4.12-rc1 kernel with lockdep enabled, the
> following warning was reported, along with a long unwinder dump:
> 
>   WARNING: kernel stack regs at c9643558 in kworker/u4:2:155 has 
> bad 'bp' value 001c
> 
> The problem is that aes_enc_block() and aes_dec_block() use %rbp as a
> temporary register, which breaks stack traces if an interrupt occurs.
> 
> Fix this by replacing %rbp with %r9, which was being used to hold the
> saved value of %rbp.  This required rearranging the AES round macro
> slightly since %r9d cannot be used as the target of a move from %ah-%dh.
> 
> Performance is essentially unchanged --- actually about 0.2% faster than
> before.  Interestingly, I also measured aes-generic as being nearly 7%
> faster than aes-asm, so perhaps aes-asm has outlived its usefulness...
> 
> Signed-off-by: Eric Biggers 

Reviewed-by: Josh Poimboeuf 

-- 
Josh


Re: [PATCH] crypto: arm64/sha - avoid non-standard inline asm tricks

2017-05-17 Thread Matthias Kaehlcke
El Wed, Apr 26, 2017 at 05:11:32PM +0100 Ard Biesheuvel ha dit:

> Replace the inline asm which exports struct offsets as ELF symbols
> with proper const variables exposing the same values. This works
> around an issue with Clang which does not interpret the "i" (or "I")
> constraints in the same way as GCC.
> 
> Signed-off-by: Ard Biesheuvel 
> ---
>  arch/arm64/crypto/sha1-ce-core.S |  6 --
>  arch/arm64/crypto/sha1-ce-glue.c | 11 +++
>  arch/arm64/crypto/sha2-ce-core.S |  6 --
>  arch/arm64/crypto/sha2-ce-glue.c | 13 +
>  4 files changed, 16 insertions(+), 20 deletions(-)

Herbert, do you plan to pick this up?

Thanks

Matthias


[RFC PATCH v2 3/4] crypto: dh - allow user to provide NULL privkey

2017-05-17 Thread Tudor Ambarus
If the user provides a NULL private key, the kernel will
generate it and further use it for dh.

Signed-off-by: Tudor Ambarus 
---
 crypto/dh.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/crypto/dh.c b/crypto/dh.c
index 87e3542..7b4ac5b 100644
--- a/crypto/dh.c
+++ b/crypto/dh.c
@@ -83,7 +83,9 @@ static int dh_set_secret(struct crypto_kpp *tfm, const void 
*buf,
 unsigned int len)
 {
struct dh_ctx *ctx = dh_get_ctx(tfm);
+   u8 *rndbuf = NULL;
struct dh params;
+   int maxsize;
 
if (crypto_dh_decode_key(buf, len, ¶ms) < 0)
return -EINVAL;
@@ -91,7 +93,26 @@ static int dh_set_secret(struct crypto_kpp *tfm, const void 
*buf,
if (dh_set_params(ctx, ¶ms) < 0)
return -EINVAL;
 
+   if (!params.key || !params.key_size) {
+   maxsize = crypto_kpp_maxsize(tfm);
+   if (maxsize < 0) {
+   dh_clear_params(ctx);
+   return maxsize;
+   }
+
+   rndbuf = kmalloc(maxsize, GFP_KERNEL);
+   if (!rndbuf) {
+   dh_clear_params(ctx);
+   return -ENOMEM;
+   }
+
+   get_random_bytes(rndbuf, maxsize);
+   params.key = rndbuf;
+   params.key_size = maxsize;
+   }
+
ctx->xa = mpi_read_raw_data(params.key, params.key_size);
+   kzfree(rndbuf);
if (!ctx->xa) {
dh_clear_params(ctx);
return -EINVAL;
-- 
2.7.4



[RFC PATCH v2 4/4] crypto: testmgr - add genkey kpp test

2017-05-17 Thread Tudor Ambarus
The test considers a party that already has a private-public
key pair and a party that provides a NULL key. The kernel will
generate the private-public key pair for the latter, computes
the shared secret on both ends and verifies it it's the same.

The explicit private-public key pairs were copied from
the previous test vectors.

Signed-off-by: Tudor Ambarus 
---
 crypto/testmgr.c |  76 +++
 crypto/testmgr.h | 155 +++
 2 files changed, 220 insertions(+), 11 deletions(-)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 6f5f3ed..faf5fd8 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -1997,6 +1997,9 @@ static int do_test_kpp(struct crypto_kpp *tfm, const 
struct kpp_testvec *vec,
struct kpp_request *req;
void *input_buf = NULL;
void *output_buf = NULL;
+   void *a_public = NULL;
+   void *a_ss = NULL;
+   void *shared_secret = NULL;
struct tcrypt_result result;
unsigned int out_len_max;
int err = -ENOMEM;
@@ -2026,20 +2029,31 @@ static int do_test_kpp(struct crypto_kpp *tfm, const 
struct kpp_testvec *vec,
kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
 tcrypt_complete, &result);
 
-   /* Compute public key */
+   /* Compute party A's public key */
err = wait_async_op(&result, crypto_kpp_generate_public_key(req));
if (err) {
-   pr_err("alg: %s: generate public key test failed. err %d\n",
+   pr_err("alg: %s: Party A: generate public key test failed. err 
%d\n",
   alg, err);
goto free_output;
}
-   /* Verify calculated public key */
-   if (memcmp(vec->expected_a_public, sg_virt(req->dst),
-  vec->expected_a_public_size)) {
-   pr_err("alg: %s: generate public key test failed. Invalid 
output\n",
-  alg);
-   err = -EINVAL;
-   goto free_output;
+
+   if (vec->genkey) {
+   /* Save party A's public key */
+   a_public = kzalloc(out_len_max, GFP_KERNEL);
+   if (!a_public) {
+   err = -ENOMEM;
+   goto free_output;
+   }
+   memcpy(a_public, sg_virt(req->dst), sizeof(*a_public));
+   } else {
+   /* Verify calculated public key */
+   if (memcmp(vec->expected_a_public, sg_virt(req->dst),
+  vec->expected_a_public_size)) {
+   pr_err("alg: %s: Party A: generate public key test 
failed. Invalid output\n",
+  alg);
+   err = -EINVAL;
+   goto free_output;
+   }
}
 
/* Calculate shared secret key by using counter part (b) public key. */
@@ -2058,15 +2072,53 @@ static int do_test_kpp(struct crypto_kpp *tfm, const 
struct kpp_testvec *vec,
 tcrypt_complete, &result);
err = wait_async_op(&result, crypto_kpp_compute_shared_secret(req));
if (err) {
-   pr_err("alg: %s: compute shard secret test failed. err %d\n",
+   pr_err("alg: %s: Party A: compute shared secret test failed. 
err %d\n",
   alg, err);
goto free_all;
}
+
+   if (vec->genkey) {
+   /* Save the shared secret obtained by party A */
+   a_ss = kzalloc(vec->expected_ss_size, GFP_KERNEL);
+   if (!a_ss) {
+   err = -ENOMEM;
+   goto free_all;
+   }
+   memcpy(a_ss, sg_virt(req->dst), sizeof(*a_ss));
+
+   /*
+* Calculate party B's shared secret by using party A's
+* public key.
+*/
+   err = crypto_kpp_set_secret(tfm, vec->b_secret,
+   vec->b_secret_size);
+   if (err < 0)
+   goto free_all;
+
+   sg_init_one(&src, a_public, vec->expected_a_public_size);
+   sg_init_one(&dst, output_buf, out_len_max);
+   kpp_request_set_input(req, &src, vec->expected_a_public_size);
+   kpp_request_set_output(req, &dst, out_len_max);
+   kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+tcrypt_complete, &result);
+   err = wait_async_op(&result,
+   crypto_kpp_compute_shared_secret(req));
+   if (err) {
+   pr_err("alg: %s: Party B: compute shared secret failed. 
err %d\n",
+  alg, err);
+   goto free_all;
+   }
+
+   shared_secret = a_ss;
+   } else {
+   shared_secret = (void *)vec->expected_ss;
+   }
+
   

[RFC PATCH v2 2/4] crypto: ecdh - allow user to provide NULL privkey

2017-05-17 Thread Tudor Ambarus
If the user provides a NULL ecc private key, the kernel will
generate it and further use it for ecdh.

Signed-off-by: Tudor Ambarus 
---
 crypto/ecdh.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/crypto/ecdh.c b/crypto/ecdh.c
index 63ca337..f28f5b5 100644
--- a/crypto/ecdh.c
+++ b/crypto/ecdh.c
@@ -55,6 +55,10 @@ static int ecdh_set_secret(struct crypto_kpp *tfm, const 
void *buf,
ctx->curve_id = params.curve_id;
ctx->ndigits = ndigits;
 
+   if (!params.key || !params.key_size)
+   return ecc_gen_privkey(ctx->curve_id, ctx->ndigits,
+  ctx->private_key);
+
if (ecc_is_key_valid(ctx->curve_id, ctx->ndigits,
 (const u8 *)params.key, params.key_size) < 0)
return -EINVAL;
-- 
2.7.4



[RFC PATCH v2 1/4] crypto: ecc - add privkey generation support

2017-05-17 Thread Tudor Ambarus
Add support for generating ecc private keys.

Generation of ecc private keys is helpful in a user-space to kernel
ecdh offload because the keys are not revealed to user-space. Private
key generation is also helpful to implement forward secrecy.

Signed-off-by: Tudor Ambarus 
---
 crypto/ecc.c | 20 
 crypto/ecc.h | 14 ++
 2 files changed, 34 insertions(+)

diff --git a/crypto/ecc.c b/crypto/ecc.c
index 414c78a..a591907 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -927,6 +927,26 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int 
ndigits,
return 0;
 }
 
+int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, u64 *privkey)
+{
+   const struct ecc_curve *curve = ecc_get_curve(curve_id);
+   u64 priv[ndigits];
+   unsigned int nbytes = ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
+
+   get_random_bytes(priv, nbytes);
+
+   if (vli_is_zero(priv, ndigits))
+   return -EINVAL;
+
+   /* Make sure the private key is in the range [1, n-1]. */
+   if (vli_cmp(curve->n, priv, ndigits) != 1)
+   return -EINVAL;
+
+   ecc_swap_digits(priv, privkey, ndigits);
+
+   return 0;
+}
+
 int ecdh_make_pub_key(unsigned int curve_id, unsigned int ndigits,
  const u8 *private_key, unsigned int private_key_len,
  u8 *public_key, unsigned int public_key_len)
diff --git a/crypto/ecc.h b/crypto/ecc.h
index 663d598..b94b7ce 100644
--- a/crypto/ecc.h
+++ b/crypto/ecc.h
@@ -44,6 +44,20 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int 
ndigits,
 const u8 *private_key, unsigned int private_key_len);
 
 /**
+ * ecc_gen_privkey() -  Generates an ECC private key.
+ * The private key is a random integer in the range 0 < random < n, where n is 
a
+ * prime that is the order of the cyclic subgroup generated by the 
distinguished
+ * point G.
+ * @curve_id:  id representing the curve to use
+ * @ndigits:   curve number of digits
+ * @private_key:   buffer for storing the generated private key
+ *
+ * Returns 0 if the private key was generated successfully, a negative value
+ * if an error occurred.
+ */
+int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, u64 *privkey);
+
+/**
  * ecdh_make_pub_key() - Compute an ECC public key
  *
  * @curve_id:  id representing the curve to use
-- 
2.7.4



[RFC PATCH v2 0/4] crypto: (ec)dh - add privkey generation support

2017-05-17 Thread Tudor Ambarus
Hi,

This is an RFC to discuss how to support private key generation for dh and ecdh.

This is helpful in a user-space to kernel (ec)dh offload because the keys are
generated in kernel and never revealed to user-space.

Private key generation is also helpful to implement forward secrecy.
A public/private key system demonstrates the property of forward secrecy if it
creates new key pairs for each communication session. These key pairs are
generated on an as-needed basis and are destroyed after the session is over.
If an attacker were to record previous encrypted session data, they wouldn't be
able to decrypt it with possession of a long-term key.

There are crypto accelerators that are capable of generating and retaining
private keys without revealing them to software. This patch set is a
prerequisite for hardware private key generation support.

Changes in v2:
 - free dh params in case of error
 - code defensively in testmgr: use sizeof(*ptr) while in memcpy

v1 can be found at:
http://www.mail-archive.com/linux-crypto@vger.kernel.org/msg25176.html

Tudor Ambarus (4):
  crypto: ecc - add privkey generation support
  crypto: ecdh - allow user to provide NULL privkey
  crypto: dh - allow user to provide NULL privkey
  crypto: testmgr - add genkey kpp test

 crypto/dh.c  |  21 
 crypto/ecc.c |  20 +++
 crypto/ecc.h |  14 +
 crypto/ecdh.c|   4 ++
 crypto/testmgr.c |  76 +++
 crypto/testmgr.h | 155 +++
 6 files changed, 279 insertions(+), 11 deletions(-)

-- 
2.7.4



[PATCH v2 09/11] crypto: testmgr - check err on kpp maxsize

2017-05-17 Thread Tudor Ambarus
crypto_kpp_maxsize() returns minimum length for output buffer
or error code if key hasn't been set.

Signed-off-by: Tudor Ambarus 
---
 crypto/testmgr.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 87a4abd..0bf9a00 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -2013,6 +2013,11 @@ static int do_test_kpp(struct crypto_kpp *tfm, const 
struct kpp_testvec *vec,
goto free_req;
 
out_len_max = crypto_kpp_maxsize(tfm);
+   if (out_len_max < 0) {
+   err = out_len_max;
+   goto free_req;
+   }
+
output_buf = kzalloc(out_len_max, GFP_KERNEL);
if (!output_buf) {
err = -ENOMEM;
-- 
2.7.4



[PATCH v2 11/11] crypto: rsa - do checks before allocating data

2017-05-17 Thread Tudor Ambarus
Signed-off-by: Tudor Ambarus 
---
 crypto/rsa.c | 16 ++--
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/crypto/rsa.c b/crypto/rsa.c
index 4c280b6..a80f76d 100644
--- a/crypto/rsa.c
+++ b/crypto/rsa.c
@@ -279,6 +279,9 @@ static int rsa_set_pub_key(struct crypto_akcipher *tfm, 
const void *key,
if (ret)
return ret;
 
+   if (rsa_check_key_length(raw_key.n_sz << 3))
+   return -EINVAL;
+
mpi_key->e = mpi_read_raw_data(raw_key.e, raw_key.e_sz);
if (!mpi_key->e)
goto err;
@@ -287,11 +290,6 @@ static int rsa_set_pub_key(struct crypto_akcipher *tfm, 
const void *key,
if (!mpi_key->n)
goto err;
 
-   if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) {
-   rsa_free_mpi_key(mpi_key);
-   return -EINVAL;
-   }
-
return 0;
 
 err:
@@ -313,6 +311,9 @@ static int rsa_set_priv_key(struct crypto_akcipher *tfm, 
const void *key,
if (ret)
return ret;
 
+   if (rsa_check_key_length(raw_key.n_sz << 3))
+   return -EINVAL;
+
mpi_key->d = mpi_read_raw_data(raw_key.d, raw_key.d_sz);
if (!mpi_key->d)
goto err;
@@ -325,11 +326,6 @@ static int rsa_set_priv_key(struct crypto_akcipher *tfm, 
const void *key,
if (!mpi_key->n)
goto err;
 
-   if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) {
-   rsa_free_mpi_key(mpi_key);
-   return -EINVAL;
-   }
-
return 0;
 
 err:
-- 
2.7.4



[PATCH v2 10/11] crypto: KEYS: check err on akcipher maxsize

2017-05-17 Thread Tudor Ambarus
crypto_akcipher_maxsize() returns minimum length for output buffer
or error code if key hasn't been set.

Signed-off-by: Tudor Ambarus 
---
 crypto/asymmetric_keys/public_key.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index d3a989e..2b2f8bf 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -123,6 +123,11 @@ int public_key_verify_signature(const struct public_key 
*pkey,
 
ret = -ENOMEM;
outlen = crypto_akcipher_maxsize(tfm);
+   if (outlen < 0) {
+   ret = outlen;
+   goto error_free_req;
+   }
+
output = kmalloc(outlen, GFP_KERNEL);
if (!output)
goto error_free_req;
-- 
2.7.4



[PATCH v2 07/11] crypto: dh - fix memleak in setkey

2017-05-17 Thread Tudor Ambarus
setkey can be called multiple times during the existence
of the transformation object. Free the old MPI key if any.

Signed-off-by: Tudor Ambarus 
---
 crypto/dh.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/crypto/dh.c b/crypto/dh.c
index 325a5dd..b55b03d 100644
--- a/crypto/dh.c
+++ b/crypto/dh.c
@@ -85,6 +85,9 @@ static int dh_set_secret(struct crypto_kpp *tfm, const void 
*buf,
struct dh_ctx *ctx = dh_get_ctx(tfm);
struct dh params;
 
+   /* Free the old MPI key if any */
+   dh_free_ctx(ctx);
+
if (crypto_dh_decode_key(buf, len, ¶ms) < 0)
return -EINVAL;
 
-- 
2.7.4



[PATCH v2 08/11] crypto: testmgr - check err on akcipher maxsize

2017-05-17 Thread Tudor Ambarus
crypto_akcipher_maxsize() returns minimum length for output buffer
or error code if key hasn't been set.

Signed-off-by: Tudor Ambarus 
---
 crypto/testmgr.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 6f5f3ed..87a4abd 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -2150,6 +2150,11 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
 
err = -ENOMEM;
out_len_max = crypto_akcipher_maxsize(tfm);
+   if (out_len_max < 0) {
+   err = out_len_max;
+   goto free_req;
+   }
+
outbuf_enc = kzalloc(out_len_max, GFP_KERNEL);
if (!outbuf_enc)
goto free_req;
-- 
2.7.4



[PATCH v2 02/11] crypto: ecc - remove unused function arguments

2017-05-17 Thread Tudor Ambarus
Signed-off-by: Tudor Ambarus 
---
 crypto/ecc.c  |  8 +++-
 crypto/ecc.h  | 13 +++--
 crypto/ecdh.c | 11 +--
 3 files changed, 11 insertions(+), 21 deletions(-)

diff --git a/crypto/ecc.c b/crypto/ecc.c
index 414c78a..69b4cc4 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -928,8 +928,7 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int 
ndigits,
 }
 
 int ecdh_make_pub_key(unsigned int curve_id, unsigned int ndigits,
- const u8 *private_key, unsigned int private_key_len,
- u8 *public_key, unsigned int public_key_len)
+ const u8 *private_key, u8 *public_key)
 {
int ret = 0;
struct ecc_point *pk;
@@ -967,9 +966,8 @@ int ecdh_make_pub_key(unsigned int curve_id, unsigned int 
ndigits,
 }
 
 int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
-  const u8 *private_key, unsigned int private_key_len,
-  const u8 *public_key, unsigned int public_key_len,
-  u8 *secret, unsigned int secret_len)
+ const u8 *private_key, const u8 *public_key,
+ u8 *secret)
 {
int ret = 0;
struct ecc_point *product, *pk;
diff --git a/crypto/ecc.h b/crypto/ecc.h
index 37f4385..1ca9bf7 100644
--- a/crypto/ecc.h
+++ b/crypto/ecc.h
@@ -49,16 +49,13 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int 
ndigits,
  * @curve_id:  id representing the curve to use
  * @ndigits:   curve's number of digits
  * @private_key:   pregenerated private key for the given curve
- * @private_key_len:   length of private_key
  * @public_key:buffer for storing the generated public key
- * @public_key_len:length of the public_key buffer
  *
  * Returns 0 if the public key was generated successfully, a negative value
  * if an error occurred.
  */
 int ecdh_make_pub_key(const unsigned int curve_id, unsigned int ndigits,
- const u8 *private_key, unsigned int private_key_len,
- u8 *public_key, unsigned int public_key_len);
+ const u8 *private_key, u8 *public_key);
 
 /**
  * crypto_ecdh_shared_secret() - Compute a shared secret
@@ -66,11 +63,8 @@ int ecdh_make_pub_key(const unsigned int curve_id, unsigned 
int ndigits,
  * @curve_id:  id representing the curve to use
  * @ndigits:   curve's number of digits
  * @private_key:   private key of part A
- * @private_key_len:   length of private_key
  * @public_key:public key of counterpart B
- * @public_key_len:length of public_key
  * @secret:buffer for storing the calculated shared secret
- * @secret_len:length of the secret buffer
  *
  * Note: It is recommended that you hash the result of 
crypto_ecdh_shared_secret
  * before using it for symmetric encryption or HMAC.
@@ -79,7 +73,6 @@ int ecdh_make_pub_key(const unsigned int curve_id, unsigned 
int ndigits,
  * if an error occurred.
  */
 int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
-  const u8 *private_key, unsigned int private_key_len,
-  const u8 *public_key, unsigned int public_key_len,
-  u8 *secret, unsigned int secret_len);
+ const u8 *private_key, const u8 *public_key,
+ u8 *secret);
 #endif
diff --git a/crypto/ecdh.c b/crypto/ecdh.c
index 3623307..69c3951 100644
--- a/crypto/ecdh.c
+++ b/crypto/ecdh.c
@@ -81,16 +81,15 @@ static int ecdh_compute_value(struct kpp_request *req)
return -EINVAL;
 
ret = crypto_ecdh_shared_secret(ctx->curve_id, ctx->ndigits,
-(const u8 *)ctx->private_key, nbytes,
-(const u8 *)ctx->public_key, 2 * 
nbytes,
-(u8 *)ctx->shared_secret, nbytes);
+   (const u8 *)ctx->private_key,
+   (const u8 *)ctx->public_key,
+   (u8 *)ctx->shared_secret);
 
buf = ctx->shared_secret;
} else {
ret = ecdh_make_pub_key(ctx->curve_id, ctx->ndigits,
-   (const u8 *)ctx->private_key, nbytes,
-   (u8 *)ctx->public_key,
-   sizeof(ctx->public_key));
+   (const u8 *)ctx->private_key,
+   (u8 *)ctx->public_key);
buf = ctx->public_key;
/* Public part is a point thus it has both coordinates */
nbytes *= 2;
-- 
2.7.4



[PATCH v2 05/11] crypto: ecdh - fix ecdh_max_size

2017-05-17 Thread Tudor Ambarus
The function should return minimum size for output buffer
or error code if key hasn't been set.

Signed-off-by: Tudor Ambarus 
---
 crypto/ecdh.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/crypto/ecdh.c b/crypto/ecdh.c
index c1f0163..830dfb6 100644
--- a/crypto/ecdh.c
+++ b/crypto/ecdh.c
@@ -107,10 +107,10 @@ static int ecdh_compute_value(struct kpp_request *req)
 static int ecdh_max_size(struct crypto_kpp *tfm)
 {
struct ecdh_ctx *ctx = ecdh_get_ctx(tfm);
-   int nbytes = ctx->ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
 
-   /* Public key is made of two coordinates */
-   return 2 * nbytes;
+   /* Public key is made of two coordinates, add one to the left shift  */
+   return ctx->ndigits ? ctx->ndigits << (ECC_DIGITS_TO_BYTES_SHIFT + 1) :
+ -EINVAL;
 }
 
 static void no_exit_tfm(struct crypto_kpp *tfm)
-- 
2.7.4



[PATCH v2 06/11] crypto: ecc - don't be selfish on pubkeys

2017-05-17 Thread Tudor Ambarus
Rename ecdh_make_pub_key() to ecc_make_pub_key().
This function might as well be used by ecdsa.

Signed-off-by: Tudor Ambarus 
---
 crypto/ecc.c  | 4 ++--
 crypto/ecc.h  | 4 ++--
 crypto/ecdh.c | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/crypto/ecc.c b/crypto/ecc.c
index e3a2b8f..6c33c43 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -927,8 +927,8 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int 
ndigits,
return 0;
 }
 
-int ecdh_make_pub_key(unsigned int curve_id, unsigned int ndigits,
- const u64 *private_key, u64 *public_key)
+int ecc_make_pub_key(unsigned int curve_id, unsigned int ndigits,
+const u64 *private_key, u64 *public_key)
 {
int ret = 0;
struct ecc_point *pk;
diff --git a/crypto/ecc.h b/crypto/ecc.h
index af2ffdb..673c834 100644
--- a/crypto/ecc.h
+++ b/crypto/ecc.h
@@ -54,8 +54,8 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int 
ndigits,
  * Returns 0 if the public key was generated successfully, a negative value
  * if an error occurred.
  */
-int ecdh_make_pub_key(const unsigned int curve_id, unsigned int ndigits,
- const u64 *private_key, u64 *public_key);
+int ecc_make_pub_key(const unsigned int curve_id, unsigned int ndigits,
+const u64 *private_key, u64 *public_key);
 
 /**
  * crypto_ecdh_shared_secret() - Compute a shared secret
diff --git a/crypto/ecdh.c b/crypto/ecdh.c
index 830dfb6..8b6450d 100644
--- a/crypto/ecdh.c
+++ b/crypto/ecdh.c
@@ -87,8 +87,8 @@ static int ecdh_compute_value(struct kpp_request *req)
 
buf = ctx->shared_secret;
} else {
-   ret = ecdh_make_pub_key(ctx->curve_id, ctx->ndigits,
-   ctx->private_key, ctx->public_key);
+   ret = ecc_make_pub_key(ctx->curve_id, ctx->ndigits,
+  ctx->private_key, ctx->public_key);
buf = ctx->public_key;
/* Public part is a point thus it has both coordinates */
nbytes *= 2;
-- 
2.7.4



[PATCH v2 04/11] crypto: dh - fix dh_max_size

2017-05-17 Thread Tudor Ambarus
The function should return minimum size for output buffer
or error code if key hasn't been set.

Signed-off-by: Tudor Ambarus 
---
 crypto/dh.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto/dh.c b/crypto/dh.c
index 7cec0498..325a5dd 100644
--- a/crypto/dh.c
+++ b/crypto/dh.c
@@ -148,7 +148,7 @@ static int dh_max_size(struct crypto_kpp *tfm)
 {
struct dh_ctx *ctx = dh_get_ctx(tfm);
 
-   return mpi_get_size(ctx->p);
+   return ctx->p ? mpi_get_size(ctx->p) : -EINVAL;
 }
 
 static void dh_exit_tfm(struct crypto_kpp *tfm)
-- 
2.7.4



[PATCH v2 00/11] fixes for ecc, ec(dh), rsa & testmgr

2017-05-17 Thread Tudor Ambarus
Hi,

These are various fixes that I made while reading kpp and akcipher
implementations.

For KEYS there is only one patch. It checks the return value of
crypto_akcipher_maxsize().

Changes in v2:
 - squash the patches that removed the unnecessary casts
 - add the last five patches

v1 can be found at:
http://www.mail-archive.com/linux-crypto@vger.kernel.org/msg25139.html

Tudor Ambarus (11):
  crypto: kpp, (ec)dh - fix typos
  crypto: ecc - remove unused function arguments
  crypto: ecc - remove unnecessary casts
  crypto: dh - fix dh_max_size
  crypto: ecdh - fix ecdh_max_size
  crypto: ecc - don't be selfish on pubkeys
  crypto: dh - fix memleak in setkey
  crypto: testmgr - check err on akcipher maxsize
  crypto: testmgr - check err on kpp maxsize
  crypto: KEYS: check err on akcipher maxsize
  crypto: rsa - do checks before allocating data

 crypto/asymmetric_keys/public_key.c |  5 +
 crypto/dh.c |  9 ++---
 crypto/dh_helper.c  |  4 ++--
 crypto/ecc.c| 32 ++--
 crypto/ecc.h| 25 ++---
 crypto/ecdh.c   | 24 +++-
 crypto/ecdh_helper.c|  4 ++--
 crypto/rsa.c| 16 ++--
 crypto/testmgr.c| 10 ++
 include/crypto/dh.h |  4 ++--
 include/crypto/ecdh.h   |  4 ++--
 include/crypto/kpp.h|  4 ++--
 12 files changed, 72 insertions(+), 69 deletions(-)

-- 
2.7.4



[PATCH v2 01/11] crypto: kpp, (ec)dh - fix typos

2017-05-17 Thread Tudor Ambarus
While here, add missing argument description (ndigits).

Signed-off-by: Tudor Ambarus 
---
 crypto/dh.c   | 4 ++--
 crypto/dh_helper.c| 4 ++--
 crypto/ecc.h  | 8 +---
 crypto/ecdh.c | 4 ++--
 crypto/ecdh_helper.c  | 4 ++--
 include/crypto/dh.h   | 4 ++--
 include/crypto/ecdh.h | 4 ++--
 include/crypto/kpp.h  | 4 ++--
 8 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/crypto/dh.c b/crypto/dh.c
index 87e3542..7cec0498 100644
--- a/crypto/dh.c
+++ b/crypto/dh.c
@@ -4,9 +4,9 @@
  * Authors: Salvatore Benedetto 
  *
  * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
+ * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
+ * 2 of the License, or (at your option) any later version.
  */
 
 #include 
diff --git a/crypto/dh_helper.c b/crypto/dh_helper.c
index 02db76b..8ba8a3f 100644
--- a/crypto/dh_helper.c
+++ b/crypto/dh_helper.c
@@ -3,9 +3,9 @@
  * Authors: Salvatore Benedetto 
  *
  * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
+ * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
+ * 2 of the License, or (at your option) any later version.
  */
 #include 
 #include 
diff --git a/crypto/ecc.h b/crypto/ecc.h
index 663d598..37f4385 100644
--- a/crypto/ecc.h
+++ b/crypto/ecc.h
@@ -34,9 +34,9 @@
  * ecc_is_key_valid() - Validate a given ECDH private key
  *
  * @curve_id:  id representing the curve to use
- * @ndigits:   curve number of digits
+ * @ndigits:   curve's number of digits
  * @private_key:   private key to be used for the given curve
- * @private_key_len:   private key len
+ * @private_key_len:   private key length
  *
  * Returns 0 if the key is acceptable, a negative value otherwise
  */
@@ -47,9 +47,10 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int 
ndigits,
  * ecdh_make_pub_key() - Compute an ECC public key
  *
  * @curve_id:  id representing the curve to use
+ * @ndigits:   curve's number of digits
  * @private_key:   pregenerated private key for the given curve
  * @private_key_len:   length of private_key
- * @public_key:buffer for storing the public key generated
+ * @public_key:buffer for storing the generated public key
  * @public_key_len:length of the public_key buffer
  *
  * Returns 0 if the public key was generated successfully, a negative value
@@ -63,6 +64,7 @@ int ecdh_make_pub_key(const unsigned int curve_id, unsigned 
int ndigits,
  * crypto_ecdh_shared_secret() - Compute a shared secret
  *
  * @curve_id:  id representing the curve to use
+ * @ndigits:   curve's number of digits
  * @private_key:   private key of part A
  * @private_key_len:   length of private_key
  * @public_key:public key of counterpart B
diff --git a/crypto/ecdh.c b/crypto/ecdh.c
index 63ca337..3623307 100644
--- a/crypto/ecdh.c
+++ b/crypto/ecdh.c
@@ -4,9 +4,9 @@
  * Authors: Salvator Benedetto 
  *
  * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
+ * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
+ * 2 of the License, or (at your option) any later version.
  */
 
 #include 
diff --git a/crypto/ecdh_helper.c b/crypto/ecdh_helper.c
index 3cd8a24..f05bea5 100644
--- a/crypto/ecdh_helper.c
+++ b/crypto/ecdh_helper.c
@@ -3,9 +3,9 @@
  * Authors: Salvatore Benedetto 
  *
  * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
+ * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
+ * 2 of the License, or (at your option) any later version.
  */
 #include 
 #include 
diff --git a/include/crypto/dh.h b/include/crypto/dh.h
index 6b424ad..f638998 100644
--- a/include/crypto/dh.h
+++ b/include/crypto/dh.h
@@ -73,9 +73,9 @@ int crypto_dh_encode_key(char *buf, unsigned int len, const 
struct dh *params);
 /**
  * crypto_dh_decode_key() - decode a private key
  * @buf:   Buffer holding a packet key that should be decoded
- * @len:   Lenth of the packet private key buffer
+ * @len:   Length of the packet private key buffer
  * @params:Buffer allocated by the caller that is filled with the
- * unpacket DH private key.
+ * unpacked DH private key.
  *
  * The unpack

[PATCH v2 03/11] crypto: ecc - remove unnecessary casts

2017-05-17 Thread Tudor Ambarus
ecc software implementation works with chunks of u64 data. There were some
unnecessary casts to u8 and then back to u64 for the ecc keys. This patch
removes the unnecessary casts.

Signed-off-by: Tudor Ambarus 
---
 crypto/ecc.c  | 28 +---
 crypto/ecc.h  |  8 
 crypto/ecdh.c | 11 +--
 3 files changed, 22 insertions(+), 25 deletions(-)

diff --git a/crypto/ecc.c b/crypto/ecc.c
index 69b4cc4..e3a2b8f 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -904,7 +904,7 @@ static inline void ecc_swap_digits(const u64 *in, u64 *out,
 }
 
 int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits,
-const u8 *private_key, unsigned int private_key_len)
+const u64 *private_key, unsigned int private_key_len)
 {
int nbytes;
const struct ecc_curve *curve = ecc_get_curve(curve_id);
@@ -917,23 +917,22 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int 
ndigits,
if (private_key_len != nbytes)
return -EINVAL;
 
-   if (vli_is_zero((const u64 *)&private_key[0], ndigits))
+   if (vli_is_zero(private_key, ndigits))
return -EINVAL;
 
/* Make sure the private key is in the range [1, n-1]. */
-   if (vli_cmp(curve->n, (const u64 *)&private_key[0], ndigits) != 1)
+   if (vli_cmp(curve->n, private_key, ndigits) != 1)
return -EINVAL;
 
return 0;
 }
 
 int ecdh_make_pub_key(unsigned int curve_id, unsigned int ndigits,
- const u8 *private_key, u8 *public_key)
+ const u64 *private_key, u64 *public_key)
 {
int ret = 0;
struct ecc_point *pk;
u64 priv[ndigits];
-   unsigned int nbytes;
const struct ecc_curve *curve = ecc_get_curve(curve_id);
 
if (!private_key || !curve) {
@@ -941,7 +940,7 @@ int ecdh_make_pub_key(unsigned int curve_id, unsigned int 
ndigits,
goto out;
}
 
-   ecc_swap_digits((const u64 *)private_key, priv, ndigits);
+   ecc_swap_digits(private_key, priv, ndigits);
 
pk = ecc_alloc_point(ndigits);
if (!pk) {
@@ -955,9 +954,8 @@ int ecdh_make_pub_key(unsigned int curve_id, unsigned int 
ndigits,
goto err_free_point;
}
 
-   nbytes = ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
-   ecc_swap_digits(pk->x, (u64 *)public_key, ndigits);
-   ecc_swap_digits(pk->y, (u64 *)&public_key[nbytes], ndigits);
+   ecc_swap_digits(pk->x, public_key, ndigits);
+   ecc_swap_digits(pk->y, &public_key[ndigits], ndigits);
 
 err_free_point:
ecc_free_point(pk);
@@ -966,8 +964,8 @@ int ecdh_make_pub_key(unsigned int curve_id, unsigned int 
ndigits,
 }
 
 int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
- const u8 *private_key, const u8 *public_key,
- u8 *secret)
+ const u64 *private_key, const u64 *public_key,
+ u64 *secret)
 {
int ret = 0;
struct ecc_point *product, *pk;
@@ -997,13 +995,13 @@ int crypto_ecdh_shared_secret(unsigned int curve_id, 
unsigned int ndigits,
goto err_alloc_product;
}
 
-   ecc_swap_digits((const u64 *)public_key, pk->x, ndigits);
-   ecc_swap_digits((const u64 *)&public_key[nbytes], pk->y, ndigits);
-   ecc_swap_digits((const u64 *)private_key, priv, ndigits);
+   ecc_swap_digits(public_key, pk->x, ndigits);
+   ecc_swap_digits(&public_key[ndigits], pk->y, ndigits);
+   ecc_swap_digits(private_key, priv, ndigits);
 
ecc_point_mult(product, pk, priv, rand_z, curve->p, ndigits);
 
-   ecc_swap_digits(product->x, (u64 *)secret, ndigits);
+   ecc_swap_digits(product->x, secret, ndigits);
 
if (ecc_point_is_zero(product))
ret = -EFAULT;
diff --git a/crypto/ecc.h b/crypto/ecc.h
index 1ca9bf7..af2ffdb 100644
--- a/crypto/ecc.h
+++ b/crypto/ecc.h
@@ -41,7 +41,7 @@
  * Returns 0 if the key is acceptable, a negative value otherwise
  */
 int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits,
-const u8 *private_key, unsigned int private_key_len);
+const u64 *private_key, unsigned int private_key_len);
 
 /**
  * ecdh_make_pub_key() - Compute an ECC public key
@@ -55,7 +55,7 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int 
ndigits,
  * if an error occurred.
  */
 int ecdh_make_pub_key(const unsigned int curve_id, unsigned int ndigits,
- const u8 *private_key, u8 *public_key);
+ const u64 *private_key, u64 *public_key);
 
 /**
  * crypto_ecdh_shared_secret() - Compute a shared secret
@@ -73,6 +73,6 @@ int ecdh_make_pub_key(const unsigned int curve_id, unsigned 
int ndigits,
  * if an error occurred.
  */
 int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
- const u8 *private_ke

[RFC PATCH 4/4] crypto: testmgr - add genkey kpp test

2017-05-17 Thread Tudor Ambarus
The test considers a party that already has a private-public
key pair and a party that provides a NULL key. The kernel will
generate the private-public key pair for the latter, computes
the shared secret on both ends and verifies it it's the same.

The explicit private-public key pairs were copied from
the previous test vectors.

Signed-off-by: Tudor Ambarus 
---
 crypto/testmgr.c |  77 +++
 crypto/testmgr.h | 155 +++
 2 files changed, 221 insertions(+), 11 deletions(-)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 6f5f3ed..48438ef 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -1997,6 +1997,9 @@ static int do_test_kpp(struct crypto_kpp *tfm, const 
struct kpp_testvec *vec,
struct kpp_request *req;
void *input_buf = NULL;
void *output_buf = NULL;
+   void *a_public = NULL;
+   void *a_ss = NULL;
+   void *shared_secret = NULL;
struct tcrypt_result result;
unsigned int out_len_max;
int err = -ENOMEM;
@@ -2026,20 +2029,32 @@ static int do_test_kpp(struct crypto_kpp *tfm, const 
struct kpp_testvec *vec,
kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
 tcrypt_complete, &result);
 
-   /* Compute public key */
+   /* Compute party A's public key */
err = wait_async_op(&result, crypto_kpp_generate_public_key(req));
if (err) {
-   pr_err("alg: %s: generate public key test failed. err %d\n",
+   pr_err("alg: %s: Party A: generate public key test failed. err 
%d\n",
   alg, err);
goto free_output;
}
-   /* Verify calculated public key */
-   if (memcmp(vec->expected_a_public, sg_virt(req->dst),
-  vec->expected_a_public_size)) {
-   pr_err("alg: %s: generate public key test failed. Invalid 
output\n",
-  alg);
-   err = -EINVAL;
-   goto free_output;
+
+   if (vec->genkey) {
+   /* Save party A's public key */
+   a_public = kzalloc(out_len_max, GFP_KERNEL);
+   if (!a_public) {
+   err = -ENOMEM;
+   goto free_output;
+   }
+   memcpy(a_public, sg_virt(req->dst),
+  vec->expected_a_public_size);
+   } else {
+   /* Verify calculated public key */
+   if (memcmp(vec->expected_a_public, sg_virt(req->dst),
+  vec->expected_a_public_size)) {
+   pr_err("alg: %s: Party A: generate public key test 
failed. Invalid output\n",
+  alg);
+   err = -EINVAL;
+   goto free_output;
+   }
}
 
/* Calculate shared secret key by using counter part (b) public key. */
@@ -2058,15 +2073,53 @@ static int do_test_kpp(struct crypto_kpp *tfm, const 
struct kpp_testvec *vec,
 tcrypt_complete, &result);
err = wait_async_op(&result, crypto_kpp_compute_shared_secret(req));
if (err) {
-   pr_err("alg: %s: compute shard secret test failed. err %d\n",
+   pr_err("alg: %s: Party A: compute shared secret test failed. 
err %d\n",
   alg, err);
goto free_all;
}
+
+   if (vec->genkey) {
+   /* Save the shared secret obtained by party A */
+   a_ss = kzalloc(vec->expected_ss_size, GFP_KERNEL);
+   if (!a_ss) {
+   err = -ENOMEM;
+   goto free_all;
+   }
+   memcpy(a_ss, sg_virt(req->dst), vec->expected_ss_size);
+
+   /*
+* Calculate party B's shared secret by using party A's
+* public key.
+*/
+   err = crypto_kpp_set_secret(tfm, vec->b_secret,
+   vec->b_secret_size);
+   if (err < 0)
+   goto free_all;
+
+   sg_init_one(&src, a_public, vec->expected_a_public_size);
+   sg_init_one(&dst, output_buf, out_len_max);
+   kpp_request_set_input(req, &src, vec->expected_a_public_size);
+   kpp_request_set_output(req, &dst, out_len_max);
+   kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+tcrypt_complete, &result);
+   err = wait_async_op(&result,
+   crypto_kpp_compute_shared_secret(req));
+   if (err) {
+   pr_err("alg: %s: Party B: compute shared secret failed. 
err %d\n",
+  alg, err);
+   goto free_all;
+   }
+
+   shared_secret = a_ss;
+   } else {
+   shared_secret = 

[RFC PATCH 2/4] crypto: ecdh - allow user to provide NULL privkey

2017-05-17 Thread Tudor Ambarus
If the user provides a NULL ecc private key, the kernel will
generate it and further use it for ecdh.

Signed-off-by: Tudor Ambarus 
---
 crypto/ecdh.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/crypto/ecdh.c b/crypto/ecdh.c
index 63ca337..f28f5b5 100644
--- a/crypto/ecdh.c
+++ b/crypto/ecdh.c
@@ -55,6 +55,10 @@ static int ecdh_set_secret(struct crypto_kpp *tfm, const 
void *buf,
ctx->curve_id = params.curve_id;
ctx->ndigits = ndigits;
 
+   if (!params.key || !params.key_size)
+   return ecc_gen_privkey(ctx->curve_id, ctx->ndigits,
+  ctx->private_key);
+
if (ecc_is_key_valid(ctx->curve_id, ctx->ndigits,
 (const u8 *)params.key, params.key_size) < 0)
return -EINVAL;
-- 
2.7.4



[RFC PATCH 3/4] crypto: dh - allow user to provide NULL privkey

2017-05-17 Thread Tudor Ambarus
If the user provides a NULL private key, the kernel will
generate it and further use it for dh.

Signed-off-by: Tudor Ambarus 
---
 crypto/dh.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/crypto/dh.c b/crypto/dh.c
index 87e3542..33df165 100644
--- a/crypto/dh.c
+++ b/crypto/dh.c
@@ -83,7 +83,9 @@ static int dh_set_secret(struct crypto_kpp *tfm, const void 
*buf,
 unsigned int len)
 {
struct dh_ctx *ctx = dh_get_ctx(tfm);
+   u8 *rndbuf = NULL;
struct dh params;
+   int maxsize;
 
if (crypto_dh_decode_key(buf, len, ¶ms) < 0)
return -EINVAL;
@@ -91,12 +93,28 @@ static int dh_set_secret(struct crypto_kpp *tfm, const void 
*buf,
if (dh_set_params(ctx, ¶ms) < 0)
return -EINVAL;
 
+   if (!params.key || !params.key_size) {
+   maxsize = crypto_kpp_maxsize(tfm);
+   if (maxsize < 0)
+   return maxsize;
+
+   rndbuf = kmalloc(maxsize, GFP_KERNEL);
+   if (!rndbuf)
+   return -ENOMEM;
+
+   get_random_bytes(rndbuf, maxsize);
+   params.key = rndbuf;
+   params.key_size = maxsize;
+   }
+
ctx->xa = mpi_read_raw_data(params.key, params.key_size);
if (!ctx->xa) {
dh_clear_params(ctx);
+   kzfree(rndbuf);
return -EINVAL;
}
 
+   kzfree(rndbuf);
return 0;
 }
 
-- 
2.7.4



[RFC PATCH 0/4] crypto: (ec)dh - add privkey generation support

2017-05-17 Thread Tudor Ambarus
Hi,

This is an RFC to discuss how to support private key generation for dh and
ecdh.

This is helpful in a user-space to kernel (ec)dh offload because the keys
are generated in kernel and never revealed to user-space.

Private key generation is also helpful to implement forward secrecy.
A public/private key system demonstrates the property of forward secrecy
if it creates new key pairs for each communication session. These
key pairs are generated on an as-needed basis and are destroyed after
the session is over. If an attacker were to record previous encrypted
session data, they wouldn't be able to decrypt it with possession of a
long-term key.

There are crypto accelerators that are capable of generating and retaining
private keys without revealing them to software. This patch set is a
prerequisite for hardware private key generation support.

Tudor Ambarus (4):
  crypto: ecc - add privkey generation support
  crypto: ecdh - allow user to provide NULL privkey
  crypto: dh - allow user to provide NULL privkey
  crypto: testmgr - add genkey kpp test

 crypto/dh.c  |  18 +++
 crypto/ecc.c |  20 +++
 crypto/ecc.h |  14 +
 crypto/ecdh.c|   4 ++
 crypto/testmgr.c |  77 +++
 crypto/testmgr.h | 155 +++
 6 files changed, 277 insertions(+), 11 deletions(-)

-- 
2.7.4



[RFC PATCH 1/4] crypto: ecc - add privkey generation support

2017-05-17 Thread Tudor Ambarus
Add support for generating ecc private keys.

Generation of ecc private keys is helpful in a user-space to kernel
ecdh offload because the keys are not revealed to user-space. Private
key generation is also helpful to implement forward secrecy.

Signed-off-by: Tudor Ambarus 
---
 crypto/ecc.c | 20 
 crypto/ecc.h | 14 ++
 2 files changed, 34 insertions(+)

diff --git a/crypto/ecc.c b/crypto/ecc.c
index 414c78a..a591907 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -927,6 +927,26 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int 
ndigits,
return 0;
 }
 
+int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, u64 *privkey)
+{
+   const struct ecc_curve *curve = ecc_get_curve(curve_id);
+   u64 priv[ndigits];
+   unsigned int nbytes = ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
+
+   get_random_bytes(priv, nbytes);
+
+   if (vli_is_zero(priv, ndigits))
+   return -EINVAL;
+
+   /* Make sure the private key is in the range [1, n-1]. */
+   if (vli_cmp(curve->n, priv, ndigits) != 1)
+   return -EINVAL;
+
+   ecc_swap_digits(priv, privkey, ndigits);
+
+   return 0;
+}
+
 int ecdh_make_pub_key(unsigned int curve_id, unsigned int ndigits,
  const u8 *private_key, unsigned int private_key_len,
  u8 *public_key, unsigned int public_key_len)
diff --git a/crypto/ecc.h b/crypto/ecc.h
index 663d598..b94b7ce 100644
--- a/crypto/ecc.h
+++ b/crypto/ecc.h
@@ -44,6 +44,20 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int 
ndigits,
 const u8 *private_key, unsigned int private_key_len);
 
 /**
+ * ecc_gen_privkey() -  Generates an ECC private key.
+ * The private key is a random integer in the range 0 < random < n, where n is 
a
+ * prime that is the order of the cyclic subgroup generated by the 
distinguished
+ * point G.
+ * @curve_id:  id representing the curve to use
+ * @ndigits:   curve number of digits
+ * @private_key:   buffer for storing the generated private key
+ *
+ * Returns 0 if the private key was generated successfully, a negative value
+ * if an error occurred.
+ */
+int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, u64 *privkey);
+
+/**
  * ecdh_make_pub_key() - Compute an ECC public key
  *
  * @curve_id:  id representing the curve to use
-- 
2.7.4