[PATCH v2] perf beauty: Fix fsconfig generator

2021-04-14 Thread Vitaly Chikunov
After gnulib update sed stopped matching `[[:space:]]*+' as before,
causing the following compilation error:

  In file included from builtin-trace.c:719:
  trace/beauty/generated/fsconfig_arrays.c:2:3: error: expected expression 
before ']' token
  2 |  [] = "",
|   ^
  trace/beauty/generated/fsconfig_arrays.c:2:3: error: array index in 
initializer not of integer type
  trace/beauty/generated/fsconfig_arrays.c:2:3: note: (near initialization for 
'fsconfig_cmds')

Fix this by correcting the regular expression used in the generator.
Also, clean up the script by removing redundant egrep, xargs, and printf
invocations.

Fixes: d35293004a5e4 ("perf beauty: Add generator for fsconfig's 'cmd' arg 
values")
Co-authored-by: Dmitry V. Levin 
Signed-off-by: Vitaly Chikunov 
---
 tools/perf/trace/beauty/fsconfig.sh | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/tools/perf/trace/beauty/fsconfig.sh 
b/tools/perf/trace/beauty/fsconfig.sh
index 83fb24df05c9f..bc6ef7bb7a5f9 100755
--- a/tools/perf/trace/beauty/fsconfig.sh
+++ b/tools/perf/trace/beauty/fsconfig.sh
@@ -10,8 +10,7 @@ fi
 linux_mount=${linux_header_dir}/mount.h
 
 printf "static const char *fsconfig_cmds[] = {\n"
-regex='^[[:space:]]*+FSCONFIG_([[:alnum:]_]+)[[:space:]]*=[[:space:]]*([[:digit:]]+)[[:space:]]*,[[:space:]]*.*'
-egrep $regex ${linux_mount} | \
-   sed -r "s/$regex/\2 \1/g"   | \
-   xargs printf "\t[%s] = \"%s\",\n"
+ms='[[:space:]]*'
+sed -nr 
"s/^${ms}FSCONFIG_([[:alnum:]_]+)${ms}=${ms}([[:digit:]]+)${ms},.*/\t[\2] = 
\"\1\",/p" \
+   ${linux_mount}
 printf "};\n"
-- 
2.11.0



[PATCH] perf beauty: Fix fsconfig generator

2021-04-14 Thread Vitaly Chikunov
After gnulib update sed stopped matching `[[:space:]]*+' as before,
causing the following compilation error:

  In file included from builtin-trace.c:719:
  trace/beauty/generated/fsconfig_arrays.c:2:3: error: expected expression 
before ']' token
  2 |  [] = "",
|   ^
  trace/beauty/generated/fsconfig_arrays.c:2:3: error: array index in 
initializer not of integer type
  trace/beauty/generated/fsconfig_arrays.c:2:3: note: (near initialization for 
'fsconfig_cmds')

Fix this by correcting the regular expression used in the generator.
Also, clean up the script by removing redundant egrep, xargs, and printf
invocations.

Fixes: d35293004a5e4 ("perf beauty: Add generator for fsconfig's 'cmd' arg 
values")
Co-authored-by: Dmitry V. Levin 
Signed-off-by: Vitaly Chikunov 
---
 tools/perf/trace/beauty/fsconfig.sh | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/tools/perf/trace/beauty/fsconfig.sh 
b/tools/perf/trace/beauty/fsconfig.sh
index 83fb24df05c9f..cc76b2aa7a5af 100755
--- a/tools/perf/trace/beauty/fsconfig.sh
+++ b/tools/perf/trace/beauty/fsconfig.sh
@@ -10,8 +10,6 @@ fi
 linux_mount=${linux_header_dir}/mount.h
 
 printf "static const char *fsconfig_cmds[] = {\n"
-regex='^[[:space:]]*+FSCONFIG_([[:alnum:]_]+)[[:space:]]*=[[:space:]]*([[:digit:]]+)[[:space:]]*,[[:space:]]*.*'
-egrep $regex ${linux_mount} | \
-   sed -r "s/$regex/\2 \1/g"   | \
-   xargs printf "\t[%s] = \"%s\",\n"
+regex='^[[:space:]]*FSCONFIG_([[:alnum:]_]+)[[:space:]]*=[[:space:]]*([[:digit:]]+)[[:space:]]*,.*'
+sed -nr "s/$regex/\t[\2] = \"\1\",/p" ${linux_mount}
 printf "};\n"
-- 
2.11.0



Re: [PATCH v10 3/9] crypto: Add math to support fast NIST P384

2021-03-06 Thread Vitaly Chikunov
Stefan,

On Sat, Mar 06, 2021 at 06:29:18PM -0500, Stefan Berger wrote:
> On 3/6/21 2:25 PM, Vitaly Chikunov wrote:
> > 
> > On Thu, Mar 04, 2021 at 07:51:57PM -0500, Stefan Berger wrote:
> > > From: Saulo Alessandre 
> > > 
> > > * crypto/ecc.c
> > >- add vli_mmod_fast_384
> > >- change some routines to pass ecc_curve forward until vli_mmod_fast
> > > 
> > > * crypto/ecc.h
> > >- add ECC_CURVE_NIST_P384_DIGITS
> > >- change ECC_MAX_DIGITS to P384 size
> > > 
> > > Signed-off-by: Saulo Alessandre 
> > > Tested-by: Stefan Berger 
> > > ---
> > >   crypto/ecc.c | 266 +--
> > >   crypto/ecc.h |   3 +-
> > >   2 files changed, 194 insertions(+), 75 deletions(-)
> > > 
> > > diff --git a/crypto/ecc.c b/crypto/ecc.c
> > > index f6cef5a7942d..c125576cda6b 100644
> > > --- a/crypto/ecc.c
> > > +++ b/crypto/ecc.c
> > > @@ -778,18 +778,133 @@ static void vli_mmod_fast_256(u64 *result, const 
> > > u64 *product,
> > >   ...
> > >   /* Computes result = product % curve_prime for different curve_primes.
> > >*
> > >* Note that curve_primes are distinguished just by heuristic check and
> > >* not by complete conformance check.
> > >*/
> > >   static bool vli_mmod_fast(u64 *result, u64 *product,
> > > -   const u64 *curve_prime, unsigned int ndigits)
> > > +   const struct ecc_curve *curve)
> > >   {
> > >   u64 tmp[2 * ECC_MAX_DIGITS];
> > > + const u64 *curve_prime = curve->p;
> > > + const unsigned int ndigits = curve->g.ndigits;
> > > - /* Currently, both NIST primes have -1 in lowest qword. */
> > > - if (curve_prime[0] != -1ull) {
> > > + /* Currently, all NIST have name nist_.* */
> > > + if (strncmp(curve->name, "nist_", 5) != 0) {
> > I am not sure, but maybe this strncmp should not be optimized somehow,
> > since vli_mmod_fast could be called quite frequently. Perhaps by integer
> > algo id or even callback?
> 
> Should be optimized or should not be? You seem to say both.

Excuse me for the typo. I meant "should be optimized". I think, maybe
it's time to add algo selector id (for the case statement, for example
instead of `switch (ndigits)') or just callback for a low level mmod
function.

If you think this would not impact performance then nevermind.

Thanks,

> 
> The code code here is shared with ecrdsa. The comparison won't go beyond a
> single letter considering the naming of the curves define here:
> 
> "cp256a":
> https://elixir.bootlin.com/linux/v5.11.3/source/crypto/ecrdsa_defs.h#L49
> 
> "cp256b":
> https://elixir.bootlin.com/linux/v5.11.3/source/crypto/ecrdsa_defs.h#L82
> 
> "cp256c":
> https://elixir.bootlin.com/linux/v5.11.3/source/crypto/ecrdsa_defs.h#L119
> 
> "tc512a":
> https://elixir.bootlin.com/linux/v5.11.3/source/crypto/ecrdsa_defs.h#L168
> 
> and here:
> 
> "nist_192":
> https://elixir.bootlin.com/linux/v5.11.3/source/crypto/ecc_curve_defs.h#L18
> 
> "nist_256":
> https://elixir.bootlin.com/linux/v5.11.3/source/crypto/ecc_curve_defs.h#L45
> 
> 
> All the ecrdsa curves were previously evaluating 'curve_prime[0] != -1ull',
> so it doesn't change anything.
> 
>   Stefan
> 


Re: [PATCH v10 3/9] crypto: Add math to support fast NIST P384

2021-03-06 Thread Vitaly Chikunov
Stefan,

On Thu, Mar 04, 2021 at 07:51:57PM -0500, Stefan Berger wrote:
> From: Saulo Alessandre 
> 
> * crypto/ecc.c
>   - add vli_mmod_fast_384
>   - change some routines to pass ecc_curve forward until vli_mmod_fast
> 
> * crypto/ecc.h
>   - add ECC_CURVE_NIST_P384_DIGITS
>   - change ECC_MAX_DIGITS to P384 size
> 
> Signed-off-by: Saulo Alessandre 
> Tested-by: Stefan Berger 
> ---
>  crypto/ecc.c | 266 +--
>  crypto/ecc.h |   3 +-
>  2 files changed, 194 insertions(+), 75 deletions(-)
> 
> diff --git a/crypto/ecc.c b/crypto/ecc.c
> index f6cef5a7942d..c125576cda6b 100644
> --- a/crypto/ecc.c
> +++ b/crypto/ecc.c
> @@ -778,18 +778,133 @@ static void vli_mmod_fast_256(u64 *result, const u64 
> *product,
>  ...
>  /* Computes result = product % curve_prime for different curve_primes.
>   *
>   * Note that curve_primes are distinguished just by heuristic check and
>   * not by complete conformance check.
>   */
>  static bool vli_mmod_fast(u64 *result, u64 *product,
> -   const u64 *curve_prime, unsigned int ndigits)
> +   const struct ecc_curve *curve)
>  {
>   u64 tmp[2 * ECC_MAX_DIGITS];
> + const u64 *curve_prime = curve->p;
> + const unsigned int ndigits = curve->g.ndigits;
>  
> - /* Currently, both NIST primes have -1 in lowest qword. */
> - if (curve_prime[0] != -1ull) {
> + /* Currently, all NIST have name nist_.* */
> + if (strncmp(curve->name, "nist_", 5) != 0) {

I am not sure, but maybe this strncmp should not be optimized somehow,
since vli_mmod_fast could be called quite frequently. Perhaps by integer
algo id or even callback?

Thanks,

>   /* Try to handle Pseudo-Marsenne primes. */
>   if (curve_prime[ndigits - 1] == -1ull) {
>   vli_mmod_special(result, product, curve_prime,
> @@ -812,6 +927,9 @@ static bool vli_mmod_fast(u64 *result, u64 *product,
>   case 4:
>   vli_mmod_fast_256(result, product, curve_prime, tmp);
>   break;
> + case 6:
> + vli_mmod_fast_384(result, product, curve_prime, tmp);
> + break;
>   default:
>   pr_err_ratelimited("ecc: unsupported digits size!\n");
>   return false;
> @@ -835,22 +953,22 @@ EXPORT_SYMBOL(vli_mod_mult_slow);
>  
>  /* Computes result = (left * right) % curve_prime. */
>  static void vli_mod_mult_fast(u64 *result, const u64 *left, const u64 *right,
> -   const u64 *curve_prime, unsigned int ndigits)
> +   const struct ecc_curve *curve)
>  {
>   u64 product[2 * ECC_MAX_DIGITS];
>  
> - vli_mult(product, left, right, ndigits);
> - vli_mmod_fast(result, product, curve_prime, ndigits);
> + vli_mult(product, left, right, curve->g.ndigits);
> + vli_mmod_fast(result, product, curve);
>  }
>  
>  /* Computes result = left^2 % curve_prime. */
>  static void vli_mod_square_fast(u64 *result, const u64 *left,
> - const u64 *curve_prime, unsigned int ndigits)
> + const struct ecc_curve *curve)
>  {
>   u64 product[2 * ECC_MAX_DIGITS];
>  
> - vli_square(product, left, ndigits);
> - vli_mmod_fast(result, product, curve_prime, ndigits);
> + vli_square(product, left, curve->g.ndigits);
> + vli_mmod_fast(result, product, curve);
>  }
>  
>  #define EVEN(vli) (!(vli[0] & 1))


Re: [PATCH v10 1/9] crypto: Add support for ECDSA signature verification

2021-03-05 Thread Vitaly Chikunov
Jarkko,

On Fri, Mar 05, 2021 at 07:05:39PM +0200, Jarkko Sakkinen wrote:
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (c) 2021 IBM Corporation
> > + *
> > + * Redistribution and use in source and binary forms, with or without
> > + * modification, are permitted provided that the following conditions are
> > + * met:
> > + *  * Redistributions of source code must retain the above copyright
> > + *   notice, this list of conditions and the following disclaimer.
> > + *  * Redistributions in binary form must reproduce the above copyright
> > + *notice, this list of conditions and the following disclaimer in the
> > + *documentation and/or other materials provided with the distribution.
> > + *
> > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > + */
> 
> This license platter is redundant, given SPDX.

I think SPDX identifier supplements license plate and is machine readable
identifier, but it does not replace or making adding of license plate
redundant.

- Quoting https://spdx.dev/ids/

  "When a license defines a recommended notice to attach to files under
  that license (sometimes called a “standard header”), the SPDX project
  recommends that the standard header be included in the files, in
  addition to an SPDX ID.

  Additionally, when a file already contains a standard header or other
  license notice, the SPDX project recommends that those existing
  notices should not be removed. The SPDX ID is recommended to be used
  to supplement, not replace, existing notices in files."

- GPL license text have section on "How to Apply These Terms to Your New
  Programs" which says to add license boilerplate text and it does not
  say SPDX identifier is enough.

- Also, page https://www.kernel.org/doc/html/latest/process/license-rules.html
  does not forbid adding license plate text. (Even though it misguidedly
  says "alternative to boilerplate text" is the use of SPDX.)

- License text is a readable text and not just identifier.
  I think SPDX tag could be not legally binding in all jurisdictions.

By there reasons I believe you cannot request removing license platter
from the source and this should be author's decision.

Thanks,



Re: [PATCH v10 1/9] crypto: Add support for ECDSA signature verification

2021-03-05 Thread Vitaly Chikunov
Jarkko,

On Fri, Mar 05, 2021 at 07:05:39PM +0200, Jarkko Sakkinen wrote:
> On Thu, Mar 04, 2021 at 07:51:55PM -0500, Stefan Berger wrote:
> > +module_exit(ecdsa_exit);
> > +
> > +MODULE_LICENSE("GPL");
> > +MODULE_AUTHOR("Stefan Berger ");
> 
> Remove MODULE_AUTHOR(). It's redundant because of Git.

When it's decided that MODULE_AUTHOR is redundant because of git?
I don't see MODULE_AUTHOR define expanding to nothing in module.h.
Also, this info is shown for end user in modinfo. And kernel is still
distributed as a tarball on kernel.org.

Thanks,



Re: [PATCH v7 4/7] crypto: add ecc curve and expose them

2021-02-08 Thread Vitaly Chikunov
Ard,

On Mon, Feb 08, 2021 at 07:47:44AM +0100, Ard Biesheuvel wrote:
> On Mon, 8 Feb 2021 at 07:37, Vitaly Chikunov  wrote:
> >
> > Herbert,
> >
> > On Fri, Jan 29, 2021 at 02:00:04PM +1100, Herbert Xu wrote:
> > > On Thu, Jan 28, 2021 at 09:49:41PM -0500, Stefan Berger wrote:
> > > >
> > > > In my patch series I initially had registered the akciphers under the 
> > > > names
> > > > ecc-nist-p192 and ecc-nist-p256 but now, in V4, joined them together as
> > > > 'ecdsa'. This may be too generic for a name. Maybe it should be called
> > > > ecsda-nist for the NIST family.
> > >
> > > What I'm proposing is specifying the curve in the name as well, i.e.,
> > > ecdsa-nist-p192 instead of just ecdsa or ecdsa-nist.
> > >
> > > This simplifies the task of handling hardware that only supports a
> > > subset of curves.
> >
> > So, if some implementation supports multiple curves (like EC-RDSA
> > currently supports 5 curves), it should add 5 ecrdsa-{a,b,c,..}
> > algorithms with actually the same top level implementation?
> > Right?
> >
> 
> Yes. The only difference will be the init() function, which can be
> used to set the TFM properties that define which curve is being used.
> The other routines can be generic, and refer to those properties if
> the behavior is curve-specific.

Thanks. This may be good!

JFYI. There is possible non-hardware accelerated implementations
for ECC algorithms which (perhaps) may never go to the kernel source,
because they are generated code. For example
  https://gitlab.com/nisec/ecckiila



Re: [PATCH v7 4/7] crypto: add ecc curve and expose them

2021-02-07 Thread Vitaly Chikunov
Herbert,

On Fri, Jan 29, 2021 at 02:00:04PM +1100, Herbert Xu wrote:
> On Thu, Jan 28, 2021 at 09:49:41PM -0500, Stefan Berger wrote:
> >
> > In my patch series I initially had registered the akciphers under the names
> > ecc-nist-p192 and ecc-nist-p256 but now, in V4, joined them together as
> > 'ecdsa'. This may be too generic for a name. Maybe it should be called
> > ecsda-nist for the NIST family.
> 
> What I'm proposing is specifying the curve in the name as well, i.e.,
> ecdsa-nist-p192 instead of just ecdsa or ecdsa-nist.
> 
> This simplifies the task of handling hardware that only supports a
> subset of curves.

So, if some implementation supports multiple curves (like EC-RDSA
currently supports 5 curves), it should add 5 ecrdsa-{a,b,c,..}
algorithms with actually the same top level implementation?
Right?


> There is a parallel discussion of exactly what curves we should
> support in the kernel.  Personally if there is a user in the kernel
> for it then I'm happy to see it added.  In your specific case, as
> long as your use of the algorithm in x509 is accepted then I don't
> have any problems with adding support in the Crypto API.
> 
> Cheers,
> -- 
> Email: Herbert Xu 
> Home Page: http://gondor.apana.org.au/~herbert/
> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH v4 3/5] crypto: expose elliptic curve parameters as Crypto APIs

2020-12-11 Thread Vitaly Chikunov
Meng,

It looks like not just definitions but some static data is moved to
includes. Why?

Thanks,

On Fri, Dec 11, 2020 at 02:30:32PM +0800, Meng Yu wrote:
> Move elliptic curves definition to 'include/crypto/ecc_curve_defs.h',
> so all can use it,
> 
> Signed-off-by: Meng Yu 
> Reviewed-by: Zaibo Xu 
> ---
>  crypto/ecc.c|  1 -
>  crypto/ecc.h| 37 +
>  crypto/ecc_curve_defs.h | 57 -
>  crypto/ecrdsa_defs.h|  2 +-
>  include/crypto/ecc_curve_defs.h | 92 
> +
>  5 files changed, 95 insertions(+), 94 deletions(-)
>  delete mode 100644 crypto/ecc_curve_defs.h
>  create mode 100644 include/crypto/ecc_curve_defs.h
> 
> diff --git a/crypto/ecc.c b/crypto/ecc.c
> index c80aa25..f23efdd 100644
> --- a/crypto/ecc.c
> +++ b/crypto/ecc.c
> @@ -35,7 +35,6 @@
>  #include 
>  
>  #include "ecc.h"
> -#include "ecc_curve_defs.h"
>  
>  typedef struct {
>   u64 m_low;
> diff --git a/crypto/ecc.h b/crypto/ecc.h
> index d4e546b..e5afaf3 100644
> --- a/crypto/ecc.h
> +++ b/crypto/ecc.h
> @@ -26,6 +26,8 @@
>  #ifndef _CRYPTO_ECC_H
>  #define _CRYPTO_ECC_H
>  
> +#include 
> +
>  /* One digit is u64 qword. */
>  #define ECC_CURVE_NIST_P192_DIGITS  3
>  #define ECC_CURVE_NIST_P256_DIGITS  4
> @@ -33,44 +35,9 @@
>  
>  #define ECC_DIGITS_TO_BYTES_SHIFT 3
>  
> -/**
> - * struct ecc_point - elliptic curve point in affine coordinates
> - *
> - * @x:   X coordinate in vli form.
> - * @y:   Y coordinate in vli form.
> - * @ndigits: Length of vlis in u64 qwords.
> - */
> -struct ecc_point {
> - u64 *x;
> - u64 *y;
> - u8 ndigits;
> -};
> -
>  #define ECC_POINT_INIT(x, y, ndigits)(struct ecc_point) { x, y, 
> ndigits }
>  
>  /**
> - * struct ecc_curve - definition of elliptic curve
> - *
> - * @name:Short name of the curve.
> - * @g:   Generator point of the curve.
> - * @p:   Prime number, if Barrett's reduction is used for this 
> curve
> - *   pre-calculated value 'mu' is appended to the @p after ndigits.
> - *   Use of Barrett's reduction is heuristically determined in
> - *   vli_mmod_fast().
> - * @n:   Order of the curve group.
> - * @a:   Curve parameter a.
> - * @b:   Curve parameter b.
> - */
> -struct ecc_curve {
> - char *name;
> - struct ecc_point g;
> - u64 *p;
> - u64 *n;
> - u64 *a;
> - u64 *b;
> -};
> -
> -/**
>   * ecc_is_key_valid() - Validate a given ECDH private key
>   *
>   * @curve_id:id representing the curve to use
> diff --git a/crypto/ecc_curve_defs.h b/crypto/ecc_curve_defs.h
> deleted file mode 100644
> index 69be6c7..000
> --- a/crypto/ecc_curve_defs.h
> +++ /dev/null
> @@ -1,57 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -#ifndef _CRYTO_ECC_CURVE_DEFS_H
> -#define _CRYTO_ECC_CURVE_DEFS_H
> -
> -/* NIST P-192: a = p - 3 */
> -static u64 nist_p192_g_x[] = { 0xF4FF0AFD82FF1012ull, 0x7CBF20EB43A18800ull,
> - 0x188DA80EB03090F6ull };
> -static u64 nist_p192_g_y[] = { 0x73F977A11E794811ull, 0x631011ED6B24CDD5ull,
> - 0x07192B95FFC8DA78ull };
> -static u64 nist_p192_p[] = { 0xull, 0xFFFEull,
> - 0xull };
> -static u64 nist_p192_n[] = { 0x146BC9B1B4D22831ull, 0x99DEF836ull,
> - 0xull };
> -static u64 nist_p192_a[] = { 0xFFFCull, 0xFFFEull,
> - 0xull };
> -static u64 nist_p192_b[] = { 0xFEB8DEECC146B9B1ull, 0x0FA7E9AB72243049ull,
> - 0x64210519E59C80E7ull };
> -static struct ecc_curve nist_p192 = {
> - .name = "nist_192",
> - .g = {
> - .x = nist_p192_g_x,
> - .y = nist_p192_g_y,
> - .ndigits = 3,
> - },
> - .p = nist_p192_p,
> - .n = nist_p192_n,
> - .a = nist_p192_a,
> - .b = nist_p192_b
> -};
> -
> -/* NIST P-256: a = p - 3 */
> -static u64 nist_p256_g_x[] = { 0xF4A13945D898C296ull, 0x77037D812DEB33A0ull,
> - 0xF8BCE6E563A440F2ull, 0x6B17D1F2E12C4247ull };
> -static u64 nist_p256_g_y[] = { 0xCBB6406837BF51F5ull, 0x2BCE33576B315ECEull,
> - 0x8EE7EB4A7C0F9E16ull, 0x4FE342E2FE1A7F9Bull };
> -static u64 nist_p256_p[] = { 0xull, 0xull,
> - 0xull, 0x0001ull };
> -static u64 nist_p256_n[] = { 0xF3B9CAC2FC632551ull, 0xBCE6FAADA7179E84ull,
> - 0xull, 0xull };
> -static u64 nist_p256_a[] = { 0xFFFCull, 0xull,
> - 0xull, 0x0001ull };
> -static u64 nist_p256_b[] = { 

Re: [PATCH v6 6/8] X.509: support OSCCA certificate parse

2020-09-12 Thread Vitaly Chikunov
On Thu, Sep 03, 2020 at 09:12:40PM +0800, Tianjia Zhang wrote:
> The digital certificate format based on SM2 crypto algorithm as
> specified in GM/T 0015-2012. It was published by State Encryption
> Management Bureau, China.
> 
> This patch adds the OID object identifier defined by OSCCA. The
> x509 certificate supports sm2-with-sm3 type certificate parsing.
> It uses the standard elliptic curve public key, and the sm2
> algorithm signs the hash generated by sm3.
> 
> Signed-off-by: Tianjia Zhang 
> Tested-by: Xufeng Zhang 
> ---
>  crypto/asymmetric_keys/x509_cert_parser.c | 14 +-
>  include/linux/oid_registry.h  |  6 ++
>  2 files changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/crypto/asymmetric_keys/x509_cert_parser.c 
> b/crypto/asymmetric_keys/x509_cert_parser.c
> index 26ec20ef4899..6a8aee22bfd4 100644
> --- a/crypto/asymmetric_keys/x509_cert_parser.c
> +++ b/crypto/asymmetric_keys/x509_cert_parser.c
> @@ -234,6 +234,10 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
>   case OID_gost2012Signature512:
>   ctx->cert->sig->hash_algo = "streebog512";
>   goto ecrdsa;
> +
> + case OID_sm2_with_sm3:
> + ctx->cert->sig->hash_algo = "sm3";
> + goto sm2;
>   }
>  
>  rsa_pkcs1:
> @@ -246,6 +250,11 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
>   ctx->cert->sig->encoding = "raw";
>   ctx->algo_oid = ctx->last_oid;
>   return 0;
> +sm2:
> + ctx->cert->sig->pkey_algo = "sm2";
> + ctx->cert->sig->encoding = "raw";
> + ctx->algo_oid = ctx->last_oid;
> + return 0;
>  }
>  
>  /*
> @@ -266,7 +275,8 @@ int x509_note_signature(void *context, size_t hdrlen,
>   }
>  
>   if (strcmp(ctx->cert->sig->pkey_algo, "rsa") == 0 ||
> - strcmp(ctx->cert->sig->pkey_algo, "ecrdsa") == 0) {
> + strcmp(ctx->cert->sig->pkey_algo, "ecrdsa") == 0 ||
> + strcmp(ctx->cert->sig->pkey_algo, "sm2") == 0) {
>   /* Discard the BIT STRING metadata */
>   if (vlen < 1 || *(const u8 *)value != 0)
>   return -EBADMSG;
> @@ -456,6 +466,8 @@ int x509_extract_key_data(void *context, size_t hdrlen,
>   else if (ctx->last_oid == OID_gost2012PKey256 ||
>ctx->last_oid == OID_gost2012PKey512)
>   ctx->cert->pub->pkey_algo = "ecrdsa";
> + else if (ctx->last_oid == OID_id_ecPublicKey)
> + ctx->cert->pub->pkey_algo = "sm2";
>   else
>   return -ENOPKG;
>  
> diff --git a/include/linux/oid_registry.h b/include/linux/oid_registry.h
> index 657d6bf2c064..48fe3133ff39 100644
> --- a/include/linux/oid_registry.h
> +++ b/include/linux/oid_registry.h
> @@ -107,6 +107,12 @@ enum OID {
>   OID_gostTC26Sign512B,   /* 1.2.643.7.1.2.1.2.2 */
>   OID_gostTC26Sign512C,   /* 1.2.643.7.1.2.1.2.3 */
>  
> + /* OSCCA */
> + OID_sm2,/* 1.2.156.10197.1.301 */
> + OID_sm3,/* 1.2.156.10197.1.401 */
> + OID_sm2_with_sm3,   /* 1.2.156.10197.1.501 */
> + OID_sm3WithRSAEncryption,   /* 1.2.156.10197.1.504 */

OID_sm3WithRSAEncryption identifier is unused and this mode looks not
implemented. But, this is probably ok for possible future extension.

Reviewed-by: Vitaly Chikunov 

Thanks,


> +
>   OID__NR
>  };
>  


Re: [PATCH v6 8/8] integrity: Asymmetric digsig supports SM2-with-SM3 algorithm

2020-09-12 Thread Vitaly Chikunov
On Thu, Sep 03, 2020 at 09:12:42PM +0800, Tianjia Zhang wrote:
> Asymmetric digsig supports SM2-with-SM3 algorithm combination,
> so that IMA can also verify SM2's signature data.
> 
> Signed-off-by: Tianjia Zhang 
> Tested-by: Xufeng Zhang 
> Reviewed-by: Mimi Zohar  (coding, not crypto

It looks not breaking ecrdsa/streebog handling and accords to rfc draft:

  https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02

  5.1.4.2.  Hash Functions
The sm2 digital signature algorithm requires the hash functions
approved by Chinese Commercial Cryptography Administration Office,
such as sm3.

Reviewed-by: Vitaly Chikunov 

Thanks,

> ---
>  security/integrity/digsig_asymmetric.c | 14 +++---
>  1 file changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/security/integrity/digsig_asymmetric.c 
> b/security/integrity/digsig_asymmetric.c
> index cfa4127d0518..b86a4a8f61ab 100644
> --- a/security/integrity/digsig_asymmetric.c
> +++ b/security/integrity/digsig_asymmetric.c
> @@ -99,14 +99,22 @@ int asymmetric_verify(struct key *keyring, const char 
> *sig,
>   memset(, 0, sizeof(pks));
>  
>   pks.hash_algo = hash_algo_name[hdr->hash_algo];
> - if (hdr->hash_algo == HASH_ALGO_STREEBOG_256 ||
> - hdr->hash_algo == HASH_ALGO_STREEBOG_512) {
> + switch (hdr->hash_algo) {
> + case HASH_ALGO_STREEBOG_256:
> + case HASH_ALGO_STREEBOG_512:
>   /* EC-RDSA and Streebog should go together. */
>   pks.pkey_algo = "ecrdsa";
>   pks.encoding = "raw";
> - } else {
> + break;
> + case HASH_ALGO_SM3_256:
> + /* SM2 and SM3 should go together. */
> + pks.pkey_algo = "sm2";
> + pks.encoding = "raw";
> + break;
> + default:
>   pks.pkey_algo = "rsa";
>   pks.encoding = "pkcs1";
> + break;
>   }
>   pks.digest = (u8 *)data;
>   pks.digest_size = datalen;


Re: Should perf version match kernel version?

2020-07-29 Thread Vitaly Chikunov
Peter, Arnaldo,

On Wed, Jul 29, 2020 at 01:27:32PM -0300, Arnaldo Carvalho de Melo wrote:
> 
> 
> On July 29, 2020 1:02:20 PM GMT-03:00, pet...@infradead.org wrote:
> >On Wed, Jul 29, 2020 at 06:56:47PM +0300, Vitaly Chikunov wrote:
> >> Hi,
> >> 
> >> It seems that most distros try to have perf version to match with
> >> running kernel version. Is is requirement? Would it be better to have
> >> single perf from kernel mainline to work with any (older) kernel
> >> version?
> >> 
> >> We have different kernel versions in ALT Linux (stable for 4.19, 5.4,
> >> and 5.7) and I want to understand if we should have three perfs or
> >> single package will be enough.
> >
> >We strive to have it all compatible, older perf should work on newer
> >kernel and newer perf should work on older kernel.
> >
> >How well it's all tested is another.
> >
> >Personally I often use a very old perf.
> 
> Yeah, never was a requirement, if you find some problem using a new perf on 
> an old kernel or the other way around, please report.

That's great to know. Thanks for the answers!



Should perf version match kernel version?

2020-07-29 Thread Vitaly Chikunov
Hi,

It seems that most distros try to have perf version to match with
running kernel version. Is is requirement? Would it be better to have
single perf from kernel mainline to work with any (older) kernel
version?

We have different kernel versions in ALT Linux (stable for 4.19, 5.4,
and 5.7) and I want to understand if we should have three perfs or
single package will be enough.

Thanks,



Re: [PATCH v3 0/8] crpyto: introduce OSCCA certificate and SM2 asymmetric algorithm

2020-06-09 Thread Vitaly Chikunov
Tianjia,

On Tue, Jun 09, 2020 at 09:48:47PM +0800, Tianjia Zhang wrote:
> Hello all,
> 
> This new module implement the OSCCA certificate and SM2 public key
> algorithm. It was published by State Encryption Management Bureau, China.
> List of specifications for OSCCA certificate and SM2 elliptic curve
> public key cryptography:
> 
> * GM/T 0003.1-2012
> * GM/T 0003.2-2012
> * GM/T 0003.3-2012
> * GM/T 0003.4-2012
> * GM/T 0003.5-2012
> * GM/T 0015-2012
> * GM/T 0009-2012 
> 
> IETF: https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02
> oscca: http://www.oscca.gov.cn/sca/xxgk/2010-12/17/content_1002386.shtml
> scctc: http://www.gmbz.org.cn/main/bzlb.html
> 
> These patchs add the OID object identifier defined by OSCCA. The
> x509 certificate supports sm2-with-sm3 type certificate parsing
> and verification.
> 
> The sm2 algorithm is based on libgcrypt's mpi implementation, and has
> made some additions to the kernel's original mpi library, and added the
> implementation of ec to better support elliptic curve-like algorithms.
> 
> sm2 has good support in both openssl and gnupg projects, and sm3 and sm4
> of the OSCCA algorithm family have also been implemented in the kernel.
> 
> Among them, sm3 and sm4 have been well implemented in the kernel.
> This group of patches has newly introduced sm2. In order to implement
> sm2 more perfectly, I expanded the mpi library and introduced the
> ec implementation of the mpi library as the basic algorithm. Compared
> to the kernel's crypto/ecc.c, the implementation of mpi/ec.c is more
> complete and elegant, sm2 is implemented based on these algorithms.

Does it use constant-time algorithms?

Thanks,

> 
> ---
> v3 changes:
>   1. integrity asymmetric digsig support sm2-with-sm3 algorithm.
>   2. remove unused sm2_set_priv_key().
>   3. rebase on mainline.
> 
> v2 changes:
>   1. simplify the sm2 algorithm and only retain the verify function.
>   2. extract the sm2 certificate code into a separate file.
> 
> Tianjia Zhang (8):
>   crypto: sm3 - export crypto_sm3_final function
>   lib/mpi: Extend the MPI library
>   lib/mpi: Introduce ec implementation to MPI library
>   crypto: sm2 - introduce OSCCA SM2 asymmetric cipher algorithm
>   crypto: testmgr - support test with different ciphertext per
> encryption
>   X.509: support OSCCA certificate parse
>   X.509: support OSCCA sm2-with-sm3 certificate verification
>   integrity: Asymmetric digsig supports SM2-with-SM3 algorithm
> 
>  crypto/Kconfig|   17 +
>  crypto/Makefile   |8 +
>  crypto/asymmetric_keys/Makefile   |1 +
>  crypto/asymmetric_keys/public_key.c   |6 +
>  crypto/asymmetric_keys/public_key_sm2.c   |   59 +
>  crypto/asymmetric_keys/x509_cert_parser.c |   14 +-
>  crypto/asymmetric_keys/x509_public_key.c  |2 +
>  crypto/sm2.c  |  473 +++
>  crypto/sm2signature.asn1  |4 +
>  crypto/sm3_generic.c  |7 +-
>  crypto/testmgr.c  |7 +-
>  include/crypto/public_key.h   |   14 +
>  include/crypto/sm2.h  |   25 +
>  include/crypto/sm3.h  |2 +
>  include/linux/mpi.h   |  193 +++
>  include/linux/oid_registry.h  |6 +
>  lib/mpi/Makefile  |6 +
>  lib/mpi/ec.c  | 1538 +
>  lib/mpi/mpi-add.c |  207 +++
>  lib/mpi/mpi-bit.c |  251 
>  lib/mpi/mpi-cmp.c |   46 +-
>  lib/mpi/mpi-div.c |  259 
>  lib/mpi/mpi-internal.h|   53 +
>  lib/mpi/mpi-inv.c |  143 ++
>  lib/mpi/mpi-mod.c |  155 +++
>  lib/mpi/mpi-mul.c |  166 +++
>  lib/mpi/mpicoder.c|  336 +
>  lib/mpi/mpih-div.c|  294 
>  lib/mpi/mpih-mul.c|   25 +
>  lib/mpi/mpiutil.c |  204 +++
>  security/integrity/digsig_asymmetric.c|   14 +-
>  31 files changed, 4517 insertions(+), 18 deletions(-)
>  create mode 100644 crypto/asymmetric_keys/public_key_sm2.c
>  create mode 100644 crypto/sm2.c
>  create mode 100644 crypto/sm2signature.asn1
>  create mode 100644 include/crypto/sm2.h
>  create mode 100644 lib/mpi/ec.c
>  create mode 100644 lib/mpi/mpi-add.c
>  create mode 100644 lib/mpi/mpi-div.c
>  create mode 100644 lib/mpi/mpi-inv.c
>  create mode 100644 lib/mpi/mpi-mod.c
>  create mode 100644 lib/mpi/mpi-mul.c
> 
> -- 
> 2.17.1


[tip:perf/urgent] perf arm64: Fix mksyscalltbl when system kernel headers are ahead of the kernel

2019-05-28 Thread tip-bot for Vitaly Chikunov
Commit-ID:  f95d050cdc5d34f9a4417e06c392ccbf146037bb
Gitweb: https://git.kernel.org/tip/f95d050cdc5d34f9a4417e06c392ccbf146037bb
Author: Vitaly Chikunov 
AuthorDate: Tue, 21 May 2019 06:02:03 +0300
Committer:  Arnaldo Carvalho de Melo 
CommitDate: Tue, 28 May 2019 09:49:03 -0300

perf arm64: Fix mksyscalltbl when system kernel headers are ahead of the kernel

When a host system has kernel headers that are newer than a compiling
kernel, mksyscalltbl fails with errors such as:

  : In function 'main':
  :271:44: error: '__NR_kexec_file_load' undeclared (first use in this 
function)
  :271:44: note: each undeclared identifier is reported only once for 
each function it appears in
  :272:46: error: '__NR_pidfd_send_signal' undeclared (first use in this 
function)
  :273:43: error: '__NR_io_uring_setup' undeclared (first use in this 
function)
  :274:43: error: '__NR_io_uring_enter' undeclared (first use in this 
function)
  :275:46: error: '__NR_io_uring_register' undeclared (first use in this 
function)
  tools/perf/arch/arm64/entry/syscalls//mksyscalltbl: line 48: 
/tmp/create-table-xvUQdD: Permission denied

mksyscalltbl is compiled with default host includes, but run with
compiling kernel tree includes, causing some syscall numbers to being
undeclared.

Committer testing:

Before this patch, in my cross build environment, no build problems, but
these new syscalls were not in the syscalls.c generated from the
unistd.h file, which is a bug, this patch fixes it:

perfbuilder@6e20056ed532:/git/perf$ tail 
/tmp/build/perf/arch/arm64/include/generated/asm/syscalls.c
[292] = "io_pgetevents",
[293] = "rseq",
[294] = "kexec_file_load",
[424] = "pidfd_send_signal",
[425] = "io_uring_setup",
[426] = "io_uring_enter",
[427] = "io_uring_register",
[428] = "syscalls",
};
perfbuilder@6e20056ed532:/git/perf$ strings /tmp/build/perf/perf | egrep 
'^(io_uring_|pidfd_|kexec_file)'
kexec_file_load
pidfd_send_signal
io_uring_setup
io_uring_enter
io_uring_register
perfbuilder@6e20056ed532:/git/perf$
$

Well, there is that last "syscalls" thing, but that looks like some
other bug.

Signed-off-by: Vitaly Chikunov 
Tested-by: Arnaldo Carvalho de Melo 
Tested-by: Michael Petlan 
Cc: Alexander Shishkin 
Cc: Hendrik Brueckner 
Cc: Jiri Olsa 
Cc: Kim Phillips 
Cc: Namhyung Kim 
Cc: Peter Zijlstra 
Cc: Ravi Bangoria 
Link: http://lkml.kernel.org/r/20190521030203.1447-1...@altlinux.org
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/perf/arch/arm64/entry/syscalls/mksyscalltbl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl 
b/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
index c88fd32563eb..459469b7222c 100755
--- a/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
+++ b/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
@@ -56,7 +56,7 @@ create_table()
echo "};"
 }
 
-$gcc -E -dM -x c  $input  \
+$gcc -E -dM -x c -I $incpath/include/uapi $input \
|sed -ne 's/^#define __NR_//p' \
|sort -t' ' -k2 -nu\
|create_table


Re: [PATCH] perf arm64: Fix mksyscalltbl when system kernel headers are ahead of the kernel

2019-05-21 Thread Vitaly Chikunov
Arnaldo,

On Tue, May 21, 2019 at 03:03:54PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Tue, May 21, 2019 at 12:19:18PM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Tue, May 21, 2019 at 04:34:47PM +0200, Michael Petlan escreveu:
> > > On Tue, 21 May 2019, Arnaldo Carvalho de Melo wrote:
> > > > Em Tue, May 21, 2019 at 06:02:03AM +0300, Vitaly Chikunov escreveu:
> > > > > When a host system has kernel headers that are newer than a compiling
> > > > > kernel, mksyscalltbl fails with errors such as:
> 
> > > > >   : In function 'main':
> > > > >   :271:44: error: '__NR_kexec_file_load' undeclared (first use 
> > > > > in this function)
> > > > >   :271:44: note: each undeclared identifier is reported only 
> > > > > once for each function it appears in
> > > > >   :272:46: error: '__NR_pidfd_send_signal' undeclared (first 
> > > > > use in this function)
> > > > >   :273:43: error: '__NR_io_uring_setup' undeclared (first use 
> > > > > in this function)
> > > > >   :274:43: error: '__NR_io_uring_enter' undeclared (first use 
> > > > > in this function)
> > > > >   :275:46: error: '__NR_io_uring_register' undeclared (first 
> > > > > use in this function)
> > > > >   tools/perf/arch/arm64/entry/syscalls//mksyscalltbl: line 48: 
> > > > > /tmp/create-table-xvUQdD: Permission denied
> 
> > > > > mksyscalltbl is compiled with default host includes, but run with
> 
> > > > It shouldn't :-\ So with this you're making it use the ones shipped in
> > > > tools/include? Good, I'll test it, thanks!
> 
> > > I've hit the issue too, this patch fixes it for me.
> > > Tested.
> 
> > Thanks, I'll add your Tested-by, appreciated.
> 
> Was this in a cross-build environment? Native?

It was native build on aarch64 with both 'hostcc' and 'gcc' arguments of
mksyscalltbl being set to gcc.

> I'm asking because I test
> this on several cross build environments, like on ubuntu 19.04 cross
> building to aarch64:
> ... 
> I.e. it didn't fail the build, but in the end these new syscalls are not
> there, while with your patch, they are:

Probably in your case system headers was older than kernel you are
building so you just silently losing syscalls.

> Thanks, applied.

Thanks!

> 
> - Arnaldo


[PATCH] perf arm64: Fix mksyscalltbl when system kernel headers are ahead of the kernel

2019-05-20 Thread Vitaly Chikunov
When a host system has kernel headers that are newer than a compiling
kernel, mksyscalltbl fails with errors such as:

  : In function 'main':
  :271:44: error: '__NR_kexec_file_load' undeclared (first use in this 
function)
  :271:44: note: each undeclared identifier is reported only once for 
each function it appears in
  :272:46: error: '__NR_pidfd_send_signal' undeclared (first use in this 
function)
  :273:43: error: '__NR_io_uring_setup' undeclared (first use in this 
function)
  :274:43: error: '__NR_io_uring_enter' undeclared (first use in this 
function)
  :275:46: error: '__NR_io_uring_register' undeclared (first use in this 
function)
  tools/perf/arch/arm64/entry/syscalls//mksyscalltbl: line 48: 
/tmp/create-table-xvUQdD: Permission denied

mksyscalltbl is compiled with default host includes, but run with
compiling kernel tree includes, causing some syscall numbers being
undeclared.

Signed-off-by: Vitaly Chikunov 
Cc: Alexander Shishkin 
Cc: Arnaldo Carvalho de Melo 
Cc: Hendrik Brueckner 
Cc: Ingo Molnar 
Cc: Jiri Olsa 
Cc: Kim Phillips 
Cc: Namhyung Kim 
Cc: Peter Zijlstra 
Cc: Ravi Bangoria 
---
 tools/perf/arch/arm64/entry/syscalls/mksyscalltbl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl 
b/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
index c88fd32563eb..459469b7222c 100755
--- a/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
+++ b/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
@@ -56,7 +56,7 @@ create_table()
echo "};"
 }
 
-$gcc -E -dM -x c  $input  \
+$gcc -E -dM -x c -I $incpath/include/uapi $input \
|sed -ne 's/^#define __NR_//p' \
|sort -t' ' -k2 -nu\
|create_table
-- 
2.11.0



[PATCH v7 07/11] crypto: Kconfig - create Public-key cryptography section

2019-03-01 Thread Vitaly Chikunov
Group RSA, DH, and ECDH into Public-key cryptography config section.

Signed-off-by: Vitaly Chikunov 
---
 crypto/Kconfig | 48 +---
 1 file changed, 25 insertions(+), 23 deletions(-)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index bbab6bf33519..370cbdca87a7 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -113,29 +113,6 @@ config CRYPTO_ACOMP
select CRYPTO_ALGAPI
select CRYPTO_ACOMP2
 
-config CRYPTO_RSA
-   tristate "RSA algorithm"
-   select CRYPTO_AKCIPHER
-   select CRYPTO_MANAGER
-   select MPILIB
-   select ASN1
-   help
- Generic implementation of the RSA public key algorithm.
-
-config CRYPTO_DH
-   tristate "Diffie-Hellman algorithm"
-   select CRYPTO_KPP
-   select MPILIB
-   help
- Generic implementation of the Diffie-Hellman algorithm.
-
-config CRYPTO_ECDH
-   tristate "ECDH algorithm"
-   select CRYPTO_KPP
-   select CRYPTO_RNG_DEFAULT
-   help
- Generic implementation of the ECDH algorithm
-
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
@@ -253,6 +230,31 @@ config CRYPTO_GLUE_HELPER_X86
 config CRYPTO_ENGINE
tristate
 
+comment "Public-key cryptography"
+
+config CRYPTO_RSA
+   tristate "RSA algorithm"
+   select CRYPTO_AKCIPHER
+   select CRYPTO_MANAGER
+   select MPILIB
+   select ASN1
+   help
+ Generic implementation of the RSA public key algorithm.
+
+config CRYPTO_DH
+   tristate "Diffie-Hellman algorithm"
+   select CRYPTO_KPP
+   select MPILIB
+   help
+ Generic implementation of the Diffie-Hellman algorithm.
+
+config CRYPTO_ECDH
+   tristate "ECDH algorithm"
+   select CRYPTO_KPP
+   select CRYPTO_RNG_DEFAULT
+   help
+ Generic implementation of the ECDH algorithm
+
 comment "Authenticated Encryption with Associated Data"
 
 config CRYPTO_CCM
-- 
2.11.0



[PATCH v7 02/11] crypto: akcipher - check the presence of callback before the call

2019-03-01 Thread Vitaly Chikunov
Because with introduction of EC-RDSA and change in workings of RSA in
regard to sign/verify, akcipher could have not all callbacks defined,
check the presence of callbacks before calling them to increase
robustness.

Signed-off-by: Vitaly Chikunov 
---
 include/crypto/akcipher.h | 25 -
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/include/crypto/akcipher.h b/include/crypto/akcipher.h
index 2d690494568c..f537fad1989f 100644
--- a/include/crypto/akcipher.h
+++ b/include/crypto/akcipher.h
@@ -268,7 +268,10 @@ static inline unsigned int crypto_akcipher_maxsize(struct 
crypto_akcipher *tfm)
 {
struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
 
-   return alg->max_size(tfm);
+   if (alg->max_size)
+   return alg->max_size(tfm);
+   else
+   return 0;
 }
 
 /**
@@ -287,10 +290,11 @@ static inline int crypto_akcipher_encrypt(struct 
akcipher_request *req)
struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
struct crypto_alg *calg = tfm->base.__crt_alg;
unsigned int src_len = req->src_len;
-   int ret;
+   int ret = -ENOSYS;
 
crypto_stats_get(calg);
-   ret = alg->encrypt(req);
+   if (alg->encrypt)
+   ret = alg->encrypt(req);
crypto_stats_akcipher_encrypt(src_len, ret, calg);
return ret;
 }
@@ -311,10 +315,11 @@ static inline int crypto_akcipher_decrypt(struct 
akcipher_request *req)
struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
struct crypto_alg *calg = tfm->base.__crt_alg;
unsigned int src_len = req->src_len;
-   int ret;
+   int ret = -ENOSYS;
 
crypto_stats_get(calg);
-   ret = alg->decrypt(req);
+   if (alg->decrypt)
+   ret = alg->decrypt(req);
crypto_stats_akcipher_decrypt(src_len, ret, calg);
return ret;
 }
@@ -334,10 +339,11 @@ static inline int crypto_akcipher_sign(struct 
akcipher_request *req)
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
struct crypto_alg *calg = tfm->base.__crt_alg;
-   int ret;
+   int ret = -ENOSYS;
 
crypto_stats_get(calg);
-   ret = alg->sign(req);
+   if (alg->sign)
+   ret = alg->sign(req);
crypto_stats_akcipher_sign(ret, calg);
return ret;
 }
@@ -357,10 +363,11 @@ static inline int crypto_akcipher_verify(struct 
akcipher_request *req)
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
struct crypto_alg *calg = tfm->base.__crt_alg;
-   int ret;
+   int ret = -ENOSYS;
 
crypto_stats_get(calg);
-   ret = alg->verify(req);
+   if (alg->verify)
+   ret = alg->verify(req);
crypto_stats_akcipher_verify(ret, calg);
return ret;
 }
-- 
2.11.0



[PATCH v7 01/11] KEYS: report to keyctl only actually supported key ops

2019-03-01 Thread Vitaly Chikunov
Because with the introduction of EC-RDSA and change in workings of RSA
in regard to sign/verify, akcipher may have not all callbacks defined,
report to keyctl only actually supported ops determined by the presence
of the akcipher callbacks.

Cc: David Howells 
Cc: keyri...@vger.kernel.org
Signed-off-by: Vitaly Chikunov 
---
 crypto/asymmetric_keys/public_key.c | 16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index f5d85b47fcc6..c2e4e73fcf06 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -130,11 +130,17 @@ static int software_key_query(const struct 
kernel_pkey_params *params,
info->max_sig_size = len;
info->max_enc_size = len;
info->max_dec_size = len;
-   info->supported_ops = (KEYCTL_SUPPORTS_ENCRYPT |
-  KEYCTL_SUPPORTS_VERIFY);
-   if (pkey->key_is_private)
-   info->supported_ops |= (KEYCTL_SUPPORTS_DECRYPT |
-   KEYCTL_SUPPORTS_SIGN);
+   info->supported_ops = 0;
+   if (crypto_akcipher_alg(tfm)->verify)
+   info->supported_ops |= KEYCTL_SUPPORTS_VERIFY;
+   if (crypto_akcipher_alg(tfm)->encrypt)
+   info->supported_ops |= KEYCTL_SUPPORTS_ENCRYPT;
+   if (pkey->key_is_private) {
+   if (crypto_akcipher_alg(tfm)->decrypt)
+   info->supported_ops |= KEYCTL_SUPPORTS_DECRYPT;
+   if (crypto_akcipher_alg(tfm)->sign)
+   info->supported_ops |= KEYCTL_SUPPORTS_SIGN;
+   }
ret = 0;
 
 error_free_tfm:
-- 
2.11.0



[PATCH v7 08/11] crypto: ecc - make ecc into separate module

2019-03-01 Thread Vitaly Chikunov
ecc.c have algorithms that could be used togeter by ecdh and ecrdsa.
Make it separate module. Add CRYPTO_ECC into Kconfig. EXPORT_SYMBOL and
document to what seems appropriate. Move structs ecc_point and ecc_curve
from ecc_curve_defs.h into ecc.h.

No code changes.

Signed-off-by: Vitaly Chikunov 
---
 crypto/Kconfig  |  4 ++
 crypto/Makefile |  2 +-
 crypto/ecc.c| 25 +
 crypto/ecc.h| 99 +
 crypto/ecc_curve_defs.h | 15 
 5 files changed, 122 insertions(+), 23 deletions(-)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 370cbdca87a7..cf0bceee0ea5 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -248,8 +248,12 @@ config CRYPTO_DH
help
  Generic implementation of the Diffie-Hellman algorithm.
 
+config CRYPTO_ECC
+   tristate
+
 config CRYPTO_ECDH
tristate "ECDH algorithm"
+   select CRYPTO_ECC
select CRYPTO_KPP
select CRYPTO_RNG_DEFAULT
help
diff --git a/crypto/Makefile b/crypto/Makefile
index 799ed5e94606..b660f078651a 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -147,8 +147,8 @@ obj-$(CONFIG_CRYPTO_USER_API_RNG) += algif_rng.o
 obj-$(CONFIG_CRYPTO_USER_API_AEAD) += algif_aead.o
 obj-$(CONFIG_CRYPTO_ZSTD) += zstd.o
 obj-$(CONFIG_CRYPTO_OFB) += ofb.o
+obj-$(CONFIG_CRYPTO_ECC) += ecc.o
 
-ecdh_generic-y := ecc.o
 ecdh_generic-y += ecdh.o
 ecdh_generic-y += ecdh_helper.o
 obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
diff --git a/crypto/ecc.c b/crypto/ecc.c
index ed1237115066..5f36792d143d 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -24,6 +24,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -112,7 +113,7 @@ static void vli_clear(u64 *vli, unsigned int ndigits)
 }
 
 /* Returns true if vli == 0, false otherwise. */
-static bool vli_is_zero(const u64 *vli, unsigned int ndigits)
+bool vli_is_zero(const u64 *vli, unsigned int ndigits)
 {
int i;
 
@@ -123,6 +124,7 @@ static bool vli_is_zero(const u64 *vli, unsigned int 
ndigits)
 
return true;
 }
+EXPORT_SYMBOL(vli_is_zero);
 
 /* Returns nonzero if bit bit of vli is set. */
 static u64 vli_test_bit(const u64 *vli, unsigned int bit)
@@ -171,7 +173,7 @@ static void vli_set(u64 *dest, const u64 *src, unsigned int 
ndigits)
 }
 
 /* Returns sign of left - right. */
-static int vli_cmp(const u64 *left, const u64 *right, unsigned int ndigits)
+int vli_cmp(const u64 *left, const u64 *right, unsigned int ndigits)
 {
int i;
 
@@ -184,6 +186,7 @@ static int vli_cmp(const u64 *left, const u64 *right, 
unsigned int ndigits)
 
return 0;
 }
+EXPORT_SYMBOL(vli_cmp);
 
 /* Computes result = in << c, returning carry. Can modify in place
  * (if result == in). 0 < shift < 64.
@@ -240,7 +243,7 @@ static u64 vli_add(u64 *result, const u64 *left, const u64 
*right,
 }
 
 /* Computes result = left - right, returning borrow. Can modify in place. */
-static u64 vli_sub(u64 *result, const u64 *left, const u64 *right,
+u64 vli_sub(u64 *result, const u64 *left, const u64 *right,
   unsigned int ndigits)
 {
u64 borrow = 0;
@@ -258,6 +261,7 @@ static u64 vli_sub(u64 *result, const u64 *left, const u64 
*right,
 
return borrow;
 }
+EXPORT_SYMBOL(vli_sub);
 
 static uint128_t mul_64_64(u64 left, u64 right)
 {
@@ -557,7 +561,7 @@ static void vli_mod_square_fast(u64 *result, const u64 
*left,
  * See "From Euclid's GCD to Montgomery Multiplication to the Great Divide"
  * https://labs.oracle.com/techrep/2001/smli_tr-2001-95.pdf
  */
-static void vli_mod_inv(u64 *result, const u64 *input, const u64 *mod,
+void vli_mod_inv(u64 *result, const u64 *input, const u64 *mod,
unsigned int ndigits)
 {
u64 a[ECC_MAX_DIGITS], b[ECC_MAX_DIGITS];
@@ -630,6 +634,7 @@ static void vli_mod_inv(u64 *result, const u64 *input, 
const u64 *mod,
 
vli_set(result, u, ndigits);
 }
+EXPORT_SYMBOL(vli_mod_inv);
 
 /* -- Point operations -- */
 
@@ -948,6 +953,7 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int 
ndigits,
 
return __ecc_is_key_valid(curve, private_key, ndigits);
 }
+EXPORT_SYMBOL(ecc_is_key_valid);
 
 /*
  * ECC private keys are generated using the method of extra random bits,
@@ -1000,6 +1006,7 @@ int ecc_gen_privkey(unsigned int curve_id, unsigned int 
ndigits, u64 *privkey)
 
return 0;
 }
+EXPORT_SYMBOL(ecc_gen_privkey);
 
 int ecc_make_pub_key(unsigned int curve_id, unsigned int ndigits,
 const u64 *private_key, u64 *public_key)
@@ -1036,10 +1043,11 @@ int ecc_make_pub_key(unsigned int curve_id, unsigned 
int ndigits,
 out:
return ret;
 }
+EXPORT_SYMBOL(ecc_make_pub_key);
 
 /* SP800-56A section 5.6.2.3.4 partial verification: ephemeral keys only */
-static int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve,
-  

[PATCH v7 03/11] crypto: rsa - unimplement sign/verify for raw RSA backends

2019-03-01 Thread Vitaly Chikunov
In preparation for new akcipher verify call remove sign/verify callbacks
from RSA backends and make PKCS1 driver call encrypt/decrypt instead.

This also complies with the well-known idea that raw RSA should never be
used for sign/verify. It only should be used with proper padding scheme
such as PKCS1 driver provides.

Cc: Giovanni Cabiddu 
Cc: qat-li...@intel.com
Cc: Tom Lendacky 
Cc: Gary Hook 
Cc: Horia Geantă 
Cc: Aymen Sghaier 
Signed-off-by: Vitaly Chikunov 
---
 crypto/rsa-pkcs1pad.c |   4 +-
 crypto/rsa.c  | 109 --
 drivers/crypto/caam/caampkc.c |   2 -
 drivers/crypto/ccp/ccp-crypto-rsa.c   |   2 -
 drivers/crypto/qat/qat_common/qat_asym_algs.c |   2 -
 5 files changed, 2 insertions(+), 117 deletions(-)

diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
index 0a6680ca8cb6..94382fa2c6ac 100644
--- a/crypto/rsa-pkcs1pad.c
+++ b/crypto/rsa-pkcs1pad.c
@@ -429,7 +429,7 @@ static int pkcs1pad_sign(struct akcipher_request *req)
akcipher_request_set_crypt(_ctx->child_req, req_ctx->in_sg,
   req->dst, ctx->key_size - 1, req->dst_len);
 
-   err = crypto_akcipher_sign(_ctx->child_req);
+   err = crypto_akcipher_decrypt(_ctx->child_req);
if (err != -EINPROGRESS && err != -EBUSY)
return pkcs1pad_encrypt_sign_complete(req, err);
 
@@ -551,7 +551,7 @@ static int pkcs1pad_verify(struct akcipher_request *req)
   req_ctx->out_sg, req->src_len,
   ctx->key_size);
 
-   err = crypto_akcipher_verify(_ctx->child_req);
+   err = crypto_akcipher_encrypt(_ctx->child_req);
if (err != -EINPROGRESS && err != -EBUSY)
return pkcs1pad_verify_complete(req, err);
 
diff --git a/crypto/rsa.c b/crypto/rsa.c
index 4167980c243d..5d427c1100d6 100644
--- a/crypto/rsa.c
+++ b/crypto/rsa.c
@@ -50,34 +50,6 @@ static int _rsa_dec(const struct rsa_mpi_key *key, MPI m, 
MPI c)
return mpi_powm(m, c, key->d, key->n);
 }
 
-/*
- * RSASP1 function [RFC3447 sec 5.2.1]
- * s = m^d mod n
- */
-static int _rsa_sign(const struct rsa_mpi_key *key, MPI s, MPI m)
-{
-   /* (1) Validate 0 <= m < n */
-   if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0)
-   return -EINVAL;
-
-   /* (2) s = m^d mod n */
-   return mpi_powm(s, m, key->d, key->n);
-}
-
-/*
- * RSAVP1 function [RFC3447 sec 5.2.2]
- * m = s^e mod n;
- */
-static int _rsa_verify(const struct rsa_mpi_key *key, MPI m, MPI s)
-{
-   /* (1) Validate 0 <= s < n */
-   if (mpi_cmp_ui(s, 0) < 0 || mpi_cmp(s, key->n) >= 0)
-   return -EINVAL;
-
-   /* (2) m = s^e mod n */
-   return mpi_powm(m, s, key->e, key->n);
-}
-
 static inline struct rsa_mpi_key *rsa_get_key(struct crypto_akcipher *tfm)
 {
return akcipher_tfm_ctx(tfm);
@@ -160,85 +132,6 @@ static int rsa_dec(struct akcipher_request *req)
return ret;
 }
 
-static int rsa_sign(struct akcipher_request *req)
-{
-   struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
-   const struct rsa_mpi_key *pkey = rsa_get_key(tfm);
-   MPI m, s = mpi_alloc(0);
-   int ret = 0;
-   int sign;
-
-   if (!s)
-   return -ENOMEM;
-
-   if (unlikely(!pkey->n || !pkey->d)) {
-   ret = -EINVAL;
-   goto err_free_s;
-   }
-
-   ret = -ENOMEM;
-   m = mpi_read_raw_from_sgl(req->src, req->src_len);
-   if (!m)
-   goto err_free_s;
-
-   ret = _rsa_sign(pkey, s, m);
-   if (ret)
-   goto err_free_m;
-
-   ret = mpi_write_to_sgl(s, req->dst, req->dst_len, );
-   if (ret)
-   goto err_free_m;
-
-   if (sign < 0)
-   ret = -EBADMSG;
-
-err_free_m:
-   mpi_free(m);
-err_free_s:
-   mpi_free(s);
-   return ret;
-}
-
-static int rsa_verify(struct akcipher_request *req)
-{
-   struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
-   const struct rsa_mpi_key *pkey = rsa_get_key(tfm);
-   MPI s, m = mpi_alloc(0);
-   int ret = 0;
-   int sign;
-
-   if (!m)
-   return -ENOMEM;
-
-   if (unlikely(!pkey->n || !pkey->e)) {
-   ret = -EINVAL;
-   goto err_free_m;
-   }
-
-   s = mpi_read_raw_from_sgl(req->src, req->src_len);
-   if (!s) {
-   ret = -ENOMEM;
-   goto err_free_m;
-   }
-
-   ret = _rsa_verify(pkey, m, s);
-   if (ret)
-   goto err_free_s;
-
-   ret = mpi_write_to_sgl(m, req->dst, req->dst_len, );
-   if (ret)
-   goto err_free_s;
-
-   if (sign < 0)
-   ret = -EBADMSG;
-
-err_free_s:
-   mpi_free(s);
-err_free_m:
-   mpi_free(m)

[PATCH v7 11/11] integrity: support EC-RDSA signatures for asymmetric_verify

2019-03-01 Thread Vitaly Chikunov
Allow to use EC-RDSA signatures for IMA by determining signature type by
the hash algorithm name. This works good for EC-RDSA since Streebog and
EC-RDSA should always be used together.

Cc: Mimi Zohar 
Cc: Dmitry Kasatkin 
Cc: linux-integr...@vger.kernel.org
Signed-off-by: Vitaly Chikunov 
---
 security/integrity/digsig_asymmetric.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/security/integrity/digsig_asymmetric.c 
b/security/integrity/digsig_asymmetric.c
index d775e03fbbcc..99080871eb9f 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -104,9 +104,16 @@ int asymmetric_verify(struct key *keyring, const char *sig,
 
memset(, 0, sizeof(pks));
 
-   pks.pkey_algo = "rsa";
pks.hash_algo = hash_algo_name[hdr->hash_algo];
-   pks.encoding = "pkcs1";
+   if (hdr->hash_algo == HASH_ALGO_STREEBOG_256 ||
+   hdr->hash_algo == HASH_ALGO_STREEBOG_512) {
+   /* EC-RDSA and Streebog should go together. */
+   pks.pkey_algo = "ecrdsa";
+   pks.encoding = "raw";
+   } else {
+   pks.pkey_algo = "rsa";
+   pks.encoding = "pkcs1";
+   }
pks.digest = (u8 *)data;
pks.digest_size = datalen;
pks.s = hdr->sig;
-- 
2.11.0



[PATCH v7 04/11] crypto: akcipher - new verify API for public key algorithms

2019-03-01 Thread Vitaly Chikunov
Previous akcipher .verify() just `decrypts' (using RSA encrypt which is
using public key) signature to uncover message hash, which was then
compared in upper level public_key_verify_signature() with the expected
hash value, which itself was never passed into verify().

This approach was incompatible with EC-DSA family of algorithms,
because, to verify a signature EC-DSA algorithm also needs a hash value
as input; then it's used (together with a signature divided into halves
`r||s') to produce a witness value, which is then compared with `r' to
determine if the signature is correct. Thus, for EC-DSA, nor
requirements of .verify() itself, nor its output expectations in
public_key_verify_signature() wasn't sufficient.

Make improved .verify() call which gets hash value as input and produce
complete signature check without any output besides status.

Now for the top level verification only crypto_akcipher_verify() needs
to be called.

Make sure that `digest' is in kmalloc'd memory (in place of `output`) in
{public,tpm}_key_verify_signature() as insisted by Herbert Xu, and will
be changed in the following commit.

Cc: David Howells 
Cc: keyri...@vger.kernel.org
Signed-off-by: Vitaly Chikunov 
---
 crypto/asymmetric_keys/asym_tpm.c   | 34 -
 crypto/asymmetric_keys/public_key.c | 34 -
 crypto/rsa-pkcs1pad.c   | 29 +
 crypto/testmgr.c| 50 ++---
 include/crypto/akcipher.h   | 40 ++---
 5 files changed, 95 insertions(+), 92 deletions(-)

diff --git a/crypto/asymmetric_keys/asym_tpm.c 
b/crypto/asymmetric_keys/asym_tpm.c
index 5d4c270463f6..4e5b6fb57a94 100644
--- a/crypto/asymmetric_keys/asym_tpm.c
+++ b/crypto/asymmetric_keys/asym_tpm.c
@@ -744,12 +744,11 @@ static int tpm_key_verify_signature(const struct key *key,
struct crypto_wait cwait;
struct crypto_akcipher *tfm;
struct akcipher_request *req;
-   struct scatterlist sig_sg, digest_sg;
+   struct scatterlist src_sg[2];
char alg_name[CRYPTO_MAX_ALG_NAME];
uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
uint32_t der_pub_key_len;
-   void *output;
-   unsigned int outlen;
+   void *digest;
int ret;
 
pr_devel("==>%s()\n", __func__);
@@ -782,35 +781,22 @@ static int tpm_key_verify_signature(const struct key *key,
goto error_free_tfm;
 
ret = -ENOMEM;
-   outlen = crypto_akcipher_maxsize(tfm);
-   output = kmalloc(outlen, GFP_KERNEL);
-   if (!output)
+   digest = kmemdup(sig->digest, sig->digest_size, GFP_KERNEL);
+   if (!digest)
goto error_free_req;
 
-   sg_init_one(_sg, sig->s, sig->s_size);
-   sg_init_one(_sg, output, outlen);
-   akcipher_request_set_crypt(req, _sg, _sg, sig->s_size,
-  outlen);
+   sg_init_table(src_sg, 2);
+   sg_set_buf(_sg[0], sig->s, sig->s_size);
+   sg_set_buf(_sg[1], digest, sig->digest_size);
+   akcipher_request_set_crypt(req, src_sg, NULL, sig->s_size,
+  sig->digest_size);
crypto_init_wait();
akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
  CRYPTO_TFM_REQ_MAY_SLEEP,
  crypto_req_done, );
-
-   /* Perform the verification calculation.  This doesn't actually do the
-* verification, but rather calculates the hash expected by the
-* signature and returns that to us.
-*/
ret = crypto_wait_req(crypto_akcipher_verify(req), );
-   if (ret)
-   goto out_free_output;
-
-   /* Do the actual verification step. */
-   if (req->dst_len != sig->digest_size ||
-   memcmp(sig->digest, output, sig->digest_size) != 0)
-   ret = -EKEYREJECTED;
 
-out_free_output:
-   kfree(output);
+   kfree(digest);
 error_free_req:
akcipher_request_free(req);
 error_free_tfm:
diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index c2e4e73fcf06..338f2b5352b1 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -233,10 +233,9 @@ int public_key_verify_signature(const struct public_key 
*pkey,
struct crypto_wait cwait;
struct crypto_akcipher *tfm;
struct akcipher_request *req;
-   struct scatterlist sig_sg, digest_sg;
+   struct scatterlist src_sg[2];
char alg_name[CRYPTO_MAX_ALG_NAME];
-   void *output;
-   unsigned int outlen;
+   void *digest;
int ret;
 
pr_devel("==>%s()\n", __func__);
@@ -270,35 +269,22 @@ int public_key_verify_signature(const struct public_key 
*pkey,
goto error_free_req;
 
ret = -ENOMEM;
-   outlen = crypt

[PATCH v7 10/11] crypto: ecrdsa - add EC-RDSA test vectors to testmgr

2019-03-01 Thread Vitaly Chikunov
Add testmgr test vectors for EC-RDSA algorithm for every of five
supported parameters (curves). Because there are no officially published
test vectors for the curves, the vectors are generated by gost-engine.

Signed-off-by: Vitaly Chikunov 
---
 crypto/testmgr.c |   6 +++
 crypto/testmgr.h | 154 +++
 2 files changed, 160 insertions(+)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 50396b3a2a47..d675755ef13f 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -3384,6 +3384,12 @@ static const struct alg_test_desc alg_test_descs[] = {
.kpp = __VECS(ecdh_tv_template)
}
}, {
+   .alg = "ecrdsa",
+   .test = alg_test_akcipher,
+   .suite = {
+   .akcipher = __VECS(ecrdsa_tv_template)
+   }
+   }, {
.alg = "gcm(aes)",
.test = alg_test_aead,
.fips_allowed = 1,
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 75d8f8c3e203..120531b0a86d 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -556,6 +556,160 @@ static const struct akcipher_testvec rsa_tv_template[] = {
 };
 
 /*
+ * EC-RDSA test vectors are generated by gost-engine.
+ */
+static const struct akcipher_testvec ecrdsa_tv_template[] = {
+   {
+   .key =
+   "\x04\x40\xd5\xa7\x77\xf9\x26\x2f\x8c\xbd\xcc\xe3\x1f\x01\x94\x05"
+   "\x3d\x2f\xec\xb5\x00\x34\xf5\x51\x6d\x3b\x90\x4b\x23\x28\x6f\x1d"
+   "\xc8\x36\x61\x60\x36\xec\xbb\xb4\x0b\x95\x4e\x54\x4f\x15\x21\x05"
+   "\xd8\x52\x66\x44\x31\x7e\x5d\xc5\xd1\x26\x00\x5f\x60\xd8\xf0\xc7"
+   "\x27\xfc",
+   .key_len = 66,
+   .params = /* OID_gostCPSignA */
+   "\x30\x13\x06\x07\x2a\x85\x03\x02\x02\x23\x01\x06\x08\x2a\x85\x03"
+   "\x07\x01\x01\x02\x02",
+   .param_len = 21,
+   .c =
+   "\x41\x32\x09\x73\xa4\xc1\x38\xd6\x63\x7d\x8b\xf7\x50\x3f\xda\x9f"
+   "\x68\x48\xc1\x50\xe3\x42\x3a\x9b\x2b\x28\x12\x2a\xa7\xc2\x75\x31"
+   "\x65\x77\x8c\x3c\x9e\x0d\x56\xb2\xf9\xdc\x04\x33\x3e\xb0\x9e\xf9"
+   "\x74\x4e\x59\xb3\x83\xf2\x91\x27\xda\x5e\xc7\x33\xc0\xc1\x8f\x41",
+   .c_size = 64,
+   .algo = OID_gost2012PKey256,
+   .m =
+   "\x75\x1b\x9b\x40\x25\xb9\x96\xd2\x9b\x00\x41\xb3\x58\xbf\x23\x14"
+   "\x79\xd2\x76\x64\xa3\xbd\x66\x10\x79\x05\x5a\x06\x42\xec\xb9\xc9",
+   .m_size = 32,
+   .public_key_vec = true,
+   .siggen_sigver_test = true,
+   },
+   {
+   .key =
+   "\x04\x40\x66\x6f\xd6\xb7\x06\xd0\xf5\xa5\x6f\x69\x5c\xa5\x13\x45"
+   "\x14\xdd\xcb\x12\x9c\x1b\xf5\x28\x64\x7a\x49\x48\x29\x14\x66\x42"
+   "\xb8\x1b\x5c\xf9\x56\x6d\x08\x3b\xce\xbb\x62\x2f\xc2\x3c\xc5\x49"
+   "\x93\x27\x70\x20\xcc\x79\xeb\xdc\x76\x8e\x48\x6e\x04\x96\xc3\x29"
+   "\xa0\x73",
+   .key_len = 66,
+   .params = /* OID_gostCPSignB */
+   "\x30\x13\x06\x07\x2a\x85\x03\x02\x02\x23\x02\x06\x08\x2a\x85\x03"
+   "\x07\x01\x01\x02\x02",
+   .param_len = 21,
+   .c =
+   "\x45\x6d\x4a\x03\x1d\x5c\x0b\x17\x79\xe7\x19\xdb\xbf\x81\x9f\x82"
+   "\xae\x06\xda\xf5\x47\x00\x05\x80\xc3\x16\x06\x9a\x8e\x7c\xb2\x8e"
+   "\x7f\x74\xaa\xec\x6b\x7b\x7f\x8b\xc6\x0b\x10\x42\x4e\x91\x2c\xdf"
+   "\x7b\x8b\x15\xf4\x9e\x59\x0f\xc7\xa4\x68\x2e\xce\x89\xdf\x84\xe9",
+   .c_size = 64,
+   .algo = OID_gost2012PKey256,
+   .m =
+   "\xd0\x54\x00\x27\x6a\xeb\xce\x6c\xf5\xf6\xfb\x57\x18\x18\x21\x13"
+   "\x11\x23\x4a\x70\x43\x52\x7a\x68\x11\x65\x45\x37\xbb\x25\xb7\x40",
+   .m_size = 32,
+   .public_key_vec = true,
+   .siggen_sigver_test = true,
+   },
+   {
+   .key =
+   "\x04\x40\x05\x91\xa9\x7d\xcb\x87\xdc\x98\xa1\xbf\xff\xdd\x20\x61"
+   "\xaa\x58\x3b\x2d\x8e\x9c\x41\x9d\x4f\xc6\x23\x17\xf9\xca\x60\x65"
+   "\xbc\x97\x97\xf6\x6b\x24\xe8\xac\xb1\xa7\x61\x29\x3c\x71\xdc\xad"
+   "\xcb\x20\xbe\x96\xe8\xf4\x44\x2e\x49\xd5\x2c\xb9\xc9\x3b\x9c\xaa"
+   "\xba\x15",
+   .key_len = 66,
+   .params = /* OID_gostCPSignC */
+   "\x30\x13\x06\x07\x2a\x85\x03\x02\x02\x23\x03\x06\x08\x2a\x85\x03"
+   "\x07\x01\x01\x02\x02",
+   .param_len = 21,
+   .c =
+   "\x3b\x2e\x2e\x74\x74\x47\xda\xea\x93\x90\x6a\xe2\xf5\xf5\xe6\x46"
+   "\x11\xfc\xab\xdc\x52\xbc\x58\xdb\x45\x44\x12\x4a\xf7\xd0\xab\xc9"
+   "\x73\xba\x64\xab\x0d\xac\x4e\x72\x10\xa8\x04\xf6\x1e\xe0\x48\x6a"
+   "\xcd\xe8\xe3\x78\x73\x77\x82\x24\x8d\xf1\xd3\xeb\x4c\x25\x7e\xc0",
+   .c_size = 64,
+   .algo = OID_gost2012P

[PATCH v7 05/11] KEYS: do not kmemdup digest in {public,tpm}_key_verify_signature

2019-03-01 Thread Vitaly Chikunov
Treat (struct public_key_signature)'s digest same as its signature (s).
Since digest should be already in the kmalloc'd memory do not kmemdup
digest value before calling {public,tpm}_key_verify_signature.

Patch is split from the previous as suggested by Herbert Xu.

Suggested-by: David Howells 
Cc: David Howells 
Cc: keyri...@vger.kernel.org
Signed-off-by: Vitaly Chikunov 
---
 crypto/asymmetric_keys/asym_tpm.c   | 10 +-
 crypto/asymmetric_keys/public_key.c |  9 +
 2 files changed, 2 insertions(+), 17 deletions(-)

diff --git a/crypto/asymmetric_keys/asym_tpm.c 
b/crypto/asymmetric_keys/asym_tpm.c
index 4e5b6fb57a94..402fc34ca044 100644
--- a/crypto/asymmetric_keys/asym_tpm.c
+++ b/crypto/asymmetric_keys/asym_tpm.c
@@ -748,7 +748,6 @@ static int tpm_key_verify_signature(const struct key *key,
char alg_name[CRYPTO_MAX_ALG_NAME];
uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
uint32_t der_pub_key_len;
-   void *digest;
int ret;
 
pr_devel("==>%s()\n", __func__);
@@ -780,14 +779,9 @@ static int tpm_key_verify_signature(const struct key *key,
if (!req)
goto error_free_tfm;
 
-   ret = -ENOMEM;
-   digest = kmemdup(sig->digest, sig->digest_size, GFP_KERNEL);
-   if (!digest)
-   goto error_free_req;
-
sg_init_table(src_sg, 2);
sg_set_buf(_sg[0], sig->s, sig->s_size);
-   sg_set_buf(_sg[1], digest, sig->digest_size);
+   sg_set_buf(_sg[1], sig->digest, sig->digest_size);
akcipher_request_set_crypt(req, src_sg, NULL, sig->s_size,
   sig->digest_size);
crypto_init_wait();
@@ -796,8 +790,6 @@ static int tpm_key_verify_signature(const struct key *key,
  crypto_req_done, );
ret = crypto_wait_req(crypto_akcipher_verify(req), );
 
-   kfree(digest);
-error_free_req:
akcipher_request_free(req);
 error_free_tfm:
crypto_free_akcipher(tfm);
diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index 338f2b5352b1..4dcfe281b898 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -235,7 +235,6 @@ int public_key_verify_signature(const struct public_key 
*pkey,
struct akcipher_request *req;
struct scatterlist src_sg[2];
char alg_name[CRYPTO_MAX_ALG_NAME];
-   void *digest;
int ret;
 
pr_devel("==>%s()\n", __func__);
@@ -268,14 +267,9 @@ int public_key_verify_signature(const struct public_key 
*pkey,
if (ret)
goto error_free_req;
 
-   ret = -ENOMEM;
-   digest = kmemdup(sig->digest, sig->digest_size, GFP_KERNEL);
-   if (!digest)
-   goto error_free_req;
-
sg_init_table(src_sg, 2);
sg_set_buf(_sg[0], sig->s, sig->s_size);
-   sg_set_buf(_sg[1], digest, sig->digest_size);
+   sg_set_buf(_sg[1], sig->digest, sig->digest_size);
akcipher_request_set_crypt(req, src_sg, NULL, sig->s_size,
   sig->digest_size);
crypto_init_wait();
@@ -284,7 +278,6 @@ int public_key_verify_signature(const struct public_key 
*pkey,
  crypto_req_done, );
ret = crypto_wait_req(crypto_akcipher_verify(req), );
 
-   kfree(digest);
 error_free_req:
akcipher_request_free(req);
 error_free_tfm:
-- 
2.11.0



[PATCH v7 06/11] X.509: parse public key parameters from x509 for akcipher

2019-03-01 Thread Vitaly Chikunov
Some public key algorithms (like EC-DSA) keep in parameters field
important data such as digest and curve OIDs (possibly more for
different EC-DSA variants). Thus, just setting a public key (as
for RSA) is not enough.

Append parameters into the key stream for akcipher_set_{pub,priv}_key.
Appended data is: (u32) algo OID, (u32) parameters length, parameters
data.

This does not affect current akcipher API nor RSA ciphers (they could
ignore it). Idea of appending parameters to the key stream is by Herbert
Xu.

Cc: David Howells 
Cc: keyri...@vger.kernel.org
Signed-off-by: Vitaly Chikunov 
---
 crypto/asymmetric_keys/asym_tpm.c | 43 --
 crypto/asymmetric_keys/public_key.c   | 72 ---
 crypto/asymmetric_keys/x509.asn1  |  2 +-
 crypto/asymmetric_keys/x509_cert_parser.c | 31 +
 crypto/testmgr.c  | 24 +--
 crypto/testmgr.h  |  5 +++
 include/crypto/akcipher.h | 18 
 include/crypto/public_key.h   |  4 ++
 8 files changed, 168 insertions(+), 31 deletions(-)

diff --git a/crypto/asymmetric_keys/asym_tpm.c 
b/crypto/asymmetric_keys/asym_tpm.c
index 402fc34ca044..d95d7ec50e5a 100644
--- a/crypto/asymmetric_keys/asym_tpm.c
+++ b/crypto/asymmetric_keys/asym_tpm.c
@@ -395,6 +395,12 @@ static int determine_akcipher(const char *encoding, const 
char *hash_algo,
return -ENOPKG;
 }
 
+static u8 *tpm_pack_u32(u8 *dst, u32 val)
+{
+   memcpy(dst, , sizeof(val));
+   return dst + sizeof(val);
+}
+
 /*
  * Query information about a key.
  */
@@ -407,6 +413,7 @@ static int tpm_key_query(const struct kernel_pkey_params 
*params,
struct crypto_akcipher *tfm;
uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
uint32_t der_pub_key_len;
+   u8 *pkey, *ptr;
int len;
 
/* TPM only works on private keys, public keys still done in software */
@@ -421,7 +428,16 @@ static int tpm_key_query(const struct kernel_pkey_params 
*params,
der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
 der_pub_key);
 
-   ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
+   pkey = kmalloc(der_pub_key_len + sizeof(u32) * 2, GFP_KERNEL);
+   if (!pkey)
+   goto error_free_tfm;
+   memcpy(pkey, der_pub_key, der_pub_key_len);
+   ptr = pkey + der_pub_key_len;
+   /* Set dummy parameters to satisfy set_pub_key ABI. */
+   ptr = tpm_pack_u32(ptr, 0); /* algo */
+   ptr = tpm_pack_u32(ptr, 0); /* parameter length */
+
+   ret = crypto_akcipher_set_pub_key(tfm, pkey, der_pub_key_len);
if (ret < 0)
goto error_free_tfm;
 
@@ -440,6 +456,7 @@ static int tpm_key_query(const struct kernel_pkey_params 
*params,
 
ret = 0;
 error_free_tfm:
+   kfree(pkey);
crypto_free_akcipher(tfm);
pr_devel("<==%s() = %d\n", __func__, ret);
return ret;
@@ -460,6 +477,7 @@ static int tpm_key_encrypt(struct tpm_key *tk,
struct scatterlist in_sg, out_sg;
uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
uint32_t der_pub_key_len;
+   u8 *pkey, *ptr;
int ret;
 
pr_devel("==>%s()\n", __func__);
@@ -475,7 +493,15 @@ static int tpm_key_encrypt(struct tpm_key *tk,
der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
 der_pub_key);
 
-   ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
+   pkey = kmalloc(der_pub_key_len + sizeof(u32) * 2, GFP_KERNEL);
+   if (!pkey)
+   goto error_free_tfm;
+   memcpy(pkey, der_pub_key, der_pub_key_len);
+   ptr = pkey + der_pub_key_len;
+   ptr = tpm_pack_u32(ptr, 0); /* algo */
+   ptr = tpm_pack_u32(ptr, 0); /* parameter length */
+
+   ret = crypto_akcipher_set_pub_key(tfm, pkey, der_pub_key_len);
if (ret < 0)
goto error_free_tfm;
 
@@ -500,6 +526,7 @@ static int tpm_key_encrypt(struct tpm_key *tk,
 
akcipher_request_free(req);
 error_free_tfm:
+   kfree(pkey);
crypto_free_akcipher(tfm);
pr_devel("<==%s() = %d\n", __func__, ret);
return ret;
@@ -748,6 +775,7 @@ static int tpm_key_verify_signature(const struct key *key,
char alg_name[CRYPTO_MAX_ALG_NAME];
uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
uint32_t der_pub_key_len;
+   u8 *pkey, *ptr;
int ret;
 
pr_devel("==>%s()\n", __func__);
@@ -770,7 +798,15 @@ static int tpm_key_verify_signature(const struct key *key,
der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
 der_pub_key);
 
-   ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
+   pkey = kmalloc(der_pub_key_len + sizeof(u32) * 2, GFP_KERNEL);

[PATCH v7 09/11] crypto: ecrdsa - add EC-RDSA (GOST 34.10) algorithm

2019-03-01 Thread Vitaly Chikunov
Add Elliptic Curve Russian Digital Signature Algorithm (GOST R
34.10-2012, RFC 7091, ISO/IEC 14888-3) is one of the Russian (and since
2018 the CIS countries) cryptographic standard algorithms (called GOST
algorithms). Only signature verification is supported, with intent to be
used in the IMA.

Summary of the changes:

* crypto/Kconfig:
  - EC-RDSA is added into Public-key cryptography section.

* crypto/Makefile:
  - ecrdsa objects are added.

* crypto/asymmetric_keys/x509_cert_parser.c:
  - Recognize EC-RDSA and Streebog OIDs.

* include/linux/oid_registry.h:
  - EC-RDSA OIDs are added to the enum. Also, a two currently not
implemented curve OIDs are added for possible extension later (to
not change numbering and grouping).

* crypto/ecc.c:
  - Kenneth MacKay copyright date is updated to 2014, because
vli_mmod_slow, ecc_point_add, ecc_point_mult_shamir are based on his
code from micro-ecc.
  - Functions needed for ecrdsa are EXPORT_SYMBOL'ed.
  - New functions:
vli_is_negative - helper to determine sign of vli;
vli_from_be64 - unpack big-endian array into vli (used for
  a signature);
vli_from_le64 - unpack little-endian array into vli (used for
  a public key);
vli_uadd, vli_usub - add/sub u64 value to/from vli (used for
  increment/decrement);
mul_64_64 - optimized to use __int128 where appropriate, this speeds
  up point multiplication (and as a consequence signature
  verification) by the factor of 1.5-2;
vli_umult - multiply vli by a small value (speeds up point
  multiplication by another factor of 1.5-2, depending on vli sizes);
vli_mmod_special - module reduction for some form of Pseudo-Mersenne
  primes (used for the curves A);
vli_mmod_special2 - module reduction for another form of
  Pseudo-Mersenne primes (used for the curves B);
vli_mmod_barrett - module reduction using pre-computed value (used
  for the curve C);
vli_mmod_slow - more general module reduction which is much slower
 (used when the modulus is subgroup order);
vli_mod_mult_slow - modular multiplication;
ecc_point_add - add two points;
ecc_point_mult_shamir - add two points multiplied by scalars in one
  combined multiplication (this gives speed up by another factor 2 in
  compare to two separate multiplications).
ecc_is_pubkey_valid_partial - additional samity check is added.
  - Updated vli_mmod_fast with non-strict heuristic to call optimal
  module reduction function depending on the prime value;
  - All computations for the previously defined (two NIST) curves should
not unaffected.

* crypto/ecc.h:
  - Newly exported functions are documented.

* crypto/ecrdsa_defs.h
  - Five curves are defined.

* crypto/ecrdsa.c:
  - Signature verification is implemented.

* crypto/ecrdsa_params.asn1, crypto/ecrdsa_pub_key.asn1:
  - Templates for BER decoder for EC-RDSA parameters and public key.

Cc: linux-integr...@vger.kernel.org
Signed-off-by: Vitaly Chikunov 
---
 crypto/Kconfig|  11 +
 crypto/Makefile   |   8 +
 crypto/asymmetric_keys/x509_cert_parser.c |  26 +-
 crypto/ecc.c  | 392 +-
 crypto/ecc.h  |  54 +++-
 crypto/ecrdsa.c   | 299 +++
 crypto/ecrdsa_defs.h  | 225 +
 crypto/ecrdsa_params.asn1 |   4 +
 crypto/ecrdsa_pub_key.asn1|   1 +
 include/linux/oid_registry.h  |  18 ++
 10 files changed, 1025 insertions(+), 13 deletions(-)
 create mode 100644 crypto/ecrdsa.c
 create mode 100644 crypto/ecrdsa_defs.h
 create mode 100644 crypto/ecrdsa_params.asn1
 create mode 100644 crypto/ecrdsa_pub_key.asn1

diff --git a/crypto/Kconfig b/crypto/Kconfig
index cf0bceee0ea5..c7e7e3ac38ed 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -259,6 +259,17 @@ config CRYPTO_ECDH
help
  Generic implementation of the ECDH algorithm
 
+config CRYPTO_ECRDSA
+   tristate "EC-RDSA (GOST 34.10) algorithm"
+   select CRYPTO_ECC
+   select CRYPTO_AKCIPHER
+   select CRYPTO_STREEBOG
+   help
+ Elliptic Curve Russian Digital Signature Algorithm (GOST R 34.10-2012,
+ RFC 7091, ISO/IEC 14888-3:2018) is one of the Russian cryptographic
+ standard algorithms (called GOST algorithms). Only signature 
verification
+ is supported.
+
 comment "Authenticated Encryption with Associated Data"
 
 config CRYPTO_CCM
diff --git a/crypto/Makefile b/crypto/Makefile
index b660f078651a..89e5e55bf391 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -153,6 +153,14 @@ ecdh_generic-y += ecdh.o
 ecdh_generic-y += ecdh_helper.o
 obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
 
+$(obj)/ecrdsa_params.asn1.o: $(obj)/ecrdsa_params.asn1.c 
$(obj)/ecrdsa_params.asn1.h
+$(obj)/ecrdsa_pub_key.asn1.o: $(obj)/ecrdsa_p

[PATCH v7 00/11] crypto: add EC-RDSA (GOST 34.10) algorithm

2019-03-01 Thread Vitaly Chikunov
This patchset changes akcipher API to support ECDSA style signature
verification, augments x509 parser to make it work with EC-RDSA certificates,
and, finally, implements EC-RDSA (GOST 34.10) signature verification and its
integration with IMA.

This patchset should be applied over cryptodev commit 0918f18c7179e8cdf718d0.

Changes since (v5-v6):
- set_params API is removed in favor of appending parameters into a key stream,
  as requested by Herbert Xu.
- verify op signature de-kmemdup'ed (as requested by David Howells) in separate
  patch (as requested by Herbert Xu).
- Add forgotten ASN.1 parser files to EC-RDSA patch.
- Tested on x86_64.

Changes since v5:
- Comparison of hash algo by enum id instead of text name, as suggested by
  Thiago Jung Bauermann and Mimi Zohar.

Changes since RFC (v1-v4):
- akcipher set_max_size, encrypt, decrypt, sign, verify callbacks may be
  undefined by the drivers, so their crypto_akcipher_* frontends check for
  their presence before passing the call.
- supported_ops flags are set for keyctl, based on the presence of implemented
  akcipher callbacks.
- Transition to verify2 API is abandoned because raw RSA does not need
  sign/verify ops at all, and we can switch to the new verify in one step.
  For this RSA backends have sign/verify ops removed as they should only
  be used (and actually used only) via PKCS1 driver.
- Verify callback requires digest as the input parameter in src SGL, as
  suggested by Herbert Xu, (instead of a separate parameter, as it was in
  verify2).
- For verify op signature is moved into kmalloc'd memory as suggested by
  Herbert Xu.
- set_params API should be called before set_{pub,priv}_key, thus set_*_key
  knows everything it needs to set they key properly. Also, set_params made
  optional for back compatibility with RSA drivers.
- Public-key cryptography section is created in Kconfig.
- ecc.c is made into separate module object, to be used together by ECDH and
  EC-RDSA.
- EC-RDSA parameters and public key are parsed using asn1_ber_decoder as
  suggested by Stephan Mueller and David Howells.
- Test vectors are added and tests are passing.
- Curves/parameters definitions are split from ecrdsa.c into ecrdsa_defs.h.
- Integration with IMA in asymmetric_verify(). Userspace ima-evm-utils already
  have a patch in the queue to support this. Tested on x86_64.

Vitaly Chikunov (11):
  KEYS: report to keyctl only actually supported key ops
  crypto: akcipher - check the presence of callback before the call
  crypto: rsa - unimplement sign/verify for raw RSA backends
  crypto: akcipher - new verify API for public key algorithms
  KEYS: do not kmemdup digest in {public,tpm}_key_verify_signature
  X.509: parse public key parameters from x509 for akcipher
  crypto: Kconfig - create Public-key cryptography section
  crypto: ecc - make ecc into separate module
  crypto: ecrdsa - add EC-RDSA (GOST 34.10) algorithm
  crypto: ecrdsa - add EC-RDSA test vectors to testmgr
  integrity: support EC-RDSA signatures for asymmetric_verify

 crypto/Kconfig|  63 ++--
 crypto/Makefile   |  10 +-
 crypto/asymmetric_keys/asym_tpm.c |  77 +++--
 crypto/asymmetric_keys/public_key.c   | 121 +---
 crypto/asymmetric_keys/x509.asn1  |   2 +-
 crypto/asymmetric_keys/x509_cert_parser.c |  57 +++-
 crypto/ecc.c  | 417 +-
 crypto/ecc.h  | 153 +-
 crypto/ecc_curve_defs.h   |  15 -
 crypto/ecrdsa.c   | 299 ++
 crypto/ecrdsa_defs.h  | 225 ++
 crypto/rsa-pkcs1pad.c |  33 +-
 crypto/rsa.c  | 109 ---
 crypto/testmgr.c  |  80 +++--
 crypto/testmgr.h  | 159 ++
 drivers/crypto/caam/caampkc.c |   2 -
 drivers/crypto/ccp/ccp-crypto-rsa.c   |   2 -
 drivers/crypto/qat/qat_common/qat_asym_algs.c |   2 -
 include/crypto/akcipher.h |  81 +++--
 include/crypto/public_key.h   |   4 +
 include/linux/oid_registry.h  |  18 ++
 security/integrity/digsig_asymmetric.c|  11 +-
 22 files changed, 1619 insertions(+), 321 deletions(-)
 create mode 100644 crypto/ecrdsa.c
 create mode 100644 crypto/ecrdsa_defs.h

-- 
2.11.0



Re: [RFC PATCH 1/4] X.509: Parse public key parameters from x509 for akcipher

2019-03-01 Thread Vitaly Chikunov
Herbert,

On Thu, Feb 28, 2019 at 06:37:15PM +0800, Herbert Xu wrote:
> On Thu, Feb 28, 2019 at 01:33:37PM +0300, Vitaly Chikunov wrote:
> >
> > To make the same for set_{pub,priv}_key it will require patching RSA
> > drivers anyway, since length of the key is stored just once as keylen
> > argument.
> 
> No we don't need to use the same format for different algorithms.
> RSA should stay as is.

I will rework as you suggest. But, just want to state that I disagree
with this approach of implicitly appending parameters data to the key
stream without any argument signifying it or length covering it. This
fitting into the old API is also somewhat disagree to your words that
we could change internal API:

On Thu, Feb 28, 2019 at 02:14:44PM +0800, Herbert Xu wrote:
> On Sun, Feb 24, 2019 at 09:48:40AM +0300, Vitaly Chikunov wrote:
> ...
> This compatibility does not matter.  We can always add translating
> layers into the crypto API to deal with this.  The only ABI that
> matters is the one to user-space.


Re: [PATCH v5 04/10] crypto: akcipher - new verify API for public key algorithms

2019-02-28 Thread Vitaly Chikunov
David,

On Thu, Feb 28, 2019 at 07:02:09PM +, David Howells wrote:
> | > It's not clear that sig->digest is guaranteed to be kmalloc memory.
> 
> Well, public_key_signature_free() will go bang if it's not kfree'able.

Well, I had similar argument, FYI:

| On Fri, Feb 01, 2019 at 10:09:23AM +0300, Vitaly Chikunov wrote:
| > On Fri, Feb 01, 2019 at 02:26:55PM +0800, Herbert Xu wrote:
| > >
| > > It's not clear that sig->digest is guaranteed to be kmalloc memory.
| > > In any case, it's best not to mix unrelated changes in a single
| > > patch.  So please keep the kmalloc on output and then copy
| > > sig->digest into it and put output into the SG list.
| >
| > It is not guaranteed that sig->s will be kmalloc memory either. (Except
| > we know it for sure like we know the same about sig->digest).
| >
| > You can see in public_key_signature_free() that both fields are kfree'd
| > together.
| >
| > So, I don't understand why we should treat sig->digest differently than
| > sig->s.
| >
| > I was just removing kmalloc'ed output as crypto_akcipher_verify() does
| > not need any output anymore. So, it's not some sort of mixing unrelated
| > changes, from my point of view.

But then I thought Herbert knows better and implemented his suggestion.

Now I have contradictory requests from two maintainers.




Re: [PATCH v5 04/10] crypto: akcipher - new verify API for public key algorithms

2019-02-28 Thread Vitaly Chikunov
David,

On Thu, Feb 28, 2019 at 06:18:54PM +, David Howells wrote:
> Vitaly Chikunov  wrote:
> 
> > +   digest = kmemdup(sig->digest, sig->digest_size, GFP_KERNEL);
> > +   if (!digest)
> 
> You shouldn't need to copy the digest.  It's being passed in to the crypto
> algorithm, not extracted out.

That's how Herbert suggested to do it. Quoting FYI:

| On Fri, Feb 01, 2019 at 02:26:55PM +0800, Herbert Xu wrote:
| > On Fri, Jan 25, 2019 at 09:01:16PM +0300, Vitaly Chikunov wrote:
| > >
| > > @@ -781,36 +780,17 @@ static int tpm_key_verify_signature(const struct 
key *key,
| > > if (!req)
| > > goto error_free_tfm;
| > >
| > > -   ret = -ENOMEM;
| > > -   outlen = crypto_akcipher_maxsize(tfm);
| > > -   output = kmalloc(outlen, GFP_KERNEL);
| > > -   if (!output)
| > > -   goto error_free_req;
| > > -
| > > -   sg_init_one(_sg, sig->s, sig->s_size);
| > > -   sg_init_one(_sg, output, outlen);
| > > -   akcipher_request_set_crypt(req, _sg, _sg, sig->s_size,
| > > -  outlen);
| > > +   sg_init_table(_sg, 2);
| > > +   sg_set_buf(_sg[0], sig->s, sig->s_size);
| > > +   sg_set_buf(_sg[1], sig->digest, sig->digest_size);
| > > +   akcipher_request_set_crypt(req, _sg, NULL, sig->s_size,
| > > +  sig->digest_size);
| >
| > It's not clear that sig->digest is guaranteed to be kmalloc memory.
| > In any case, it's best not to mix unrelated changes in a single
| > patch.  So please keep the kmalloc on output and then copy
| > sig->digest into it and put output into the SG list.


> > +   if (memcmp(c, outbuf_enc, c_size)) {
> 
> Please use == 0 and != 0 with memcmp() and strcmp().  Their return values are
> kind of inverted in sense if you treat them as boolean.

OK.

Thanks!



Re: [RFC PATCH 1/4] X.509: Parse public key parameters from x509 for akcipher

2019-02-28 Thread Vitaly Chikunov
On Thu, Feb 28, 2019 at 05:01:25PM +0800, Herbert Xu wrote:
> On Thu, Feb 28, 2019 at 11:28:01AM +0300, Vitaly Chikunov wrote:
> > On Thu, Feb 28, 2019 at 03:51:41PM +0800, Herbert Xu wrote:
> > > On Thu, Feb 28, 2019 at 10:04:49AM +0300, Vitaly Chikunov wrote:
> > > > 
> > > > It seems that you insist on set_params to be removed and both key and
> > > > params to be passed into set_{pub,priv}_key. This means reworking all
> > > > existing RSA drivers and callers, right? Can you please confirm that
> > > > huge rework to avoid misunderstanding?
> > > 
> > > I don't understand why we even need to touch the existing RSA
> > > drivers.  Nothing needs to change as far as they're concerned.
> > > 
> > > Only the new algorithms would need to decode the extra parameters
> > > in the key stream.
> > 
> > int (*set_pub_key)(struct crypto_akcipher *tfm, const void *key,
> >unsigned int keylen);
> > int (*set_priv_key)(struct crypto_akcipher *tfm, const void *key,
> > unsigned int keylen);
> > 
> > So you want `keylen' not to cover parameters data, but parameters
> > actually present in key after `keylen' bytes (in come packed format)?
> > (And if there is no parameters appended, there is still appended some
> > marker, like 0, to signify that there is no parameters.)
> > 
> > This looks a bit counter-intuitive usage of arguments (as argument
> > signifying length does not cover all arguments data), is this ok to you?
> 
> This is how we handle things in DH as well as other places such
> as authenc.

dh.c (set_secret) is getting buf, len arguments and then parameters are
unpacked from that buffer. I think you want me to do this.

To make the same for set_{pub,priv}_key it will require patching RSA
drivers anyway, since length of the key is stored just once as keylen
argument.

Drivers will be changed to interpret key, keylen as buf, len and actual
keylen will be stored into the buf, and will be unpacked from there.

Thanks,

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


Re: [RFC PATCH 1/4] X.509: Parse public key parameters from x509 for akcipher

2019-02-28 Thread Vitaly Chikunov
On Thu, Feb 28, 2019 at 03:51:41PM +0800, Herbert Xu wrote:
> On Thu, Feb 28, 2019 at 10:04:49AM +0300, Vitaly Chikunov wrote:
> > 
> > It seems that you insist on set_params to be removed and both key and
> > params to be passed into set_{pub,priv}_key. This means reworking all
> > existing RSA drivers and callers, right? Can you please confirm that
> > huge rework to avoid misunderstanding?
> 
> I don't understand why we even need to touch the existing RSA
> drivers.  Nothing needs to change as far as they're concerned.
> 
> Only the new algorithms would need to decode the extra parameters
> in the key stream.

int (*set_pub_key)(struct crypto_akcipher *tfm, const void *key,
   unsigned int keylen);
int (*set_priv_key)(struct crypto_akcipher *tfm, const void *key,
unsigned int keylen);

So you want `keylen' not to cover parameters data, but parameters
actually present in key after `keylen' bytes (in come packed format)?
(And if there is no parameters appended, there is still appended some
marker, like 0, to signify that there is no parameters.)

This looks a bit counter-intuitive usage of arguments (as argument
signifying length does not cover all arguments data), is this ok to you?


More intuitive would be to add at least paramlen argument to signify how
much data is appended. Or (if we add argument anyway) additional
const void *params, unsigned int paramlen - which callers who don't
have params will pass NULL, and RSA drivers just ignore.



Re: [RFC PATCH 1/4] X.509: Parse public key parameters from x509 for akcipher

2019-02-27 Thread Vitaly Chikunov
On Thu, Feb 28, 2019 at 10:04:49AM +0300, Vitaly Chikunov wrote:
> Herbert,
> 
> On Thu, Feb 28, 2019 at 02:14:44PM +0800, Herbert Xu wrote:
> > On Sun, Feb 24, 2019 at 09:48:40AM +0300, Vitaly Chikunov wrote:
> > > 
> > > If we pass SubjectPublicKeyInfo into set_pub_key itself (making
> > > set_params not needed) we will break ABI and compatibility with RSA
> > > drivers, because whole SubjectPublicKeyInfo is not expected by the
> > 
> > This compatibility does not matter.  We can always add translating
> > layers into the crypto API to deal with this.  The only ABI that
> > matters is the one to user-space.
> 
> It seems that you insist on set_params to be removed and both key and
> params to be passed into set_{pub,priv}_key. This means reworking all
> existing RSA drivers and callers, right? Can you please confirm that
> huge rework to avoid misunderstanding?
> 
> I think to pass SubjectPublicKeyInfo into set_*_key would be overkill,
> because TPM drivers may not have it and we would need BER encoder just
> for that.
> 
> So, probably, something simple like length, key data, length, params data
> will be enough?

Or maybe we could just add additional argument to set_{pub,priv}_key?
(If you agree to change that ABI anyway).

> Thanks,


Re: [RFC PATCH 1/4] X.509: Parse public key parameters from x509 for akcipher

2019-02-27 Thread Vitaly Chikunov
Herbert,

On Thu, Feb 28, 2019 at 02:14:44PM +0800, Herbert Xu wrote:
> On Sun, Feb 24, 2019 at 09:48:40AM +0300, Vitaly Chikunov wrote:
> > 
> > If we pass SubjectPublicKeyInfo into set_pub_key itself (making
> > set_params not needed) we will break ABI and compatibility with RSA
> > drivers, because whole SubjectPublicKeyInfo is not expected by the
> 
> This compatibility does not matter.  We can always add translating
> layers into the crypto API to deal with this.  The only ABI that
> matters is the one to user-space.

It seems that you insist on set_params to be removed and both key and
params to be passed into set_{pub,priv}_key. This means reworking all
existing RSA drivers and callers, right? Can you please confirm that
huge rework to avoid misunderstanding?

I think to pass SubjectPublicKeyInfo into set_*_key would be overkill,
because TPM drivers may not have it and we would need BER encoder just
for that.

So, probably, something simple like length, key data, length, params data
will be enough?

Thanks,



Re: [PATCH v5 04/10] crypto: akcipher - new verify API for public key algorithms

2019-02-27 Thread Vitaly Chikunov
On Wed, Feb 27, 2019 at 06:28:37PM -0500, Mimi Zohar wrote:
> 
> On Sun, 2019-02-24 at 09:08 +0300, Vitaly Chikunov wrote:
> > Previous akcipher .verify() just `decrypts' (using RSA encrypt which is
> > using public key) signature to uncover message hash, which was then
> > compared in upper level public_key_verify_signature() with the expected
> > hash value, which itself was never passed into verify().
> > 
> > This approach was incompatible with EC-DSA family of algorithms,
> > because, to verify a signature EC-DSA algorithm also needs a hash value
> > as input; then it's used (together with a signature divided into halves
> > `r||s') to produce a witness value, which is then compared with `r' to
> > determine if the signature is correct. Thus, for EC-DSA, nor
> > requirements of .verify() itself, nor its output expectations in
> > public_key_verify_signature() wasn't sufficient.
> > 
> > Make improved .verify() call which gets hash value as input and produce
> > complete signature check without any output besides status.
> > 
> > Now for the top level verification only crypto_akcipher_verify() needs
> > to be called.
> 
> All but this patch apply.  Which branch is this patch based against?

This patchest is over 920d7f7215d87005beb4aa2b90b9cb0b74b36947 in
cryptodev/master.

> 
> Mimi


[PATCH RFC v6] integrity: support EC-RDSA signatures for asymmetric_verify

2019-02-26 Thread Vitaly Chikunov
Allow to use EC-RDSA signatures for IMA by determining signature type by
the hash algorithm name. This works good for EC-RDSA since Streebog and
EC-RDSA should always be used together.

Cc: Mimi Zohar 
Cc: Dmitry Kasatkin 
Cc: linux-integr...@vger.kernel.org
Signed-off-by: Vitaly Chikunov 
---
Changes since v5:

- This should go over "[PATCH v5 00/10] crypto: add EC-RDSA (GOST 34.10)
  algorithm" instead of "[PATCH v5 10/10] integrity: support EC-RDSA signatures
  for asymmetric_verify."

- Comparison of hash algo by enum id instead of text name, as suggested by
  Thiago Jung Bauermann and Mimi Zohar.

 security/integrity/digsig_asymmetric.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/security/integrity/digsig_asymmetric.c 
b/security/integrity/digsig_asymmetric.c
index d775e03fbbcc..99080871eb9f 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -104,9 +104,16 @@ int asymmetric_verify(struct key *keyring, const char *sig,
 
memset(, 0, sizeof(pks));
 
-   pks.pkey_algo = "rsa";
pks.hash_algo = hash_algo_name[hdr->hash_algo];
-   pks.encoding = "pkcs1";
+   if (hdr->hash_algo == HASH_ALGO_STREEBOG_256 ||
+   hdr->hash_algo == HASH_ALGO_STREEBOG_512) {
+   /* EC-RDSA and Streebog should go together. */
+   pks.pkey_algo = "ecrdsa";
+   pks.encoding = "raw";
+   } else {
+   pks.pkey_algo = "rsa";
+   pks.encoding = "pkcs1";
+   }
pks.digest = (u8 *)data;
pks.digest_size = datalen;
pks.s = hdr->sig;
-- 
2.11.0



Re: [PATCH v5 10/10] integrity: support EC-RDSA signatures for asymmetric_verify

2019-02-25 Thread Vitaly Chikunov
Thiago,

On Mon, Feb 25, 2019 at 06:20:49PM -0300, Thiago Jung Bauermann wrote:
> Vitaly Chikunov  writes:
> 
> > Allow to use EC-RDSA signatures for IMA by determining signature type by
> > the hash algorithm name. This works good for EC-RDSA since Streebog and
> > EC-RDSA should always be used together.
> >
> > Cc: Mimi Zohar 
> > Cc: Dmitry Kasatkin 
> > Cc: linux-integr...@vger.kernel.org
> > Signed-off-by: Vitaly Chikunov 
> > ---
> >  security/integrity/digsig_asymmetric.c | 9 +++--
> >  1 file changed, 7 insertions(+), 2 deletions(-)
> >
> > diff --git a/security/integrity/digsig_asymmetric.c 
> > b/security/integrity/digsig_asymmetric.c
> > index d775e03fbbcc..c4a3313e0210 100644
> > --- a/security/integrity/digsig_asymmetric.c
> > +++ b/security/integrity/digsig_asymmetric.c
> > @@ -104,9 +104,14 @@ int asymmetric_verify(struct key *keyring, const char 
> > *sig,
> >
> > memset(, 0, sizeof(pks));
> >
> > -   pks.pkey_algo = "rsa";
> > pks.hash_algo = hash_algo_name[hdr->hash_algo];
> > -   pks.encoding = "pkcs1";
> > +   if (!strncmp(pks.hash_algo, "streebog", 8)) {
> 
> Is it possible to test hdr->hash_algo instead of pkcs.hash_algo? IMHO if
> an integer value is available it's preferable to check it rather than
> doing a string comparison.

Yes. But we have long tradition of comparing by the name too:

  --linux$ git grep str.*cmp.*'"sha[12]'
  drivers/crypto/mxs-dcp.c:   if (strcmp(halg->base.cra_name, "sha1") == 0)
  drivers/crypto/talitos.c:   (!strcmp(alg->cra_name, "sha224") 
||
  net/sctp/sysctl.c:  if (!strncmp(tmp, "sha1", 4)) {
  scripts/sign-file.c:if (strcmp(hash_algo, "sha1") != 0) {
  security/integrity/ima/ima_main.c:  if (strncmp(str, "sha1", 4) 
== 0)
  --linux$ git grep str.*cmp.*hash_algo
  fs/ubifs/sb.c:  if (strcmp(hash_algo_name[hash_algo], c->auth_hash_name)) {
  scripts/sign-file.c:if (strcmp(hash_algo, "sha1") != 0) {
  security/integrity/ima/ima_main.c:  if (error && 
strcmp(hash_algo_name[ima_hash_algo],
  security/keys/trusted.c:if 
(!strcmp(args[0].from, hash_algo_name[i])) {
  --linux$ git grep str.*cmp.*cra_name
  crypto/adiantum.c:  if (strcmp(streamcipher_alg->base.cra_name, 
"xchacha12") != 0 &&
  crypto/adiantum.c:  strcmp(streamcipher_alg->base.cra_name, 
"xchacha20") != 0)
  crypto/adiantum.c:  if (strcmp(hash_alg->base.cra_name, "nhpoly1305") != 
0)
  crypto/algapi.c:if (!strcmp(q->cra_driver_name, 
alg->cra_name) ||
  crypto/algapi.c:!strcmp(q->cra_name, 
alg->cra_driver_name))
  crypto/algapi.c:if (strcmp(alg->cra_name, 
q->cra_name) &&
  crypto/algapi.c:strcmp(alg->cra_driver_name, 
q->cra_name))
  crypto/algapi.c:if (strcmp(alg->cra_name, q->cra_name))
  crypto/api.c:   fuzzy = !strcmp(q->cra_name, name);
  crypto/crypto_user_base.c:  match = !strcmp(q->cra_name, 
p->cru_name);
  crypto/cts.c:   if (strncmp(alg->base.cra_name, "cbc(", 4))
  crypto/simd.c:  WARN_ON(strncmp(algs[i].base.cra_name, "__", 2));
  drivers/crypto/mxs-dcp.c:   if (strcmp(halg->base.cra_name, "sha1") == 0)
  drivers/crypto/talitos.c:   !strncmp(alg->cra_name, 
"authenc(hmac(sha224)", 20)) {
  drivers/crypto/talitos.c:   if (!strncmp(alg->cra_name, "hmac", 
4))
  drivers/crypto/talitos.c:   !strncmp(alg->cra_name, "hmac", 
4)) {
  drivers/crypto/talitos.c:   (!strcmp(alg->cra_name, "sha224") 
||
  drivers/crypto/talitos.c:!strcmp(alg->cra_name, 
"hmac(sha224)"))) {
  lib/crc-t10dif.c:   strncmp(alg->cra_name, CRC_T10DIF_STRING, 
strlen(CRC_T10DIF_STRING)))


After all pkey_algo, hash_algo, cra_name are set to strings to be used
somewhere. So both ways looks equal to me.

[I more wonder if we should leave algo names to be used as they are in
x509_note_signature() (to check for "rsa" and "ecrdsa"), since there are
no other pkey_algo's set in x509_note_pkey_algo().]

> Also, it would be good to have a comment here mentioning that Streebog
> and EC-RDSA should always be used together

Thanks,

> > +   pks.pkey_algo = "ecrdsa";
> > +   pks.encoding = "raw";
> > +   } else {
> > +   pks.pkey_algo = "rsa";
> > +   pks.encoding = "pkcs1";
> > +   }
> > pks.digest = (u8 *)data;
> > pks.digest_size = datalen;
> > pks.s = hdr->sig;
> 
> --
> Thiago Jung Bauermann
> IBM Linux Technology Center


Re: [RFC PATCH 1/4] X.509: Parse public key parameters from x509 for akcipher

2019-02-23 Thread Vitaly Chikunov
Herbert,

On Tue, Feb 19, 2019 at 12:37:32PM +0800, Herbert Xu wrote:
> On Sun, Feb 10, 2019 at 09:46:28PM +0300, Vitaly Chikunov wrote:
> >
> > >From the other point of view, set_params may never be called or
> > implemented. So, making it called first and move memory zeroing
> > into set_params may create more complications than simplicity.
> > 
> > Making both callbacks callable in any order also will not make
> > things simpler. (Need to be prepared to be called in different
> > order.)
> 
> How about encoding these parameters together with the public/private
> keys so that they can be set through the existing setkey functions?
> 
> You might want to have a look at how we handle this in crypto/dh.c.

Thanks. I viewed and thought about this idea. But, I think separate
set_params call will be the most simple and backward compatible approach.

[In the new patchset] I made set_params to be called before set_p*_key
call, thus set_p*_key will know everything to start processing the key
immediately. Also, I made set_params completely optional, so code that
rely on RSA can just not call it, and driver that actually needs
set_params may check if required parameters are set or return an error.

(I overthought about zeroing of memory (in previous mail) that turned
out completely non-problem as ctx in `struct crypto_akcipher' is always
zeroed and I don't need to use ctx from `struct akcipher_request').


More thoughts. Parameters are part of AlgorithmIdentifier which is
included in SubjectPublicKeyInfo together with subjectPublicKey.

This, to pass into set_params callback AlgorithmIdentifier is the same
as passing just parameters. But, passing SubjectPublicKeyInfo will
overlap with passing the key into set_pub_key. So, if we pass other
structure (SubjectPublicKeyInfo) into set_params we will logically
conflict with set_pub_key and that call will be alternative to
set_pub_key, making one of them redundant.

If we pass SubjectPublicKeyInfo into set_pub_key itself (making
set_params not needed) we will break ABI and compatibility with RSA
drivers, because whole SubjectPublicKeyInfo is not expected by the
drivers, or new set_pub_key need somehow signal to the driver that is
different parameters are going (callers should be aware of that too),
and/or we will need to change all RSA-centric code to use
SubjectPublicKeyInfo which will affect to much code (more than verify2
required I think). And this will offload work which is already done by
x509 parser into the drivers bloating their code needlessly.

Thus, I think to try to remove set_params will only increase complexity.
Now it's small, very flexible, and back compatible.

Thanks,



[PATCH v5 00/10] crypto: add EC-RDSA (GOST 34.10) algorithm

2019-02-23 Thread Vitaly Chikunov
This patchset changes akcipher API to support ECDSA style signature
verification, augments x509 parser to make it work with EC-RDSA certificates,
and, finally, implements EC-RDSA (GOST 34.10) signature verification and its
integration with IMA.

Changes since RFC (v1-v4):
- akcipher set_max_size, encrypt, decrypt, sign, verify callbacks may be
  undefined by the drivers, so their crypto_akcipher_* frontends check for
  their presence before passing the call.
- supported_ops flags are set for keyctl, based on the presence of implemented
  akcipher callbacks.
- Transition to verify2 API is abandoned because raw RSA does not need
  sign/verify ops at all, and we can switch to the new verify in one step.
  For this RSA backends have sign/verify ops removed as they should only
  be used (and actually used only) via PKCS1 driver.
- Verify callback requires digest as the input parameter in src SGL, as
  suggested by Herbert Xu, (instead of a separate parameter, as it was in
  verify2).
- For verify op signature is moved into kmalloc'd memory as suggested by
  Herbert Xu.
- set_params API should be called before set_{pub,priv}_key, thus set_*_key
  knows everything it needs to set they key properly. Also, set_params made
  optional for back compatibility with RSA drivers.
- Public-key cryptography section is created in Kconfig.
- ecc.c is made into separate module object, to be used together by ECDH and
  EC-RDSA.
- EC-RDSA parameters and public key are parsed using asn1_ber_decoder as
  suggested by Stephan Mueller and David Howells.
- Test vectors are added and tests are passing.
- Curves/parameters definitions are split from ecrdsa.c into ecrdsa_defs.h.
- Integration with IMA in asymmetric_verify(). Userspace ima-evm-utils already
  have a patch in the queue to support this. Tested on x86_64.

---
Vitaly Chikunov (10):
  KEYS: report to keyctl only actually supported key ops
  crypto: akcipher - check the presence of callback before the call
  crypto: rsa - unimplement sign/verify for raw RSA backends
  crypto: akcipher - new verify API for public key algorithms
  X.509: parse public key parameters from x509 for akcipher
  crypto: Kconfig - create Public-key cryptography section
  crypto: ecc - make ecc into separate module
  crypto: ecrdsa - add EC-RDSA (GOST 34.10) algorithm
  crypto: ecrdsa - add EC-RDSA test vectors to testmgr
  integrity: support EC-RDSA signatures for asymmetric_verify

 crypto/Kconfig|  63 ++--
 crypto/Makefile   |  10 +-
 crypto/asymmetric_keys/asym_tpm.c |  34 +--
 crypto/asymmetric_keys/public_key.c   |  63 ++--
 crypto/asymmetric_keys/x509.asn1  |   2 +-
 crypto/asymmetric_keys/x509_cert_parser.c |  57 +++-
 crypto/ecc.c  | 417 +-
 crypto/ecc.h  | 153 +-
 crypto/ecc_curve_defs.h   |  15 -
 crypto/ecrdsa.c   | 297 ++
 crypto/ecrdsa_defs.h  | 225 ++
 crypto/rsa-pkcs1pad.c |  33 +-
 crypto/rsa.c  | 109 ---
 crypto/testmgr.c  |  60 ++--
 crypto/testmgr.h  | 157 ++
 drivers/crypto/caam/caampkc.c |   2 -
 drivers/crypto/ccp/ccp-crypto-rsa.c   |   2 -
 drivers/crypto/qat/qat_common/qat_asym_algs.c |   2 -
 include/crypto/akcipher.h |  97 --
 include/crypto/public_key.h   |   4 +
 include/linux/oid_registry.h  |  18 ++
 security/integrity/digsig_asymmetric.c|   9 +-
 22 files changed, 1545 insertions(+), 284 deletions(-)
 create mode 100644 crypto/ecrdsa.c
 create mode 100644 crypto/ecrdsa_defs.h

-- 
2.11.0



[PATCH v5 07/10] crypto: ecc - make ecc into separate module

2019-02-23 Thread Vitaly Chikunov
ecc.c have algorithms that could be used togeter by ecdh and ecrdsa.
Make it separate module. Add CRYPTO_ECC into Kconfig. EXPORT_SYMBOL and
document to what seems appropriate. Move structs ecc_point and ecc_curve
from ecc_curve_defs.h into ecc.h.

No code changes.

Signed-off-by: Vitaly Chikunov 
---
 crypto/Kconfig  |  4 ++
 crypto/Makefile |  2 +-
 crypto/ecc.c| 25 +
 crypto/ecc.h| 99 +
 crypto/ecc_curve_defs.h | 15 
 5 files changed, 122 insertions(+), 23 deletions(-)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 370cbdca87a7..cf0bceee0ea5 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -248,8 +248,12 @@ config CRYPTO_DH
help
  Generic implementation of the Diffie-Hellman algorithm.
 
+config CRYPTO_ECC
+   tristate
+
 config CRYPTO_ECDH
tristate "ECDH algorithm"
+   select CRYPTO_ECC
select CRYPTO_KPP
select CRYPTO_RNG_DEFAULT
help
diff --git a/crypto/Makefile b/crypto/Makefile
index 799ed5e94606..b660f078651a 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -147,8 +147,8 @@ obj-$(CONFIG_CRYPTO_USER_API_RNG) += algif_rng.o
 obj-$(CONFIG_CRYPTO_USER_API_AEAD) += algif_aead.o
 obj-$(CONFIG_CRYPTO_ZSTD) += zstd.o
 obj-$(CONFIG_CRYPTO_OFB) += ofb.o
+obj-$(CONFIG_CRYPTO_ECC) += ecc.o
 
-ecdh_generic-y := ecc.o
 ecdh_generic-y += ecdh.o
 ecdh_generic-y += ecdh_helper.o
 obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
diff --git a/crypto/ecc.c b/crypto/ecc.c
index ed1237115066..5f36792d143d 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -24,6 +24,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -112,7 +113,7 @@ static void vli_clear(u64 *vli, unsigned int ndigits)
 }
 
 /* Returns true if vli == 0, false otherwise. */
-static bool vli_is_zero(const u64 *vli, unsigned int ndigits)
+bool vli_is_zero(const u64 *vli, unsigned int ndigits)
 {
int i;
 
@@ -123,6 +124,7 @@ static bool vli_is_zero(const u64 *vli, unsigned int 
ndigits)
 
return true;
 }
+EXPORT_SYMBOL(vli_is_zero);
 
 /* Returns nonzero if bit bit of vli is set. */
 static u64 vli_test_bit(const u64 *vli, unsigned int bit)
@@ -171,7 +173,7 @@ static void vli_set(u64 *dest, const u64 *src, unsigned int 
ndigits)
 }
 
 /* Returns sign of left - right. */
-static int vli_cmp(const u64 *left, const u64 *right, unsigned int ndigits)
+int vli_cmp(const u64 *left, const u64 *right, unsigned int ndigits)
 {
int i;
 
@@ -184,6 +186,7 @@ static int vli_cmp(const u64 *left, const u64 *right, 
unsigned int ndigits)
 
return 0;
 }
+EXPORT_SYMBOL(vli_cmp);
 
 /* Computes result = in << c, returning carry. Can modify in place
  * (if result == in). 0 < shift < 64.
@@ -240,7 +243,7 @@ static u64 vli_add(u64 *result, const u64 *left, const u64 
*right,
 }
 
 /* Computes result = left - right, returning borrow. Can modify in place. */
-static u64 vli_sub(u64 *result, const u64 *left, const u64 *right,
+u64 vli_sub(u64 *result, const u64 *left, const u64 *right,
   unsigned int ndigits)
 {
u64 borrow = 0;
@@ -258,6 +261,7 @@ static u64 vli_sub(u64 *result, const u64 *left, const u64 
*right,
 
return borrow;
 }
+EXPORT_SYMBOL(vli_sub);
 
 static uint128_t mul_64_64(u64 left, u64 right)
 {
@@ -557,7 +561,7 @@ static void vli_mod_square_fast(u64 *result, const u64 
*left,
  * See "From Euclid's GCD to Montgomery Multiplication to the Great Divide"
  * https://labs.oracle.com/techrep/2001/smli_tr-2001-95.pdf
  */
-static void vli_mod_inv(u64 *result, const u64 *input, const u64 *mod,
+void vli_mod_inv(u64 *result, const u64 *input, const u64 *mod,
unsigned int ndigits)
 {
u64 a[ECC_MAX_DIGITS], b[ECC_MAX_DIGITS];
@@ -630,6 +634,7 @@ static void vli_mod_inv(u64 *result, const u64 *input, 
const u64 *mod,
 
vli_set(result, u, ndigits);
 }
+EXPORT_SYMBOL(vli_mod_inv);
 
 /* -- Point operations -- */
 
@@ -948,6 +953,7 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int 
ndigits,
 
return __ecc_is_key_valid(curve, private_key, ndigits);
 }
+EXPORT_SYMBOL(ecc_is_key_valid);
 
 /*
  * ECC private keys are generated using the method of extra random bits,
@@ -1000,6 +1006,7 @@ int ecc_gen_privkey(unsigned int curve_id, unsigned int 
ndigits, u64 *privkey)
 
return 0;
 }
+EXPORT_SYMBOL(ecc_gen_privkey);
 
 int ecc_make_pub_key(unsigned int curve_id, unsigned int ndigits,
 const u64 *private_key, u64 *public_key)
@@ -1036,10 +1043,11 @@ int ecc_make_pub_key(unsigned int curve_id, unsigned 
int ndigits,
 out:
return ret;
 }
+EXPORT_SYMBOL(ecc_make_pub_key);
 
 /* SP800-56A section 5.6.2.3.4 partial verification: ephemeral keys only */
-static int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve,
-  

[PATCH v5 04/10] crypto: akcipher - new verify API for public key algorithms

2019-02-23 Thread Vitaly Chikunov
Previous akcipher .verify() just `decrypts' (using RSA encrypt which is
using public key) signature to uncover message hash, which was then
compared in upper level public_key_verify_signature() with the expected
hash value, which itself was never passed into verify().

This approach was incompatible with EC-DSA family of algorithms,
because, to verify a signature EC-DSA algorithm also needs a hash value
as input; then it's used (together with a signature divided into halves
`r||s') to produce a witness value, which is then compared with `r' to
determine if the signature is correct. Thus, for EC-DSA, nor
requirements of .verify() itself, nor its output expectations in
public_key_verify_signature() wasn't sufficient.

Make improved .verify() call which gets hash value as input and produce
complete signature check without any output besides status.

Now for the top level verification only crypto_akcipher_verify() needs
to be called.

Cc: David Howells 
Cc: keyri...@vger.kernel.org
Signed-off-by: Vitaly Chikunov 
---
 crypto/asymmetric_keys/asym_tpm.c   | 34 -
 crypto/asymmetric_keys/public_key.c | 34 -
 crypto/rsa-pkcs1pad.c   | 29 +
 crypto/testmgr.c| 50 ++---
 include/crypto/akcipher.h   | 40 ++---
 5 files changed, 95 insertions(+), 92 deletions(-)

diff --git a/crypto/asymmetric_keys/asym_tpm.c 
b/crypto/asymmetric_keys/asym_tpm.c
index 5d4c270463f6..4e5b6fb57a94 100644
--- a/crypto/asymmetric_keys/asym_tpm.c
+++ b/crypto/asymmetric_keys/asym_tpm.c
@@ -744,12 +744,11 @@ static int tpm_key_verify_signature(const struct key *key,
struct crypto_wait cwait;
struct crypto_akcipher *tfm;
struct akcipher_request *req;
-   struct scatterlist sig_sg, digest_sg;
+   struct scatterlist src_sg[2];
char alg_name[CRYPTO_MAX_ALG_NAME];
uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
uint32_t der_pub_key_len;
-   void *output;
-   unsigned int outlen;
+   void *digest;
int ret;
 
pr_devel("==>%s()\n", __func__);
@@ -782,35 +781,22 @@ static int tpm_key_verify_signature(const struct key *key,
goto error_free_tfm;
 
ret = -ENOMEM;
-   outlen = crypto_akcipher_maxsize(tfm);
-   output = kmalloc(outlen, GFP_KERNEL);
-   if (!output)
+   digest = kmemdup(sig->digest, sig->digest_size, GFP_KERNEL);
+   if (!digest)
goto error_free_req;
 
-   sg_init_one(_sg, sig->s, sig->s_size);
-   sg_init_one(_sg, output, outlen);
-   akcipher_request_set_crypt(req, _sg, _sg, sig->s_size,
-  outlen);
+   sg_init_table(src_sg, 2);
+   sg_set_buf(_sg[0], sig->s, sig->s_size);
+   sg_set_buf(_sg[1], digest, sig->digest_size);
+   akcipher_request_set_crypt(req, src_sg, NULL, sig->s_size,
+  sig->digest_size);
crypto_init_wait();
akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
  CRYPTO_TFM_REQ_MAY_SLEEP,
  crypto_req_done, );
-
-   /* Perform the verification calculation.  This doesn't actually do the
-* verification, but rather calculates the hash expected by the
-* signature and returns that to us.
-*/
ret = crypto_wait_req(crypto_akcipher_verify(req), );
-   if (ret)
-   goto out_free_output;
-
-   /* Do the actual verification step. */
-   if (req->dst_len != sig->digest_size ||
-   memcmp(sig->digest, output, sig->digest_size) != 0)
-   ret = -EKEYREJECTED;
 
-out_free_output:
-   kfree(output);
+   kfree(digest);
 error_free_req:
akcipher_request_free(req);
 error_free_tfm:
diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index c2e4e73fcf06..338f2b5352b1 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -233,10 +233,9 @@ int public_key_verify_signature(const struct public_key 
*pkey,
struct crypto_wait cwait;
struct crypto_akcipher *tfm;
struct akcipher_request *req;
-   struct scatterlist sig_sg, digest_sg;
+   struct scatterlist src_sg[2];
char alg_name[CRYPTO_MAX_ALG_NAME];
-   void *output;
-   unsigned int outlen;
+   void *digest;
int ret;
 
pr_devel("==>%s()\n", __func__);
@@ -270,35 +269,22 @@ int public_key_verify_signature(const struct public_key 
*pkey,
goto error_free_req;
 
ret = -ENOMEM;
-   outlen = crypto_akcipher_maxsize(tfm);
-   output = kmalloc(outlen, GFP_KERNEL);
-   if (!output)
+   digest = kmemdup(sig->digest, sig->digest_size, GFP_KERNEL);
+   if (!digest)
 

[PATCH v5 10/10] integrity: support EC-RDSA signatures for asymmetric_verify

2019-02-23 Thread Vitaly Chikunov
Allow to use EC-RDSA signatures for IMA by determining signature type by
the hash algorithm name. This works good for EC-RDSA since Streebog and
EC-RDSA should always be used together.

Cc: Mimi Zohar 
Cc: Dmitry Kasatkin 
Cc: linux-integr...@vger.kernel.org
Signed-off-by: Vitaly Chikunov 
---
 security/integrity/digsig_asymmetric.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/security/integrity/digsig_asymmetric.c 
b/security/integrity/digsig_asymmetric.c
index d775e03fbbcc..c4a3313e0210 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -104,9 +104,14 @@ int asymmetric_verify(struct key *keyring, const char *sig,
 
memset(, 0, sizeof(pks));
 
-   pks.pkey_algo = "rsa";
pks.hash_algo = hash_algo_name[hdr->hash_algo];
-   pks.encoding = "pkcs1";
+   if (!strncmp(pks.hash_algo, "streebog", 8)) {
+   pks.pkey_algo = "ecrdsa";
+   pks.encoding = "raw";
+   } else {
+   pks.pkey_algo = "rsa";
+   pks.encoding = "pkcs1";
+   }
pks.digest = (u8 *)data;
pks.digest_size = datalen;
pks.s = hdr->sig;
-- 
2.11.0



[PATCH v5 09/10] crypto: ecrdsa - add EC-RDSA test vectors to testmgr

2019-02-23 Thread Vitaly Chikunov
Add testmgr test vectors for EC-RDSA algorithm for every of five
supported parameters (curves). Because there are no officially published
test vectors for the curves, the vectors are generated by gost-engine.

Signed-off-by: Vitaly Chikunov 
---
 crypto/testmgr.c |   6 +++
 crypto/testmgr.h | 154 +++
 2 files changed, 160 insertions(+)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index b5bafb59e1dc..bfccf5260241 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -3370,6 +3370,12 @@ static const struct alg_test_desc alg_test_descs[] = {
.kpp = __VECS(ecdh_tv_template)
}
}, {
+   .alg = "ecrdsa",
+   .test = alg_test_akcipher,
+   .suite = {
+   .akcipher = __VECS(ecrdsa_tv_template)
+   }
+   }, {
.alg = "gcm(aes)",
.test = alg_test_aead,
.fips_allowed = 1,
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 9c6a2752..dc2332ce4f4e 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -552,6 +552,160 @@ static const struct akcipher_testvec rsa_tv_template[] = {
 };
 
 /*
+ * EC-RDSA test vectors are generated by gost-engine.
+ */
+static const struct akcipher_testvec ecrdsa_tv_template[] = {
+   {
+   .key =
+   "\x04\x40\xd5\xa7\x77\xf9\x26\x2f\x8c\xbd\xcc\xe3\x1f\x01\x94\x05"
+   "\x3d\x2f\xec\xb5\x00\x34\xf5\x51\x6d\x3b\x90\x4b\x23\x28\x6f\x1d"
+   "\xc8\x36\x61\x60\x36\xec\xbb\xb4\x0b\x95\x4e\x54\x4f\x15\x21\x05"
+   "\xd8\x52\x66\x44\x31\x7e\x5d\xc5\xd1\x26\x00\x5f\x60\xd8\xf0\xc7"
+   "\x27\xfc",
+   .key_len = 66,
+   .params = /* OID_gostCPSignA */
+   "\x30\x13\x06\x07\x2a\x85\x03\x02\x02\x23\x01\x06\x08\x2a\x85\x03"
+   "\x07\x01\x01\x02\x02",
+   .param_len = 21,
+   .c =
+   "\x41\x32\x09\x73\xa4\xc1\x38\xd6\x63\x7d\x8b\xf7\x50\x3f\xda\x9f"
+   "\x68\x48\xc1\x50\xe3\x42\x3a\x9b\x2b\x28\x12\x2a\xa7\xc2\x75\x31"
+   "\x65\x77\x8c\x3c\x9e\x0d\x56\xb2\xf9\xdc\x04\x33\x3e\xb0\x9e\xf9"
+   "\x74\x4e\x59\xb3\x83\xf2\x91\x27\xda\x5e\xc7\x33\xc0\xc1\x8f\x41",
+   .c_size = 64,
+   .algo = OID_gost2012PKey256,
+   .m =
+   "\x75\x1b\x9b\x40\x25\xb9\x96\xd2\x9b\x00\x41\xb3\x58\xbf\x23\x14"
+   "\x79\xd2\x76\x64\xa3\xbd\x66\x10\x79\x05\x5a\x06\x42\xec\xb9\xc9",
+   .m_size = 32,
+   .public_key_vec = true,
+   .siggen_sigver_test = true,
+   },
+   {
+   .key =
+   "\x04\x40\x66\x6f\xd6\xb7\x06\xd0\xf5\xa5\x6f\x69\x5c\xa5\x13\x45"
+   "\x14\xdd\xcb\x12\x9c\x1b\xf5\x28\x64\x7a\x49\x48\x29\x14\x66\x42"
+   "\xb8\x1b\x5c\xf9\x56\x6d\x08\x3b\xce\xbb\x62\x2f\xc2\x3c\xc5\x49"
+   "\x93\x27\x70\x20\xcc\x79\xeb\xdc\x76\x8e\x48\x6e\x04\x96\xc3\x29"
+   "\xa0\x73",
+   .key_len = 66,
+   .params = /* OID_gostCPSignB */
+   "\x30\x13\x06\x07\x2a\x85\x03\x02\x02\x23\x02\x06\x08\x2a\x85\x03"
+   "\x07\x01\x01\x02\x02",
+   .param_len = 21,
+   .c =
+   "\x45\x6d\x4a\x03\x1d\x5c\x0b\x17\x79\xe7\x19\xdb\xbf\x81\x9f\x82"
+   "\xae\x06\xda\xf5\x47\x00\x05\x80\xc3\x16\x06\x9a\x8e\x7c\xb2\x8e"
+   "\x7f\x74\xaa\xec\x6b\x7b\x7f\x8b\xc6\x0b\x10\x42\x4e\x91\x2c\xdf"
+   "\x7b\x8b\x15\xf4\x9e\x59\x0f\xc7\xa4\x68\x2e\xce\x89\xdf\x84\xe9",
+   .c_size = 64,
+   .algo = OID_gost2012PKey256,
+   .m =
+   "\xd0\x54\x00\x27\x6a\xeb\xce\x6c\xf5\xf6\xfb\x57\x18\x18\x21\x13"
+   "\x11\x23\x4a\x70\x43\x52\x7a\x68\x11\x65\x45\x37\xbb\x25\xb7\x40",
+   .m_size = 32,
+   .public_key_vec = true,
+   .siggen_sigver_test = true,
+   },
+   {
+   .key =
+   "\x04\x40\x05\x91\xa9\x7d\xcb\x87\xdc\x98\xa1\xbf\xff\xdd\x20\x61"
+   "\xaa\x58\x3b\x2d\x8e\x9c\x41\x9d\x4f\xc6\x23\x17\xf9\xca\x60\x65"
+   "\xbc\x97\x97\xf6\x6b\x24\xe8\xac\xb1\xa7\x61\x29\x3c\x71\xdc\xad"
+   "\xcb\x20\xbe\x96\xe8\xf4\x44\x2e\x49\xd5\x2c\xb9\xc9\x3b\x9c\xaa"
+   "\xba\x15",
+   .key_len = 66,
+   .params = /* OID_gostCPSignC */
+   "\x30\x13\x06\x07\x2a\x85\x03\x02\x02\x23\x03\x06\x08\x2a\x85\x03"
+   "\x07\x01\x01\x02\x02",
+   .param_len = 21,
+   .c =
+   "\x3b\x2e\x2e\x74\x74\x47\xda\xea\x93\x90\x6a\xe2\xf5\xf5\xe6\x46"
+   "\x11\xfc\xab\xdc\x52\xbc\x58\xdb\x45\x44\x12\x4a\xf7\xd0\xab\xc9"
+   "\x73\xba\x64\xab\x0d\xac\x4e\x72\x10\xa8\x04\xf6\x1e\xe0\x48\x6a"
+   "\xcd\xe8\xe3\x78\x73\x77\x82\x24\x8d\xf1\xd3\xeb\x4c\x25\x7e\xc0",
+   .c_size = 64,
+   .algo = OID_gost2012P

[PATCH v5 08/10] crypto: ecrdsa - add EC-RDSA (GOST 34.10) algorithm

2019-02-23 Thread Vitaly Chikunov
Add Elliptic Curve Russian Digital Signature Algorithm (GOST R
34.10-2012, RFC 7091, ISO/IEC 14888-3) is one of the Russian (and since
2018 the CIS countries) cryptographic standard algorithms (called GOST
algorithms). Only signature verification is supported, with intent to be
used in the IMA.

Summary of the changes:

* crypto/Kconfig:
  - EC-RDSA is added into Public-key cryptography section.

* crypto/Makefile:
  - ecrdsa objects are added.

* crypto/asymmetric_keys/x509_cert_parser.c:
  - Recognize EC-RDSA and Streebog OIDs.

* include/linux/oid_registry.h:
  - EC-RDSA OIDs are added to the enum. Also, a two currently not
implemented curve OIDs are added for possible extension later (to
not change numbering and grouping).

* crypto/ecc.c:
  - Kenneth MacKay copyright date is updated to 2014, because
vli_mmod_slow, ecc_point_add, ecc_point_mult_shamir are based on his
code from micro-ecc.
  - Functions needed for ecrdsa are EXPORT_SYMBOL'ed.
  - New functions:
vli_is_negative - helper to determine sign of vli;
vli_from_be64 - unpack big-endian array into vli (used for
  a signature);
vli_from_le64 - unpack little-endian array into vli (used for
  a public key);
vli_uadd, vli_usub - add/sub u64 value to/from vli (used for
  increment/decrement);
mul_64_64 - optimized to use __int128 where appropriate, this speeds
  up point multiplication (and as a consequence signature
  verification) by the factor of 1.5-2;
vli_umult - multiply vli by a small value (speeds up point
  multiplication by another factor of 1.5-2, depending on vli sizes);
vli_mmod_special - module reduction for some form of Pseudo-Mersenne
  primes (used for the curves A);
vli_mmod_special2 - module reduction for another form of
  Pseudo-Mersenne primes (used for the curves B);
vli_mmod_barrett - module reduction using pre-computed value (used
  for the curve C);
vli_mmod_slow - more general module reduction which is much slower
 (used when the modulus is subgroup order);
vli_mod_mult_slow - modular multiplication;
ecc_point_add - add two points;
ecc_point_mult_shamir - add two points multiplied by scalars in one
  combined multiplication (this gives speed up by another factor 2 in
  compare to two separate multiplications).
ecc_is_pubkey_valid_partial - additional samity check is added.
  - Updated vli_mmod_fast with non-strict heuristic to call optimal
  module reduction function depending on the prime value;
  - All computations for the previously defined (two NIST) curves should
not unaffected.

* crypto/ecc.h:
  - Newly exported functions are documented.

* crypto/ecrdsa_defs.h
  - Five curves are defined.

* crypto/ecrdsa.c:
  - Signature verification is implemented.

* crypto/ecrdsa_params.asn1, crypto/ecrdsa_pub_key.asn1:
  - Templates for BER decoder for EC-RDSA parameters and public key.

Cc: linux-integr...@vger.kernel.org
Signed-off-by: Vitaly Chikunov 
---
 crypto/Kconfig|  11 +
 crypto/Makefile   |   8 +
 crypto/asymmetric_keys/x509_cert_parser.c |  26 +-
 crypto/ecc.c  | 392 +-
 crypto/ecc.h  |  54 +++-
 crypto/ecrdsa.c   | 297 ++
 crypto/ecrdsa_defs.h  | 225 +
 include/linux/oid_registry.h  |  18 ++
 8 files changed, 1018 insertions(+), 13 deletions(-)
 create mode 100644 crypto/ecrdsa.c
 create mode 100644 crypto/ecrdsa_defs.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index cf0bceee0ea5..c7e7e3ac38ed 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -259,6 +259,17 @@ config CRYPTO_ECDH
help
  Generic implementation of the ECDH algorithm
 
+config CRYPTO_ECRDSA
+   tristate "EC-RDSA (GOST 34.10) algorithm"
+   select CRYPTO_ECC
+   select CRYPTO_AKCIPHER
+   select CRYPTO_STREEBOG
+   help
+ Elliptic Curve Russian Digital Signature Algorithm (GOST R 34.10-2012,
+ RFC 7091, ISO/IEC 14888-3:2018) is one of the Russian cryptographic
+ standard algorithms (called GOST algorithms). Only signature 
verification
+ is supported.
+
 comment "Authenticated Encryption with Associated Data"
 
 config CRYPTO_CCM
diff --git a/crypto/Makefile b/crypto/Makefile
index b660f078651a..89e5e55bf391 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -153,6 +153,14 @@ ecdh_generic-y += ecdh.o
 ecdh_generic-y += ecdh_helper.o
 obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
 
+$(obj)/ecrdsa_params.asn1.o: $(obj)/ecrdsa_params.asn1.c 
$(obj)/ecrdsa_params.asn1.h
+$(obj)/ecrdsa_pub_key.asn1.o: $(obj)/ecrdsa_pub_key.asn1.c 
$(obj)/ecrdsa_pub_key.asn1.h
+$(obj)/ecrdsa.o: $(obj)/ecrdsa_params.asn1.h $(obj)/ecrdsa_pub_key.asn1.h
+ecrdsa_generic-y += ecrdsa.o
+ecrdsa_generic-y += ecrdsa_params.asn1

[PATCH v5 05/10] X.509: parse public key parameters from x509 for akcipher

2019-02-23 Thread Vitaly Chikunov
Some public key algorithms (like EC-DSA) keep in parameters field
important data such as digest and curve OIDs (possibly more for
different EC-DSA variants). Thus, just setting a public key (as
for RSA) is not enough.

Introduce set_params() callback for akcipher which will be used to
pass BER encoded parameters array, with additional argument of
algorithm OID.

Rationale:

- For such keys just setting a public key without parameters is
  meaningless, so it would be possible to set parameters before
  crypto_akcipher_set_pub_key (and .set_pub_key) calls without
  needless change of API for RSA akcipher. Also, additional
  callback making it possible to pass parameters for
  crypto_akcipher_set_priv_key (and .set_priv_key).

- Algorithm OID is passed to be validated in .set_params callback,
  otherwise, it could have a wrong value.

- The callback is completely optional and if the driver doesn't need
  parameters, it may not implement it, such as for RSA drivers.

Cc: David Howells 
Cc: keyri...@vger.kernel.org
Signed-off-by: Vitaly Chikunov 
---
 crypto/asymmetric_keys/public_key.c   | 13 
 crypto/asymmetric_keys/x509.asn1  |  2 +-
 crypto/asymmetric_keys/x509_cert_parser.c | 31 
 crypto/testmgr.c  |  4 
 crypto/testmgr.h  |  3 +++
 include/crypto/akcipher.h | 34 +++
 include/crypto/public_key.h   |  4 
 7 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index 338f2b5352b1..d67374ef4f24 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -45,6 +45,7 @@ void public_key_free(struct public_key *key)
 {
if (key) {
kfree(key->key);
+   kfree(key->params);
kfree(key);
}
 }
@@ -115,6 +116,10 @@ static int software_key_query(const struct 
kernel_pkey_params *params,
if (IS_ERR(tfm))
return PTR_ERR(tfm);
 
+   ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
+pkey->paramlen);
+   if (ret)
+   goto error_free_tfm;
if (pkey->key_is_private)
ret = crypto_akcipher_set_priv_key(tfm,
   pkey->key, pkey->keylen);
@@ -179,6 +184,10 @@ static int software_key_eds_op(struct kernel_pkey_params 
*params,
if (!req)
goto error_free_tfm;
 
+   ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
+pkey->paramlen);
+   if (ret)
+   goto error_free_req;
if (pkey->key_is_private)
ret = crypto_akcipher_set_priv_key(tfm,
   pkey->key, pkey->keylen);
@@ -259,6 +268,10 @@ int public_key_verify_signature(const struct public_key 
*pkey,
if (!req)
goto error_free_tfm;
 
+   ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
+pkey->paramlen);
+   if (ret)
+   goto error_free_req;
if (pkey->key_is_private)
ret = crypto_akcipher_set_priv_key(tfm,
   pkey->key, pkey->keylen);
diff --git a/crypto/asymmetric_keys/x509.asn1 b/crypto/asymmetric_keys/x509.asn1
index aae0cde414e2..5c9f4e4a5231 100644
--- a/crypto/asymmetric_keys/x509.asn1
+++ b/crypto/asymmetric_keys/x509.asn1
@@ -22,7 +22,7 @@ CertificateSerialNumber ::= INTEGER
 
 AlgorithmIdentifier ::= SEQUENCE {
algorithm   OBJECT IDENTIFIER ({ x509_note_OID }),
-   parameters  ANY OPTIONAL
+   parameters  ANY OPTIONAL ({ x509_note_params })
 }
 
 Name ::= SEQUENCE OF RelativeDistinguishedName
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c 
b/crypto/asymmetric_keys/x509_cert_parser.c
index 991f4d735a4e..b2cdf2db1987 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -26,6 +26,9 @@ struct x509_parse_context {
const void  *cert_start;/* Start of cert content */
const void  *key;   /* Key data */
size_t  key_size;   /* Size of key data */
+   const void  *params;/* Key parameters */
+   size_t  params_size;/* Size of key parameters */
+   enum OIDkey_algo;   /* Public key algorithm */
enum OIDlast_oid;   /* Last OID encountered */
enum OIDalgo_oid;   /* Algorithm OID */
unsigned char   nr_mpi; /* Number of MPIs stored */
@@ -109,6 +112,13 @@ struct

[PATCH v5 03/10] crypto: rsa - unimplement sign/verify for raw RSA backends

2019-02-23 Thread Vitaly Chikunov
In preparation for new akcipher verify call remove sign/verify callbacks
from RSA backends and make PKCS1 driver call encrypt/decrypt instead.

This also complies with the well-known idea that raw RSA should never be
used for sign/verify. It only should be used with proper padding scheme
such as PKCS1 driver provides.

Cc: Giovanni Cabiddu 
Cc: qat-li...@intel.com
Cc: Tom Lendacky 
Cc: Gary Hook 
Cc: Horia Geantă 
Cc: Aymen Sghaier 
Signed-off-by: Vitaly Chikunov 
---
 crypto/rsa-pkcs1pad.c |   4 +-
 crypto/rsa.c  | 109 --
 drivers/crypto/caam/caampkc.c |   2 -
 drivers/crypto/ccp/ccp-crypto-rsa.c   |   2 -
 drivers/crypto/qat/qat_common/qat_asym_algs.c |   2 -
 5 files changed, 2 insertions(+), 117 deletions(-)

diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
index 0a6680ca8cb6..94382fa2c6ac 100644
--- a/crypto/rsa-pkcs1pad.c
+++ b/crypto/rsa-pkcs1pad.c
@@ -429,7 +429,7 @@ static int pkcs1pad_sign(struct akcipher_request *req)
akcipher_request_set_crypt(_ctx->child_req, req_ctx->in_sg,
   req->dst, ctx->key_size - 1, req->dst_len);
 
-   err = crypto_akcipher_sign(_ctx->child_req);
+   err = crypto_akcipher_decrypt(_ctx->child_req);
if (err != -EINPROGRESS && err != -EBUSY)
return pkcs1pad_encrypt_sign_complete(req, err);
 
@@ -551,7 +551,7 @@ static int pkcs1pad_verify(struct akcipher_request *req)
   req_ctx->out_sg, req->src_len,
   ctx->key_size);
 
-   err = crypto_akcipher_verify(_ctx->child_req);
+   err = crypto_akcipher_encrypt(_ctx->child_req);
if (err != -EINPROGRESS && err != -EBUSY)
return pkcs1pad_verify_complete(req, err);
 
diff --git a/crypto/rsa.c b/crypto/rsa.c
index 4167980c243d..5d427c1100d6 100644
--- a/crypto/rsa.c
+++ b/crypto/rsa.c
@@ -50,34 +50,6 @@ static int _rsa_dec(const struct rsa_mpi_key *key, MPI m, 
MPI c)
return mpi_powm(m, c, key->d, key->n);
 }
 
-/*
- * RSASP1 function [RFC3447 sec 5.2.1]
- * s = m^d mod n
- */
-static int _rsa_sign(const struct rsa_mpi_key *key, MPI s, MPI m)
-{
-   /* (1) Validate 0 <= m < n */
-   if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0)
-   return -EINVAL;
-
-   /* (2) s = m^d mod n */
-   return mpi_powm(s, m, key->d, key->n);
-}
-
-/*
- * RSAVP1 function [RFC3447 sec 5.2.2]
- * m = s^e mod n;
- */
-static int _rsa_verify(const struct rsa_mpi_key *key, MPI m, MPI s)
-{
-   /* (1) Validate 0 <= s < n */
-   if (mpi_cmp_ui(s, 0) < 0 || mpi_cmp(s, key->n) >= 0)
-   return -EINVAL;
-
-   /* (2) m = s^e mod n */
-   return mpi_powm(m, s, key->e, key->n);
-}
-
 static inline struct rsa_mpi_key *rsa_get_key(struct crypto_akcipher *tfm)
 {
return akcipher_tfm_ctx(tfm);
@@ -160,85 +132,6 @@ static int rsa_dec(struct akcipher_request *req)
return ret;
 }
 
-static int rsa_sign(struct akcipher_request *req)
-{
-   struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
-   const struct rsa_mpi_key *pkey = rsa_get_key(tfm);
-   MPI m, s = mpi_alloc(0);
-   int ret = 0;
-   int sign;
-
-   if (!s)
-   return -ENOMEM;
-
-   if (unlikely(!pkey->n || !pkey->d)) {
-   ret = -EINVAL;
-   goto err_free_s;
-   }
-
-   ret = -ENOMEM;
-   m = mpi_read_raw_from_sgl(req->src, req->src_len);
-   if (!m)
-   goto err_free_s;
-
-   ret = _rsa_sign(pkey, s, m);
-   if (ret)
-   goto err_free_m;
-
-   ret = mpi_write_to_sgl(s, req->dst, req->dst_len, );
-   if (ret)
-   goto err_free_m;
-
-   if (sign < 0)
-   ret = -EBADMSG;
-
-err_free_m:
-   mpi_free(m);
-err_free_s:
-   mpi_free(s);
-   return ret;
-}
-
-static int rsa_verify(struct akcipher_request *req)
-{
-   struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
-   const struct rsa_mpi_key *pkey = rsa_get_key(tfm);
-   MPI s, m = mpi_alloc(0);
-   int ret = 0;
-   int sign;
-
-   if (!m)
-   return -ENOMEM;
-
-   if (unlikely(!pkey->n || !pkey->e)) {
-   ret = -EINVAL;
-   goto err_free_m;
-   }
-
-   s = mpi_read_raw_from_sgl(req->src, req->src_len);
-   if (!s) {
-   ret = -ENOMEM;
-   goto err_free_m;
-   }
-
-   ret = _rsa_verify(pkey, m, s);
-   if (ret)
-   goto err_free_s;
-
-   ret = mpi_write_to_sgl(m, req->dst, req->dst_len, );
-   if (ret)
-   goto err_free_s;
-
-   if (sign < 0)
-   ret = -EBADMSG;
-
-err_free_s:
-   mpi_free(s);
-err_free_m:
-   mpi_free(m)

[PATCH v5 02/10] crypto: akcipher - check the presence of callback before the call

2019-02-23 Thread Vitaly Chikunov
Because with introduction of EC-RDSA and change in workings of RSA in
regard to sign/verify, akcipher could have not all callbacks defined,
check the presence of callbacks before calling them to increase
robustness.

Signed-off-by: Vitaly Chikunov 
---
 include/crypto/akcipher.h | 25 -
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/include/crypto/akcipher.h b/include/crypto/akcipher.h
index 2d690494568c..f537fad1989f 100644
--- a/include/crypto/akcipher.h
+++ b/include/crypto/akcipher.h
@@ -268,7 +268,10 @@ static inline unsigned int crypto_akcipher_maxsize(struct 
crypto_akcipher *tfm)
 {
struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
 
-   return alg->max_size(tfm);
+   if (alg->max_size)
+   return alg->max_size(tfm);
+   else
+   return 0;
 }
 
 /**
@@ -287,10 +290,11 @@ static inline int crypto_akcipher_encrypt(struct 
akcipher_request *req)
struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
struct crypto_alg *calg = tfm->base.__crt_alg;
unsigned int src_len = req->src_len;
-   int ret;
+   int ret = -ENOSYS;
 
crypto_stats_get(calg);
-   ret = alg->encrypt(req);
+   if (alg->encrypt)
+   ret = alg->encrypt(req);
crypto_stats_akcipher_encrypt(src_len, ret, calg);
return ret;
 }
@@ -311,10 +315,11 @@ static inline int crypto_akcipher_decrypt(struct 
akcipher_request *req)
struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
struct crypto_alg *calg = tfm->base.__crt_alg;
unsigned int src_len = req->src_len;
-   int ret;
+   int ret = -ENOSYS;
 
crypto_stats_get(calg);
-   ret = alg->decrypt(req);
+   if (alg->decrypt)
+   ret = alg->decrypt(req);
crypto_stats_akcipher_decrypt(src_len, ret, calg);
return ret;
 }
@@ -334,10 +339,11 @@ static inline int crypto_akcipher_sign(struct 
akcipher_request *req)
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
struct crypto_alg *calg = tfm->base.__crt_alg;
-   int ret;
+   int ret = -ENOSYS;
 
crypto_stats_get(calg);
-   ret = alg->sign(req);
+   if (alg->sign)
+   ret = alg->sign(req);
crypto_stats_akcipher_sign(ret, calg);
return ret;
 }
@@ -357,10 +363,11 @@ static inline int crypto_akcipher_verify(struct 
akcipher_request *req)
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
struct crypto_alg *calg = tfm->base.__crt_alg;
-   int ret;
+   int ret = -ENOSYS;
 
crypto_stats_get(calg);
-   ret = alg->verify(req);
+   if (alg->verify)
+   ret = alg->verify(req);
crypto_stats_akcipher_verify(ret, calg);
return ret;
 }
-- 
2.11.0



[PATCH v5 06/10] crypto: Kconfig - create Public-key cryptography section

2019-02-23 Thread Vitaly Chikunov
Group RSA, DH, and ECDH into Public-key cryptography config section.

Signed-off-by: Vitaly Chikunov 
---
 crypto/Kconfig | 48 +---
 1 file changed, 25 insertions(+), 23 deletions(-)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index bbab6bf33519..370cbdca87a7 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -113,29 +113,6 @@ config CRYPTO_ACOMP
select CRYPTO_ALGAPI
select CRYPTO_ACOMP2
 
-config CRYPTO_RSA
-   tristate "RSA algorithm"
-   select CRYPTO_AKCIPHER
-   select CRYPTO_MANAGER
-   select MPILIB
-   select ASN1
-   help
- Generic implementation of the RSA public key algorithm.
-
-config CRYPTO_DH
-   tristate "Diffie-Hellman algorithm"
-   select CRYPTO_KPP
-   select MPILIB
-   help
- Generic implementation of the Diffie-Hellman algorithm.
-
-config CRYPTO_ECDH
-   tristate "ECDH algorithm"
-   select CRYPTO_KPP
-   select CRYPTO_RNG_DEFAULT
-   help
- Generic implementation of the ECDH algorithm
-
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
@@ -253,6 +230,31 @@ config CRYPTO_GLUE_HELPER_X86
 config CRYPTO_ENGINE
tristate
 
+comment "Public-key cryptography"
+
+config CRYPTO_RSA
+   tristate "RSA algorithm"
+   select CRYPTO_AKCIPHER
+   select CRYPTO_MANAGER
+   select MPILIB
+   select ASN1
+   help
+ Generic implementation of the RSA public key algorithm.
+
+config CRYPTO_DH
+   tristate "Diffie-Hellman algorithm"
+   select CRYPTO_KPP
+   select MPILIB
+   help
+ Generic implementation of the Diffie-Hellman algorithm.
+
+config CRYPTO_ECDH
+   tristate "ECDH algorithm"
+   select CRYPTO_KPP
+   select CRYPTO_RNG_DEFAULT
+   help
+ Generic implementation of the ECDH algorithm
+
 comment "Authenticated Encryption with Associated Data"
 
 config CRYPTO_CCM
-- 
2.11.0



[PATCH v5 01/10] KEYS: report to keyctl only actually supported key ops

2019-02-23 Thread Vitaly Chikunov
Because with the introduction of EC-RDSA and change in workings of RSA
in regard to sign/verify, akcipher may have not all callbacks defined,
report to keyctl only actually supported ops determined by the presence
of the akcipher callbacks.

Cc: David Howells 
Cc: keyri...@vger.kernel.org
Signed-off-by: Vitaly Chikunov 
---
 crypto/asymmetric_keys/public_key.c | 16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index f5d85b47fcc6..c2e4e73fcf06 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -130,11 +130,17 @@ static int software_key_query(const struct 
kernel_pkey_params *params,
info->max_sig_size = len;
info->max_enc_size = len;
info->max_dec_size = len;
-   info->supported_ops = (KEYCTL_SUPPORTS_ENCRYPT |
-  KEYCTL_SUPPORTS_VERIFY);
-   if (pkey->key_is_private)
-   info->supported_ops |= (KEYCTL_SUPPORTS_DECRYPT |
-   KEYCTL_SUPPORTS_SIGN);
+   info->supported_ops = 0;
+   if (crypto_akcipher_alg(tfm)->verify)
+   info->supported_ops |= KEYCTL_SUPPORTS_VERIFY;
+   if (crypto_akcipher_alg(tfm)->encrypt)
+   info->supported_ops |= KEYCTL_SUPPORTS_ENCRYPT;
+   if (pkey->key_is_private) {
+   if (crypto_akcipher_alg(tfm)->decrypt)
+   info->supported_ops |= KEYCTL_SUPPORTS_DECRYPT;
+   if (crypto_akcipher_alg(tfm)->sign)
+   info->supported_ops |= KEYCTL_SUPPORTS_SIGN;
+   }
ret = 0;
 
 error_free_tfm:
-- 
2.11.0



Re: [RFC PATCH 1/4] X.509: Parse public key parameters from x509 for akcipher

2019-02-10 Thread Vitaly Chikunov
On Sun, Feb 10, 2019 at 12:42:40AM +0300, Vitaly Chikunov wrote:
> On Sun, Jan 06, 2019 at 04:36:05PM +0300, Vitaly Chikunov wrote:
> > Some public key algorithms (like ECDSA) keep in parameters field
> > important data such as digest and curve OIDs (possibly more for
> > different ECDSA variants). Thus, just setting a public key (as
> > for RSA) is not enough.
> > 
> > Introduce set_params() callback for akcipher which will be used to
> > pass DER encoded parameters array, with additional argument of
> > algorithm OID.
> > 
> > This is done with the intent of adding support for EC-RDSA (ISO/IEC
> > 14888-3:2018, RFC 7091, and basically ECDSA variant) public keys (which
> > will be finally used in IMA subsystem). Thus, also oid_registry.h is
> > updated.
> > 
> > Rationale:
> > 
> > - For such keys just setting public key without parameters is
> >   meaningless, so it would be possible to add parameters in
> >   crypto_akcipher_set_pub_key (and .set_pub_key) calls. But, this will
> >   needlessly change API for RSA akcipher. Also, additional callback
> >   making it possible to pass parameters after
> >   crypto_akcipher_set_priv_key (and .set_priv_key) in the future.
> >
> > - Algorithm OID is passed to be validated in .set_params callback,
> >   otherwise, it could have the wrong value.
> > 
> > - Particular algorithm OIDs are checked in x509_note_params, (because
> >   this is called from AlgorithmIdentifier (ASN.1) parser, which is
> >   called multiple times, as it's used multiple times in X.509
> >   certificate), to distinguish a public key call from a signature call.
> > 
> > Signed-off-by: Vitaly Chikunov 
> > ---
> 
> > @@ -263,6 +274,11 @@ int public_key_verify_signature(const struct 
> > public_key *pkey,
> >if (pkey->key_is_private)
> >ret = crypto_akcipher_set_priv_key(tfm,
> >   pkey->key, pkey->keylen);
> >else
> >ret = crypto_akcipher_set_pub_key(tfm,
> >  pkey->key, pkey->keylen);
> >if (ret)
> >goto error_free_req;
> > +   ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
> > +pkey->paramlen);
> 
> Nobody said anything if this is a good idea to call set_params after
> set_{pub,priv}_key and not before.
> 
> When `struct crypto_akcipher' is allocated ctx data is never zeroed,
> thus either call will be the first to zero ctx, making these calls not
> swappable in the future.
> 
> Also, algorithm parameters could be interpreted without knowing the key,
> but the key cannot be interpreted without knowing the parameters.

>From the other point of view, set_params may never be called or
implemented. So, making it called first and move memory zeroing
into set_params may create more complications than simplicity.

Making both callbacks callable in any order also will not make
things simpler. (Need to be prepared to be called in different
order.)

Maybe it's better to make memzero in akcipher_request_alloc() and allow
optional call to crypto_akcipher_set_params() strictly before
crypto_akcipher_set_{pub,priv}_key(), so, set_{pub,priv}_key will
already know everything to set the key properly. set_params may not be
implemented if akcipher does not need it (as with RSA).

> 
> > +   if (ret)
> > +   goto error_free_req;
> > +
> > ret = -ENOMEM;
> > outlen = crypto_akcipher_maxsize(tfm);
> > output = kmalloc(outlen, GFP_KERNEL);


Re: [RFC PATCH 1/4] X.509: Parse public key parameters from x509 for akcipher

2019-02-09 Thread Vitaly Chikunov
On Sun, Jan 06, 2019 at 04:36:05PM +0300, Vitaly Chikunov wrote:
> Some public key algorithms (like ECDSA) keep in parameters field
> important data such as digest and curve OIDs (possibly more for
> different ECDSA variants). Thus, just setting a public key (as
> for RSA) is not enough.
> 
> Introduce set_params() callback for akcipher which will be used to
> pass DER encoded parameters array, with additional argument of
> algorithm OID.
> 
> This is done with the intent of adding support for EC-RDSA (ISO/IEC
> 14888-3:2018, RFC 7091, and basically ECDSA variant) public keys (which
> will be finally used in IMA subsystem). Thus, also oid_registry.h is
> updated.
> 
> Rationale:
> 
> - For such keys just setting public key without parameters is
>   meaningless, so it would be possible to add parameters in
>   crypto_akcipher_set_pub_key (and .set_pub_key) calls. But, this will
>   needlessly change API for RSA akcipher. Also, additional callback
>   making it possible to pass parameters after
>   crypto_akcipher_set_priv_key (and .set_priv_key) in the future.
>
> - Algorithm OID is passed to be validated in .set_params callback,
>   otherwise, it could have the wrong value.
> 
> - Particular algorithm OIDs are checked in x509_note_params, (because
>   this is called from AlgorithmIdentifier (ASN.1) parser, which is
>   called multiple times, as it's used multiple times in X.509
>   certificate), to distinguish a public key call from a signature call.
> 
> Signed-off-by: Vitaly Chikunov 
> ---

> @@ -263,6 +274,11 @@ int public_key_verify_signature(const struct public_key 
> *pkey,
>if (pkey->key_is_private)
>ret = crypto_akcipher_set_priv_key(tfm,
>   pkey->key, pkey->keylen);
>else
>ret = crypto_akcipher_set_pub_key(tfm,
>  pkey->key, pkey->keylen);
>if (ret)
>goto error_free_req;
> + ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
> +  pkey->paramlen);

Nobody said anything if this is a good idea to call set_params after
set_{pub,priv}_key and not before.

When `struct crypto_akcipher' is allocated ctx data is never zeroed,
thus either call will be the first to zero ctx, making these calls not
swappable in the future.

Also, algorithm parameters could be interpreted without knowing the key,
but the key cannot be interpreted without knowing the parameters.

> + if (ret)
> + goto error_free_req;
> +
>   ret = -ENOMEM;
>   outlen = crypto_akcipher_maxsize(tfm);
>   output = kmalloc(outlen, GFP_KERNEL);


Re: [RFC PATCH v4] akcipher: new verify API for public key algorithms

2019-02-04 Thread Vitaly Chikunov
Herbert,

On Fri, Feb 01, 2019 at 10:09:23AM +0300, Vitaly Chikunov wrote:
> On Fri, Feb 01, 2019 at 02:26:55PM +0800, Herbert Xu wrote:
> > On Fri, Jan 25, 2019 at 09:01:16PM +0300, Vitaly Chikunov wrote:
> > >
> > > @@ -781,36 +780,17 @@ static int tpm_key_verify_signature(const struct 
> > > key *key,
> > >   if (!req)
> > >   goto error_free_tfm;
> > >  
> > > - ret = -ENOMEM;
> > > - outlen = crypto_akcipher_maxsize(tfm);
> > > - output = kmalloc(outlen, GFP_KERNEL);
> > > - if (!output)
> > > - goto error_free_req;
> > > -
> > > - sg_init_one(_sg, sig->s, sig->s_size);
> > > - sg_init_one(_sg, output, outlen);
> > > - akcipher_request_set_crypt(req, _sg, _sg, sig->s_size,
> > > -outlen);
> > > + sg_init_table(_sg, 2);
> > > + sg_set_buf(_sg[0], sig->s, sig->s_size);
> > > + sg_set_buf(_sg[1], sig->digest, sig->digest_size);
> > > + akcipher_request_set_crypt(req, _sg, NULL, sig->s_size,
> > > +sig->digest_size);
> > 
> > It's not clear that sig->digest is guaranteed to be kmalloc memory.
> > In any case, it's best not to mix unrelated changes in a single
> > patch.  So please keep the kmalloc on output and then copy
> > sig->digest into it and put output into the SG list.

I will do that.

Thanks,

> It is not guaranteed that sig->s will be kmalloc memory either. (Except
> we know it for sure like we know the same about sig->digest).
> 
> You can see in public_key_signature_free() that both fields are kfree'd
> together.
> 
> So, I don't understand why we should treat sig->digest differently than
> sig->s.
> 
> I was just removing kmalloc'ed output as crypto_akcipher_verify() does
> not need any output anymore. So, it's not some sort of mixing unrelated
> changes, from my point of view.
> 
> Thanks,
> 
> > 
> > Thanks,
> > -- 
> > Email: Herbert Xu 
> > Home Page: http://gondor.apana.org.au/~herbert/
> > PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [RFC PATCH v4] akcipher: new verify API for public key algorithms

2019-01-31 Thread Vitaly Chikunov
Herbert,

On Fri, Feb 01, 2019 at 02:26:55PM +0800, Herbert Xu wrote:
> On Fri, Jan 25, 2019 at 09:01:16PM +0300, Vitaly Chikunov wrote:
> >
> > @@ -781,36 +780,17 @@ static int tpm_key_verify_signature(const struct key 
> > *key,
> > if (!req)
> > goto error_free_tfm;
> >  
> > -   ret = -ENOMEM;
> > -   outlen = crypto_akcipher_maxsize(tfm);
> > -   output = kmalloc(outlen, GFP_KERNEL);
> > -   if (!output)
> > -   goto error_free_req;
> > -
> > -   sg_init_one(_sg, sig->s, sig->s_size);
> > -   sg_init_one(_sg, output, outlen);
> > -   akcipher_request_set_crypt(req, _sg, _sg, sig->s_size,
> > -  outlen);
> > +   sg_init_table(_sg, 2);
> > +   sg_set_buf(_sg[0], sig->s, sig->s_size);
> > +   sg_set_buf(_sg[1], sig->digest, sig->digest_size);
> > +   akcipher_request_set_crypt(req, _sg, NULL, sig->s_size,
> > +  sig->digest_size);
> 
> It's not clear that sig->digest is guaranteed to be kmalloc memory.
> In any case, it's best not to mix unrelated changes in a single
> patch.  So please keep the kmalloc on output and then copy
> sig->digest into it and put output into the SG list.

It is not guaranteed that sig->s will be kmalloc memory either. (Except
we know it for sure like we know the same about sig->digest).

You can see in public_key_signature_free() that both fields are kfree'd
together.

So, I don't understand why we should treat sig->digest differently than
sig->s.

I was just removing kmalloc'ed output as crypto_akcipher_verify() does
not need any output anymore. So, it's not some sort of mixing unrelated
changes, from my point of view.

Thanks,

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


[RFC PATCH v4] akcipher: new verify API for public key algorithms

2019-01-25 Thread Vitaly Chikunov
API is reworked following suggestions of Herbert Xu.

Previous akcipher .verify() just `decrypts' (using RSA encrypt which is
using public key) signature to uncover message hash, which was then
compared in upper level public_key_verify_signature() with the expected
hash value, which itself was never passed into verify().

This approach was incompatible with EC-DSA family of algorithms,
because, to verify a signature EC-DSA algorithm also needs a hash value
as input; then it's used (together with a signature divided into halves
`r||s') to produce a witness value, which is then compared with `r' to
determine if the signature is correct. Thus, for EC-DSA, nor
requirements of .verify() itself, nor its output expectations in
public_key_verify_signature() wasn't sufficient.

Make improved .verify() call which gets a signature together with a hash
value as input and produce complete signature check without any output
besides status.

RSA backends should not have sign/verify callbacks defined (nor they
should be used directly). PKCS1 driver knows to call appropriate RSA
encrypt/decrypt callbacks to implement sign/verify.

Now for the top level verification only crypto_akcipher_verify() needs
to be called.

Tested on x86_64.

Signed-off-by: Vitaly Chikunov 
---
This should be applied over cryptodev tree.

Changes since v3:
- remove verify_rsa API from RSA backends.
- digest is appended to akcipher_request->src SG.
- pkcs1pad calls encrypt/decrypt for its backends instead of sign/verify.
- pkcs1pad now conform to the new verify API.
- make crypto_akcipher_{maxsize,sign,verify} more robust allowing
  appropriate akcipher clllbacks to be undefined.

Changes since v2:
- `output` is factored out from public_key_verify_signature() into
  crypto_akcipher_verify().
- in crypto_akcipher_verify_rsa() -ENOSYS error is added for robustness (if,
  in the future, some RSA driver will not implement this api).
- api descriptions are updated to be more clear.

Changes since v1:
- complete rework to the different approach and should be treated as
  a new patch.

 crypto/asymmetric_keys/asym_tpm.c |  32 ++--
 crypto/asymmetric_keys/public_key.c   |  33 ++--
 crypto/rsa-pkcs1pad.c |  31 +---
 crypto/rsa.c  | 109 --
 crypto/testmgr.c  |  47 ++-
 drivers/crypto/caam/caampkc.c |   2 -
 drivers/crypto/ccp/ccp-crypto-rsa.c   |   2 -
 drivers/crypto/qat/qat_common/qat_asym_algs.c |   2 -
 include/crypto/akcipher.h |  53 +
 9 files changed, 94 insertions(+), 217 deletions(-)

diff --git a/crypto/asymmetric_keys/asym_tpm.c 
b/crypto/asymmetric_keys/asym_tpm.c
index 5d4c270463f6..eef548319877 100644
--- a/crypto/asymmetric_keys/asym_tpm.c
+++ b/crypto/asymmetric_keys/asym_tpm.c
@@ -744,11 +744,10 @@ static int tpm_key_verify_signature(const struct key *key,
struct crypto_wait cwait;
struct crypto_akcipher *tfm;
struct akcipher_request *req;
-   struct scatterlist sig_sg, digest_sg;
+   struct scatterlist src_sg[2];
char alg_name[CRYPTO_MAX_ALG_NAME];
uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
uint32_t der_pub_key_len;
-   void *output;
unsigned int outlen;
int ret;
 
@@ -781,36 +780,17 @@ static int tpm_key_verify_signature(const struct key *key,
if (!req)
goto error_free_tfm;
 
-   ret = -ENOMEM;
-   outlen = crypto_akcipher_maxsize(tfm);
-   output = kmalloc(outlen, GFP_KERNEL);
-   if (!output)
-   goto error_free_req;
-
-   sg_init_one(_sg, sig->s, sig->s_size);
-   sg_init_one(_sg, output, outlen);
-   akcipher_request_set_crypt(req, _sg, _sg, sig->s_size,
-  outlen);
+   sg_init_table(_sg, 2);
+   sg_set_buf(_sg[0], sig->s, sig->s_size);
+   sg_set_buf(_sg[1], sig->digest, sig->digest_size);
+   akcipher_request_set_crypt(req, _sg, NULL, sig->s_size,
+  sig->digest_size);
crypto_init_wait();
akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
  CRYPTO_TFM_REQ_MAY_SLEEP,
  crypto_req_done, );
-
-   /* Perform the verification calculation.  This doesn't actually do the
-* verification, but rather calculates the hash expected by the
-* signature and returns that to us.
-*/
ret = crypto_wait_req(crypto_akcipher_verify(req), );
-   if (ret)
-   goto out_free_output;
-
-   /* Do the actual verification step. */
-   if (req->dst_len != sig->digest_size ||
-   memcmp(sig->digest, output, sig->digest_size) != 0)
-   ret = -EKEYREJECTED;
 
-out_free_output:
-   kfree(output);
 error_free_req:
akciphe

Re: [RFC PATCH v3] akcipher: Introduce verify_rsa/verify for public key algorithms

2019-01-25 Thread Vitaly Chikunov
On Fri, Jan 25, 2019 at 06:09:29PM +0800, Herbert Xu wrote:
> On Fri, Jan 18, 2019 at 11:58:46PM +0300, Vitaly Chikunov wrote:
> > Previous akcipher .verify() just `decrypts' (using RSA encrypt which is
> > using public key) signature to uncover message hash, which was then
> > compared in upper level public_key_verify_signature() with the expected
> > hash value, which itself was never passed into verify().
> > 
> > This approach was incompatible with EC-DSA family of algorithms,
> > because, to verify a signature EC-DSA algorithm also needs a hash value
> > as input; then it's used (together with a signature divided into halves
> > `r||s') to produce a witness value, which is then compared with `r' to
> > determine if the signature is correct. Thus, for EC-DSA, nor
> > requirements of .verify() itself, nor its output expectations in
> > public_key_verify_signature() wasn't sufficient.
> > 
> > Make improved .verify() call which gets hash value as parameter and
> > produce complete signature check without any output besides status.
> > 
> > RSA-centric drivers have replaced verify() with verify_rsa() which
> > have old semantic and which they still should implement (if they want
> > pkcs1pad to work). If akcipher have .verify_rsa() callback, it will be
> > used for a partial verification, which then is finished in
> > crypto_akcipher_verify().
> > 
> > Now for the top level verification only crypto_akcipher_verify() needs
> > to be called.
> > 
> > For pkcs1pad crypto_akcipher_verify_rsa() is introduced which directly
> > calls .verify_rsa() for its backend. Without this api PKCS1 can not be
> > implemented.
> > 
> > Tested on x86_64.
> > 
> > Signed-off-by: Vitaly Chikunov 
> 
> Thanks for working on this!
> 
> We have been here before.  We changed the AEAD interface in a way
> that is not dissimilar to what you want to do here.
> 
> So I think the basic plan should be:

While time goes, I got another simpler idea how we should settle this:

1. Since we are know that by nature RSA sign/verify is just encrypt/decrypt,
and since sign/verify calls should not be used directly by any normal
users:
- Remove sign/verify calls from all existing RSA backends.

2. pkcs1pad should use encrypt/decrypt API for its low level purposes
(instead of sign/verify API, which now would be not implemented by them),
and provide sign (same as before) and new verify (returning only status).

Thus, we avoid verify_rsa call altogether while remaining its
functionality, and skipping conversion step.

> 1) Implement new top-level verify, alongside existing verify_rsa.
> 2) For existing drivers implement a wrapper over verify_rsa.
> 3) Convert *all* existing users to the new verify API.
> 4) Remove top-level verify_rsa API.
> 5) Convert existing drivers over to verify API.
> 6) Remove verify_rsa completely.
> 
> > +int crypto_akcipher_verify(struct akcipher_request *req,
> > +  const unsigned char *digest, unsigned int digest_len)
> 
> We should not add new fields outside of akcipher_request.  So
> these fields need to go inside it.  However, I think we don't
> actually need two new fields.  They could both go into the src
> scatterlist.  All we need is a new field, say textlen to indicate
> where the text stops and where the hash starts.  We could also
> overlay textlen over dstlen as it would now be unused for verify.

Well, if we allowed to reuse dst* fields why not just put digest over
dst scatterlist? That would be much simpler.

Thanks,


> The advantage of having it in one scatterlist is that for those
> users that already have the two pieces together could simply provide
> a single SG element (I don't know how likely that is in practice
> though).
> 
> For others you would simply tack on an extra SG element.
> 
> Thanks,
> -- 
> Email: Herbert Xu 
> Home Page: http://gondor.apana.org.au/~herbert/
> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


[RFC PATCH v3] akcipher: Introduce verify_rsa/verify for public key algorithms

2019-01-18 Thread Vitaly Chikunov
Previous akcipher .verify() just `decrypts' (using RSA encrypt which is
using public key) signature to uncover message hash, which was then
compared in upper level public_key_verify_signature() with the expected
hash value, which itself was never passed into verify().

This approach was incompatible with EC-DSA family of algorithms,
because, to verify a signature EC-DSA algorithm also needs a hash value
as input; then it's used (together with a signature divided into halves
`r||s') to produce a witness value, which is then compared with `r' to
determine if the signature is correct. Thus, for EC-DSA, nor
requirements of .verify() itself, nor its output expectations in
public_key_verify_signature() wasn't sufficient.

Make improved .verify() call which gets hash value as parameter and
produce complete signature check without any output besides status.

RSA-centric drivers have replaced verify() with verify_rsa() which
have old semantic and which they still should implement (if they want
pkcs1pad to work). If akcipher have .verify_rsa() callback, it will be
used for a partial verification, which then is finished in
crypto_akcipher_verify().

Now for the top level verification only crypto_akcipher_verify() needs
to be called.

For pkcs1pad crypto_akcipher_verify_rsa() is introduced which directly
calls .verify_rsa() for its backend. Without this api PKCS1 can not be
implemented.

Tested on x86_64.

Signed-off-by: Vitaly Chikunov 
---

This should be applied over cryptodev tree.

Changes since v2:
- `output` is factored out from public_key_verify_signature() into
  crypto_akcipher_verify().
- in crypto_akcipher_verify_rsa() -ENOSYS error is added for robustness (if,
  in the future, some RSA driver will not implement this api).
- api descriptions are updated to be more clear.

Changes since v1:
- complete rework to the different approach and should be treated as
  a new patch.

 crypto/akcipher.c | 60 +++
 crypto/asymmetric_keys/public_key.c   | 32 ++
 crypto/rsa-pkcs1pad.c |  4 +-
 crypto/rsa.c  |  2 +-
 crypto/testmgr.c  | 43 ++-
 drivers/crypto/caam/caampkc.c |  2 +-
 drivers/crypto/ccp/ccp-crypto-rsa.c   |  2 +-
 drivers/crypto/qat/qat_common/qat_asym_algs.c |  2 +-
 include/crypto/akcipher.h | 34 ++-
 9 files changed, 117 insertions(+), 64 deletions(-)

diff --git a/crypto/akcipher.c b/crypto/akcipher.c
index 0cbeae137e0a..95f207b2eb12 100644
--- a/crypto/akcipher.c
+++ b/crypto/akcipher.c
@@ -25,6 +25,66 @@
 #include 
 #include "internal.h"
 
+/**
+ * crypto_akcipher_verify() - Invoke public key signature verification
+ *
+ * Function invokes the specific public key signature verification operation
+ * for a given public key algorithm.
+ *
+ * @req:   asymmetric key request
+ * @digest:expected hash value
+ * @digest_len:hash length
+ *
+ * Return: zero on verification success; error code in case of error.
+ */
+int crypto_akcipher_verify(struct akcipher_request *req,
+  const unsigned char *digest, unsigned int digest_len)
+{
+   struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+   struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
+   struct crypto_alg *calg = tfm->base.__crt_alg;
+   int ret;
+
+   if (WARN_ON(!digest || !digest_len) ||
+   WARN_ON(req->dst || req->dst_len))
+   return -EINVAL;
+
+   crypto_stats_get(calg);
+   if (alg->verify_rsa) {
+   struct scatterlist output_sg;
+   void *output;
+   unsigned int outlen;
+
+   outlen = crypto_akcipher_maxsize(tfm);
+   ret = -EKEYREJECTED;
+   if (WARN_ON(outlen < digest_len))
+   goto out;
+   ret = -ENOMEM;
+   output = kmalloc(outlen, GFP_KERNEL);
+   if (!output)
+   goto out;
+   sg_init_one(_sg, output, outlen);
+   akcipher_request_set_crypt(req, req->src, _sg,
+  req->src_len, outlen);
+
+   /* Perform the verification calculation.  This doesn't actually
+* do the verification, but rather calculates the hash expected
+* by the signature and returns that to us.
+*/
+   ret = crypto_akcipher_verify_rsa(req);
+   if (!ret &&
+   (req->dst_len != digest_len ||
+memcmp(digest, output, digest_len)))
+   ret = -EKEYREJECTED;
+   kfree(output);
+   } else
+   ret = alg->verify(req, digest, digest_len);
+out:
+   crypto_stats_akcipher_verify(ret, calg);
+   return ret;
+}
+EXPORT_SYMBOL_GPL(crypto_a

Re: [RFC PATCH v2] akcipher: Introduce verify_rsa/verify for public key algorithms

2019-01-18 Thread Vitaly Chikunov
David,

On Wed, Jan 16, 2019 at 09:27:19PM +0300, Vitaly Chikunov wrote:
> On Wed, Jan 16, 2019 at 05:12:20PM +, David Howells wrote:
> > Umm...  What do I apply this patch to?
> 
> This should go over "crypto: testmgr - split akcipher tests by a key type"
> which I sent at 20190107 to linux-crypto. Sorry for the mess.
> 
> > In your modified public_key_verify_signature():
> > 
> > > - sg_init_one(_sg, output, outlen);
> > > - akcipher_request_set_crypt(req, _sg, _sg, sig->s_size,
> > > + sg_init_one(_sg, output, outlen);
> > > + akcipher_request_set_crypt(req, _sg, _sg, sig->s_size,
> > >  outlen);
> > 
> > Why is the output necessary?  It was there for the decoded hash to be placed
> > in prior to comparison - but now that's not necessary.
> 
> Agreed.

I prepared the patch which factors `output' into public_key_verify_signature().

Also, I try to elucidate my arguments below.

> > > - ret = crypto_wait_req(crypto_akcipher_verify(req), );
> > > + ret = crypto_wait_req(crypto_akcipher_verify(req, sig->digest,
> > > +  sig->digest_size), );
> > 
> > I see sig->digest is passed in here.  Should it be passed in in place of
> > output_sg above?

In short, it's passed as parameter to not clutter `struct
akcipher_request' and to distinguish it from encrypt/decrypt scatterlists.

New 'verify' op requires very different parameter set than encrypt,
decrypt, sign. This difference is now most illustrative in testmgr (see
in the next patch).

> (I tried different approaches such as passing additional arguments to
> `akcipher_request_set_crypt' or having additional setter like
> `akcipher_request_set_aux' just to set value of digest and that should
> be used just for verify op.)
> 
> I thought passing input parameter in `struct akcipher_request' in the
> field called 'dst' could be confusing for users. So this should be an
> additional parameter in the request which is never used by any other caller.
> Also, it was unknown if this should be scatterlist or not (I choose that
> it should not). When it's separate argument to crypto_akcipher_verify()
> call user is forced to set it, and there is no cluttering of `struct
> akcipher_request' (which is designed to handle just encryption/decryption)
> with not needed auxiliary parameters, and because it's very separated
> from request parameters which all scatterlists and all other calls
> arguments usually are not scatterlists, so this looked like similar
> approach to what others do.
> 
> > > - inst->alg.verify = pkcs1pad_verify;
> > > + inst->alg.verify_rsa = pkcs1pad_verify;
> > 
> > Is there a reason that pkcs1pad_verify() can't do the comparison?
> 
> If you agree that we have two callbacks for a full and a partial
> verification (I assume you do), why should pkcs1pad_verify do a full
> verification if it's allowed to do just partial one, and it's RSA
> cipher which have special partial verification designed for them.
> 
> So I decided that pkcs1pad_verify should implement verify_rsa api only
> and this is beneficial for having minimal code change and somewhat
> backward compatible.
> 
> > > - .verify = rsa_verify,
> > > + .verify_rsa = rsa_verify,
> > 
> > Likewise verify_rsa()?
> > 
> > Granted, this might involve pkcs1pad_verify() dressing up the signature in 
> > the
> > appropriate wrappings and passing it along to verify_rsa() to do the actual
> > comparison there (ie. what pkcs1pad_verify_complete() does).

a) RSA verify works differently (is it just disguised encrypt),
b) We have separate wrapper module for it (pkcs1pad). Thus:

Old API can not be removed. In other words, we can not replace
.verify_rsa with .verify in these drivers or PKCS1 will not work.

We can replace .verify_rsa with .verify in pkcs1pad, but there is no
need for that if we stay with two API calls, which we can't avoid.

> If we stay with the two api calls (verify and verify_rsa) pkcs1pad_verify
> does not need to do any verification leaving it to the akcipher core.
> 
> There is only potential "problem" that pkcs1pad code will not be able to
> use other akciphers besides rsa family (implementing only verify_rsa),
> but I assumed this is not needed (since only RSA is actually using
> PKCS1) and maybe even beneficial restriction.
> 
> > > - .verify = caam_rsa_enc,
> > > + .verify_rsa = caam_rsa_enc,
> > 
> > I presume this is the reason - because this reuses its encrypt operation
> > directly.  But could this instead perform the comparison upon completion, 
> > say
> > in rsa_pub_done()?

N

Re: [RFC PATCH v2] akcipher: Introduce verify_rsa/verify for public key algorithms

2019-01-16 Thread Vitaly Chikunov
David,

On Wed, Jan 16, 2019 at 05:12:20PM +, David Howells wrote:
> Umm...  What do I apply this patch to?

This should go over "crypto: testmgr - split akcipher tests by a key type"
which I sent at 20190107 to linux-crypto. Sorry for the mess.

> In your modified public_key_verify_signature():
> 
> > -   sg_init_one(_sg, output, outlen);
> > -   akcipher_request_set_crypt(req, _sg, _sg, sig->s_size,
> > +   sg_init_one(_sg, output, outlen);
> > +   akcipher_request_set_crypt(req, _sg, _sg, sig->s_size,
> >outlen);
> 
> Why is the output necessary?  It was there for the decoded hash to be placed
> in prior to comparison - but now that's not necessary.

Agreed.

> > -   ret = crypto_wait_req(crypto_akcipher_verify(req), );
> > +   ret = crypto_wait_req(crypto_akcipher_verify(req, sig->digest,
> > +sig->digest_size), );
> 
> I see sig->digest is passed in here.  Should it be passed in in place of
> output_sg above?

(I tried different approaches such as passing additional arguments to
`akcipher_request_set_crypt' or having additional setter like
`akcipher_request_set_aux' just to set value of digest and that should
be used just for verify op.)

I thought passing input parameter in `struct akcipher_request' in the
field called 'dst' could be confusing for users. So this should be an
additional parameter in the request which is never used by any other caller.
Also, it was unknown if this should be scatterlist or not (I choose that
it should not). When it's separate argument to crypto_akcipher_verify()
call user is forced to set it, and there is no cluttering of `struct
akcipher_request' (which is designed to handle just encryption/decryption)
with not needed auxiliary parameters, and because it's very separated
from request parameters which all scatterlists and all other calls
arguments usually are not scatterlists, so this looked like similar
approach to what others do.

> > -   inst->alg.verify = pkcs1pad_verify;
> > +   inst->alg.verify_rsa = pkcs1pad_verify;
> 
> Is there a reason that pkcs1pad_verify() can't do the comparison?

If you agree that we have two callbacks for a full and a partial
verification (I assume you do), why should pkcs1pad_verify do a full
verification if it's allowed to do just partial one, and it's RSA
cipher which have special partial verification designed for them.

So I decided that pkcs1pad_verify should implement verify_rsa api only
and this is beneficial for having minimal code change and somewhat
backward compatible.

> > -   .verify = rsa_verify,
> > +   .verify_rsa = rsa_verify,
> 
> Likewise verify_rsa()?
> 
> Granted, this might involve pkcs1pad_verify() dressing up the signature in the
> appropriate wrappings and passing it along to verify_rsa() to do the actual
> comparison there (ie. what pkcs1pad_verify_complete() does).

If we stay with the two api calls (verify and verify_rsa) pkcs1pad_verify
does not need to do any verification leaving it to the akcipher core.

There is only potential "problem" that pkcs1pad code will not be able to
use other akciphers besides rsa family (implementing only verify_rsa),
but I assumed this is not needed (since only RSA is actually using
PKCS1) and maybe even beneficial restriction.

> > -   .verify = caam_rsa_enc,
> > +   .verify_rsa = caam_rsa_enc,
> 
> I presume this is the reason - because this reuses its encrypt operation
> directly.  But could this instead perform the comparison upon completion, say
> in rsa_pub_done()?
> 
> > -   .verify = qat_rsa_enc,
> > +   .verify_rsa = qat_rsa_enc,
> 
> Again, this could do the comparison, say, in qat_rsa_cb().

Abandoning idea with two api calls (full verify and partial verify_rsa)
will require me to modify code for all these drivers for devices that I
don't have and can't test. So, I choose approach with less new code.

If you think that partial verify api should be completely removed that
change will require much bigger rework. Please tell if you would prefer
that.

Thanks,



[RFC PATCH v2] akcipher: Introduce verify_rsa/verify for public key algorithms

2019-01-16 Thread Vitaly Chikunov
To my opinion this new version may fit suggestions of Herbert and David - we 
only
have single general top level crypto_akcipher_verify() call, but two low level
 ->verify() and ->verify_rsa() calls. Final signature verification is moved from
each caller of crypto_akcipher_verify() into crypto_akcipher_verify() itself.

There is remained crypto_akcipher_verify_rsa() just for rsa specific (pkcs1)
code (it seems that we are isolating from calling directly ->verify_rsa()).

Does it looks good?

Original/new commit message:

Previous akcipher .verify() just `decrypts' (using RSA encrypt which is
using public key) signature to uncover message hash, which was then
compared in upper level public_key_verify_signature() with the expected
hash value, which itself was never passed into verify().

This approach was incompatible with EC-DSA family of algorithms,
because, to verify a signature EC-DSA algorithm also needs a hash value
as input; then it's used (together with a signature divided into halves
`r||s') to produce a witness value, which is then compared with `r' to
determine if the signature is correct. Thus, for EC-DSA, nor
requirements of .verify() itself, nor its output expectations in
public_key_verify_signature() wasn't satisfied.

Make improved .verify() call which gets hash value as parameter and
produce complete signature check (without any output besides status.

Other rsa-centric drivers have replaced verify() with verify_rsa() which
have old semantic. If akcipher have .verify_rsa() callback, it will be
used for a partial verification, which then is finished in
crypto_akcipher_verify().

Now for the top level verification only crypto_akcipher_verify() needs
to be called.

crypto_akcipher_verify_rsa() is introduced which directly calls
.verify_rsa() for use by PKCS1 driver to call its backend.

Signed-off-by: Vitaly Chikunov 
---
 crypto/akcipher.c | 53 +++
 crypto/asymmetric_keys/public_key.c   | 19 +++---
 crypto/rsa-pkcs1pad.c |  4 +-
 crypto/rsa.c  |  2 +-
 crypto/testmgr.c  |  5 ++-
 drivers/crypto/caam/caampkc.c |  2 +-
 drivers/crypto/ccp/ccp-crypto-rsa.c   |  2 +-
 drivers/crypto/qat/qat_common/qat_asym_algs.c |  2 +-
 include/crypto/akcipher.h | 21 +++
 9 files changed, 81 insertions(+), 29 deletions(-)

diff --git a/crypto/akcipher.c b/crypto/akcipher.c
index 0cbeae137e0a..2e247cbf5115 100644
--- a/crypto/akcipher.c
+++ b/crypto/akcipher.c
@@ -25,6 +25,59 @@
 #include 
 #include "internal.h"
 
+/**
+ * crypto_akcipher_verify() - Invoke public key signature verification
+ *
+ * Function invokes the specific public key signature verification operation
+ * for a given public key algorithm.
+ *
+ * @req:   asymmetric key request
+ * @digest:expected hash value
+ * @digest_len:hash length
+ *
+ * Return: zero on verification success; error code in case of error.
+ */
+int crypto_akcipher_verify(struct akcipher_request *req,
+  const unsigned char *digest, unsigned int digest_len)
+{
+   struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+   struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
+   struct crypto_alg *calg = tfm->base.__crt_alg;
+   int ret;
+
+   if (WARN_ON(!digest || !digest_len))
+   return -EINVAL;
+
+   crypto_stats_get(calg);
+   if (alg->verify_rsa) {
+   u8 output[HASH_MAX_DIGESTSIZE];
+
+   /* Perform the verification calculation.  This doesn't actually
+* do the verification, but rather calculates the hash expected
+* by the signature and returns that to us.
+*/
+   ret = crypto_akcipher_verify_rsa(req);
+   if (ret)
+   goto out;
+   if (req->dst_len != digest_len ||
+   WARN_ON(req->dst_len > sizeof(output))) {
+   ret = -EKEYREJECTED;
+   goto out;
+   }
+   sg_copy_to_buffer(req->dst,
+ sg_nents_for_len(req->dst, digest_len),
+ output, digest_len);
+   /* Do final verification step. */
+   if (memcmp(digest, output, digest_len))
+   ret = -EKEYREJECTED;
+   } else
+   ret = alg->verify(req, digest, digest_len);
+out:
+   crypto_stats_akcipher_verify(ret, calg);
+   return ret;
+}
+EXPORT_SYMBOL_GPL(crypto_akcipher_verify);
+
 #ifdef CONFIG_NET
 static int crypto_akcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
 {
diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index f5d85b47fcc6..1f86d22548f0 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/as

[PATCH] crypto: testmgr - split akcipher tests by a key type

2019-01-07 Thread Vitaly Chikunov
Before this, if akcipher_testvec have `public_key_vec' set to true
(i.e. having a public key) only sign/encrypt test is performed, but
verify/decrypt test is skipped.

With a public key we could do encrypt and verify, but to sign and decrypt
a private key is required.

This logic is correct for encrypt/decrypt tests (decrypt is skipped if
no private key). But incorrect for sign/verify tests - sign is performed
no matter if there is no private key, but verify is skipped if there is
a public key.

Rework `test_akcipher_one' to arrange tests properly depending on value
of `public_key_vec` and `siggen_sigver_test'.

No tests were missed since there is only one sign/verify test (which
have `siggen_sigver_test' set to true) and it has a private key, but
future tests could benefit from this improvement.

Signed-off-by: Vitaly Chikunov 
---
 crypto/testmgr.c | 86 +---
 1 file changed, 57 insertions(+), 29 deletions(-)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 0f684a414acb..1ce53f8058d2 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -2238,6 +2238,9 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
unsigned int out_len_max, out_len = 0;
int err = -ENOMEM;
struct scatterlist src, dst, src_tab[2];
+   const char *m, *c;
+   unsigned int m_size, c_size;
+   const char *op;
 
if (testmgr_alloc_buf(xbuf))
return err;
@@ -2259,46 +2262,72 @@ static int test_akcipher_one(struct crypto_akcipher 
*tfm,
 
err = -ENOMEM;
out_len_max = crypto_akcipher_maxsize(tfm);
+
+   /*
+* First run test which do not require a private key, such as
+* encrypt or verify.
+*/
outbuf_enc = kzalloc(out_len_max, GFP_KERNEL);
if (!outbuf_enc)
goto free_req;
 
-   if (WARN_ON(vecs->m_size > PAGE_SIZE))
-   goto free_all;
+   if (!vecs->siggen_sigver_test) {
+   m = vecs->m;
+   m_size = vecs->m_size;
+   c = vecs->c;
+   c_size = vecs->c_size;
+   op = "encrypt";
+   } else {
+   /* Swap args so we could keep plaintext (digest)
+* in vecs->m, and cooked signature in vecs->c.
+*/
+   m = vecs->c; /* signature */
+   m_size = vecs->c_size;
+   c = vecs->m; /* digest */
+   c_size = vecs->m_size;
+   op = "verify";
+   }
 
-   memcpy(xbuf[0], vecs->m, vecs->m_size);
+   if (WARN_ON(m_size > PAGE_SIZE))
+   goto free_all;
+   memcpy(xbuf[0], m, m_size);
 
sg_init_table(src_tab, 2);
sg_set_buf(_tab[0], xbuf[0], 8);
-   sg_set_buf(_tab[1], xbuf[0] + 8, vecs->m_size - 8);
+   sg_set_buf(_tab[1], xbuf[0] + 8, m_size - 8);
sg_init_one(, outbuf_enc, out_len_max);
-   akcipher_request_set_crypt(req, src_tab, , vecs->m_size,
+   akcipher_request_set_crypt(req, src_tab, , m_size,
   out_len_max);
akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
  crypto_req_done, );
 
err = crypto_wait_req(vecs->siggen_sigver_test ?
- /* Run asymmetric signature generation */
- crypto_akcipher_sign(req) :
+ /* Run asymmetric signature verification */
+ crypto_akcipher_verify(req) :
  /* Run asymmetric encrypt */
  crypto_akcipher_encrypt(req), );
if (err) {
-   pr_err("alg: akcipher: encrypt test failed. err %d\n", err);
+   pr_err("alg: akcipher: %s test failed. err %d\n", op, err);
goto free_all;
}
-   if (req->dst_len != vecs->c_size) {
-   pr_err("alg: akcipher: encrypt test failed. Invalid output 
len\n");
+   if (req->dst_len != c_size) {
+   pr_err("alg: akcipher: %s test failed. Invalid output len\n",
+  op);
err = -EINVAL;
goto free_all;
}
/* verify that encrypted message is equal to expected */
-   if (memcmp(vecs->c, outbuf_enc, vecs->c_size)) {
-   pr_err("alg: akcipher: encrypt test failed. Invalid output\n");
-   hexdump(outbuf_enc, vecs->c_size);
+   if (memcmp(c, outbuf_enc, c_size)) {
+   pr_err("alg: akcipher: %s test failed. Invalid output\n", op);
+   hexdump(outbuf_enc, c_size);
err = -EINVAL;
goto free_all;
}
-   /* Don't invoke decrypt for vectors with public key */
+
+   /*
+* Don't invoke (decrypt or si

Re: [RFC PATCH 4/4] crypto: Add EC-RDSA algorithm

2019-01-07 Thread Vitaly Chikunov
Stephan,

On Mon, Jan 07, 2019 at 09:31:40AM +0100, Stephan Mueller wrote:
> Am Montag, 7. Januar 2019, 09:07:10 CET schrieb Vitaly Chikunov:
> 
> > > Why do you manually parse the ASN.1 structure instead of using the ASN.1
> > > parser?
> > 
> > I am not sure this worth effort and will not be most degenerate use of
> > asn1_ber_decoder, since 1) I only need to parse one type in each case:
> > OCTET STRING string above code, and OIDs in below code; 2) this data is
> > said to be in DER format, which asn1_ber_decoder can not enforce. Surely
> > this will also produce more code and files.
> 
> RSA public keys also only contain n and e in the ASN.1 structure for which 
> the 
> ASN.1 parser is used (see linux/crypto/rsapubkey.asn1).

Yes I saw it, but at least there is two values (n and e), while EC-RDSA
pub_key is just one OCTET STRING value (which internally is not defined
to be ASN.1).

> As ASN.1 parsing is always having security issues, I would rather suggest to
> have this parsing implemented in one spot and not here and there.

Yes. So I tried to parse it very carefully and strictly.

> Regarding your comment (2), I am not sure I understand. Why do you say that 
> the DER format cannot be parsed by the kernel's ASN.1 parser? For example, 

It can, but DER is stricter than BER. For example, in DER 'OCTET STRING'
length field should be encoded in just one byte if it's smaller than
128, in BER it could be encoded in multiple encodings. This does not
seem like a big deal, though. With BER decoder an improperly DER-encoded
certificate could be successfully parsed.

> when you generate RSA keys in DER format with, say, openssl, the kernel ASN.1 
> parser will happily use them. Also, when I created my (not accepted) patch to 
> load PQG domain parameters for DH using the ASN.1 parser, the PQG domain 
> parameters created by openssl in DER format were processed well.
> 
> Ciao
> Stephan
> 


Re: [RFC PATCH 4/4] crypto: Add EC-RDSA algorithm

2019-01-07 Thread Vitaly Chikunov
Stephan,

On Sun, Jan 06, 2019 at 07:11:50PM +0100, Stephan Müller wrote:
> Am Sonntag, 6. Januar 2019, 14:36:08 CET schrieb Vitaly Chikunov:
> 
> > Add Elliptic Curve Russian Digital Signature Algorithm (GOST R
> > 34.10-2012, RFC 7091, ISO/IEC 14888-3) is one of the Russian (and since
> > 2018 the CIS countries) cryptographic standard algorithms (called GOST
> > algorithms). Only signature verification is supported, with intent to be
> > used in the IMA.
> 
> Do you happen to have test vectors for the testmgr?

Yes, I will add this.

> > +/* Parse DER encoded subjectPublicKey. */
> > +static int ecrdsa_set_pub_key(struct crypto_akcipher *tfm, const void *ber,
> > + unsigned int len)
> > +{
> > +   struct ecrdsa_ctx *ctx = akcipher_tfm_ctx(tfm);
> > +   unsigned int ndigits;
> > +   const u8 *k = ber;
> > +   unsigned int offset;
> > +
> > +   /* First chance to zero ctx */
> > +   memset(ctx, 0, sizeof(*ctx));
> > +
> > +   if (len < 3 ||
> > +   k[0] != 0x04 || /* OCTET STRING */
> > +   (k[1] < 0x80 && len != k[1] + 2) ||
> > +   (k[1] == 0x81 && len != k[2] + 3) ||
> > +   k[1] > 0x81)
> > +   return -EBADMSG;
> > +   offset = (k[1] < 0x80)? 2 : 3;
> > +   k += offset;
> > +   len -= offset;
> 
> Why do you manually parse the ASN.1 structure instead of using the ASN.1 
> parser?

I am not sure this worth effort and will not be most degenerate use of
asn1_ber_decoder, since 1) I only need to parse one type in each case:
OCTET STRING string above code, and OIDs in below code; 2) this data is
said to be in DER format, which asn1_ber_decoder can not enforce. Surely
this will also produce more code and files.

> > +/* Parse DER encoded SubjectPublicKeyInfo.AlgorithmIdentifier.parameters.
> > */ +static int ecrdsa_set_params(struct crypto_akcipher *tfm, enum OID
> > algo, +  const void *params, unsigned int paramlen)
> > +{
> > +   struct ecrdsa_ctx *ctx = akcipher_tfm_ctx(tfm);
> > +   const u8 *p = params;
> > +   int i;
> > +
> > +   if (algo == OID_gost2012PublicKey256) {
> > +   ctx->digest = "streebog256";
> > +   ctx->digest_oid = OID_gost2012Digest256;
> > +   ctx->digest_len = 256 / 8;
> > +   } else if (algo == OID_gost2012PublicKey512) {
> > +   ctx->digest = "streebog512";
> > +   ctx->digest_oid = OID_gost2012Digest512;
> > +   ctx->digest_len = 512 / 8;
> > +   } else
> > +   return -ENOPKG;
> > +   ctx->curve = NULL;
> > +   ctx->curve_oid = 0;
> > +   ctx->algo_oid = algo;
> > +
> > +   for (i = 0; i < paramlen; i += p[i + 1] + 2) {
> > +   const struct ecc_curve *curve;
> > +   enum OID oid;
> > +
> > +   if (paramlen - i < 2 ||
> > +   p[i] != 0x06 || /* OBJECT IDENTIFIER */
> 
> Same here and in the following
> 
> > +   p[i + 1] > paramlen - i - 2)
> > +   return -EBADMSG;
> > +   oid = look_up_OID(p + i + 2, p[i + 1]);

> > +MODULE_ALIAS_CRYPTO("ecrdsa");
> 
> I do not think you need that alias as the module name already will be named 
> this way. I guess you rather should add ecrdsa-generic as module alias.

Thanks!



[RFC PATCH 4/4] crypto: Add EC-RDSA algorithm

2019-01-06 Thread Vitaly Chikunov
Add Elliptic Curve Russian Digital Signature Algorithm (GOST R
34.10-2012, RFC 7091, ISO/IEC 14888-3) is one of the Russian (and since
2018 the CIS countries) cryptographic standard algorithms (called GOST
algorithms). Only signature verification is supported, with intent to be
used in the IMA.

Summary of the changes:

crypto/Kconfig:
- Public-key methods are moved to the new "Public-key cryptography"
  section;
- Where EC-RDSA is added.

crypto/Makefile:
- ecc.o is split into a separate module to use both by ecdh and ecrdsa.

crypto/asymmetric_keys/x509_cert_parser.c:
- Recognize EC-RDSA and Streebog OIDs.

include/linux/oid_registry.h:
- EC-RDSA OIDs are added to the enum. Also, a few currently not used
  curve OIDs are added for possible extension later (to not change
  numbering and grouping).

crypto/ecc.c:
- Kenneth MacKay copyright date is updated to 2014, because
  vli_mmod_slow, ecc_point_add, ecc_point_mult_shamir are based on his
  code from micro-ecc.
- Functions needed for ecrdsa are EXPORT_SYMBOL'ed.
- New functions:
  vli_is_negative - helper to determine sign of vli;
  vli_from_be64 - unpack big-endian array into vli (used for
a signature);
  vli_from_le64 - unpack little-endian array into vli (used for
a public key);
  vli_uadd, vli_usub - add/sub u64 value to/from vli (used for
increment/decrement);
  mul_64_64 - optimized to use __int128 where appropriate, this speeds
up point multiplication (and as a consequence signature
verification) by the factor of 1.5-2;
  vli_umult - multiply vli by a small value (speeds up point
multiplication by another factor of 1.5-2, depending on vli sizes);
  vli_mmod_special - module reduction for some form of Pseudo-Mersenne
primes (used for the curves A);
  vli_mmod_special2 - module reduction for another form of
Pseudo-Mersenne primes (used for the curves B);
  vli_mmod_barrett - module reduction using pre-computed value (used
for the curve C);
  vli_mmod_slow - more general module reduction which is much slower
   (used when the modulus is subgroup order);
  vli_mmod_fast - integrated non-strict heuristic to call optimal
module reduction function depending on the prime value;
  vli_mod_mult_slow - modular multiplication;
  ecc_point_add - add two points;
  ecc_point_mult_shamir - add two points multiplied by scalars in one
combined multiplication (this gives speed up by another factor 2 in
compare to two separate multiplications).

crypto/ecc.h:
- struct ecc_point and struct ecc_curve definitions are moved from
  ecc.c and slightly extended.
- All exported functions are documented.

crypto/ecrdsa.c:
- All five curves are defined locally since they are limited to use by
  EC-RDSA. (Possible by ECDH too, though.)
- Only signature verification is implemented.

Signed-off-by: Vitaly Chikunov 
---
 crypto/Kconfig|  63 ++--
 crypto/Makefile   |   5 +-
 crypto/asymmetric_keys/x509_cert_parser.c |  13 +
 crypto/ecc.c  | 421 +++--
 crypto/ecc.h  | 162 +-
 crypto/ecc_curve_defs.h   |  15 -
 crypto/ecrdsa.c   | 494 ++
 include/linux/oid_registry.h  |  12 +
 8 files changed, 1126 insertions(+), 59 deletions(-)
 create mode 100644 crypto/ecrdsa.c

diff --git a/crypto/Kconfig b/crypto/Kconfig
index b6376d5d973e..75783af857ce 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -113,29 +113,6 @@ config CRYPTO_ACOMP
select CRYPTO_ALGAPI
select CRYPTO_ACOMP2
 
-config CRYPTO_RSA
-   tristate "RSA algorithm"
-   select CRYPTO_AKCIPHER
-   select CRYPTO_MANAGER
-   select MPILIB
-   select ASN1
-   help
- Generic implementation of the RSA public key algorithm.
-
-config CRYPTO_DH
-   tristate "Diffie-Hellman algorithm"
-   select CRYPTO_KPP
-   select MPILIB
-   help
- Generic implementation of the Diffie-Hellman algorithm.
-
-config CRYPTO_ECDH
-   tristate "ECDH algorithm"
-   select CRYPTO_KPP
-   select CRYPTO_RNG_DEFAULT
-   help
- Generic implementation of the ECDH algorithm
-
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
@@ -243,6 +220,46 @@ config CRYPTO_GLUE_HELPER_X86
 config CRYPTO_ENGINE
tristate
 
+comment "Public-key cryptography"
+
+config CRYPTO_RSA
+   tristate "RSA algorithm"
+   select CRYPTO_AKCIPHER
+   select CRYPTO_MANAGER
+   select MPILIB
+   select ASN1
+   help
+ Generic implementation of the RSA public key algorithm.
+
+config CRYPTO_DH
+   tristate "Diffie-Hellman algorithm"
+   select CRYPTO_KPP
+   select MPILIB
+   help
+ Generic implementation of the Diffie-Hellman algorithm.
+

[RFC PATCH 3/4] KEYS: set correct flags for keyctl if encrypt is not supported

2019-01-06 Thread Vitaly Chikunov
Signed-off-by: Vitaly Chikunov 
---
 crypto/asymmetric_keys/public_key.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index 51dc1c858c7c..382cf67f510e 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -136,8 +136,9 @@ static int software_key_query(const struct 
kernel_pkey_params *params,
info->max_sig_size = len;
info->max_enc_size = len;
info->max_dec_size = len;
-   info->supported_ops = (KEYCTL_SUPPORTS_ENCRYPT |
-  KEYCTL_SUPPORTS_VERIFY);
+   info->supported_ops = KEYCTL_SUPPORTS_VERIFY;
+   if (crypto_akcipher_alg(tfm)->encrypt)
+   info->supported_ops |= KEYCTL_SUPPORTS_ENCRYPT;
if (pkey->key_is_private)
info->supported_ops |= (KEYCTL_SUPPORTS_DECRYPT |
KEYCTL_SUPPORTS_SIGN);
-- 
2.11.0



[RFC PATCH 0/4] crypto: Add EC-RDSA algorithm

2019-01-06 Thread Vitaly Chikunov
This patchset changes akcipher api to support ECDSA style signature
verification. Augments x509 parser to make it work with EC-RDSA certificates.
And finally implements EC-RDSA (GOST 34.10) signature verification.

It is intended to use in IMA for appraisal.

Tested on x86_64 with openssl+gost-engine generated certificates.

Vitaly Chikunov (4):
  X.509: Parse public key parameters from x509 for akcipher
  akcipher: Introduce verify2 for public key algorithms
  KEYS: set correct flags for keyctl if encrypt is not supported
  crypto: Add EC-RDSA algorithm

 crypto/Kconfig|  63 ++--
 crypto/Makefile   |   5 +-
 crypto/asymmetric_keys/public_key.c   |  74 +++--
 crypto/asymmetric_keys/x509.asn1  |   2 +-
 crypto/asymmetric_keys/x509_cert_parser.c |  51 ++-
 crypto/ecc.c  | 421 +++--
 crypto/ecc.h  | 162 +-
 crypto/ecc_curve_defs.h   |  15 -
 crypto/ecrdsa.c   | 494 ++
 crypto/testmgr.c  |   5 +
 crypto/testmgr.h  |   3 +
 include/crypto/akcipher.h |  87 +-
 include/crypto/public_key.h   |   4 +
 include/linux/oid_registry.h  |  18 ++
 14 files changed, 1319 insertions(+), 85 deletions(-)
 create mode 100644 crypto/ecrdsa.c

-- 
2.11.0



[RFC PATCH 1/4] X.509: Parse public key parameters from x509 for akcipher

2019-01-06 Thread Vitaly Chikunov
Some public key algorithms (like ECDSA) keep in parameters field
important data such as digest and curve OIDs (possibly more for
different ECDSA variants). Thus, just setting a public key (as
for RSA) is not enough.

Introduce set_params() callback for akcipher which will be used to
pass DER encoded parameters array, with additional argument of
algorithm OID.

This is done with the intent of adding support for EC-RDSA (ISO/IEC
14888-3:2018, RFC 7091, and basically ECDSA variant) public keys (which
will be finally used in IMA subsystem). Thus, also oid_registry.h is
updated.

Rationale:

- For such keys just setting public key without parameters is
  meaningless, so it would be possible to add parameters in
  crypto_akcipher_set_pub_key (and .set_pub_key) calls. But, this will
  needlessly change API for RSA akcipher. Also, additional callback
  making it possible to pass parameters after
  crypto_akcipher_set_priv_key (and .set_priv_key) in the future.

- Algorithm OID is passed to be validated in .set_params callback,
  otherwise, it could have the wrong value.

- Particular algorithm OIDs are checked in x509_note_params, (because
  this is called from AlgorithmIdentifier (ASN.1) parser, which is
  called multiple times, as it's used multiple times in X.509
  certificate), to distinguish a public key call from a signature call.

Signed-off-by: Vitaly Chikunov 
---
 crypto/asymmetric_keys/public_key.c   | 16 +
 crypto/asymmetric_keys/x509.asn1  |  2 +-
 crypto/asymmetric_keys/x509_cert_parser.c | 38 ---
 crypto/testmgr.c  |  5 
 crypto/testmgr.h  |  3 +++
 include/crypto/akcipher.h | 33 +++
 include/crypto/public_key.h   |  4 
 include/linux/oid_registry.h  |  6 +
 8 files changed, 103 insertions(+), 4 deletions(-)

diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index f5d85b47fcc6..3bc090b8adef 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -45,6 +45,7 @@ void public_key_free(struct public_key *key)
 {
if (key) {
kfree(key->key);
+   kfree(key->params);
kfree(key);
}
 }
@@ -124,6 +125,11 @@ static int software_key_query(const struct 
kernel_pkey_params *params,
if (ret < 0)
goto error_free_tfm;
 
+   ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
+pkey->paramlen);
+   if (ret)
+   goto error_free_tfm;
+
len = crypto_akcipher_maxsize(tfm);
info->key_size = len * 8;
info->max_data_size = len;
@@ -182,6 +188,11 @@ static int software_key_eds_op(struct kernel_pkey_params 
*params,
if (ret)
goto error_free_req;
 
+   ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
+pkey->paramlen);
+   if (ret)
+   goto error_free_req;
+
sg_init_one(_sg, in, params->in_len);
sg_init_one(_sg, out, params->out_len);
akcipher_request_set_crypt(req, _sg, _sg, params->in_len,
@@ -263,6 +274,11 @@ int public_key_verify_signature(const struct public_key 
*pkey,
if (ret)
goto error_free_req;
 
+   ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
+pkey->paramlen);
+   if (ret)
+   goto error_free_req;
+
ret = -ENOMEM;
outlen = crypto_akcipher_maxsize(tfm);
output = kmalloc(outlen, GFP_KERNEL);
diff --git a/crypto/asymmetric_keys/x509.asn1 b/crypto/asymmetric_keys/x509.asn1
index aae0cde414e2..5c9f4e4a5231 100644
--- a/crypto/asymmetric_keys/x509.asn1
+++ b/crypto/asymmetric_keys/x509.asn1
@@ -22,7 +22,7 @@ CertificateSerialNumber ::= INTEGER
 
 AlgorithmIdentifier ::= SEQUENCE {
algorithm   OBJECT IDENTIFIER ({ x509_note_OID }),
-   parameters  ANY OPTIONAL
+   parameters  ANY OPTIONAL ({ x509_note_params })
 }
 
 Name ::= SEQUENCE OF RelativeDistinguishedName
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c 
b/crypto/asymmetric_keys/x509_cert_parser.c
index 991f4d735a4e..202a9dc66c93 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -26,6 +26,9 @@ struct x509_parse_context {
const void  *cert_start;/* Start of cert content */
const void  *key;   /* Key data */
size_t  key_size;   /* Size of key data */
+   const void  *params;/* Key parameters */
+   size_t  params_size;/* Size of key parameters */
+   enum OIDkey_algo;   /* Publi

[RFC PATCH 2/4] akcipher: Introduce verify2 for public key algorithms

2019-01-06 Thread Vitaly Chikunov
Current akcipher .verify() just decrypts signature to uncover message
hash, which is then verified in upper level public_key_verify_signature
by memcmp with the expected signature value, which is never passed into
verify().

This approach is incompatible with ECDSA algorithms, because, to verify
a signature ECDSA algorithm also needs a hash value as input; also, hash
is used in ECDSA (together with a signature divided into halves `r||s`),
not to produce hash, but to produce a number, which is then compared to
`r` (first part of the signature) to determine if the signature is
correct.  Thus, for ECDSA, nor requirements of .verify() itself, nor its
output expectations in public_key_verify_signature aren't satisfied.

Make alternative .verify2() call which gets hash value and produce
complete signature check (without any output, thus max_size() call will
not be needed for verify2() operation).

If .verify2() call is present, it should be used in place of .verify().

Signed-off-by: Vitaly Chikunov 
---
 crypto/asymmetric_keys/public_key.c | 57 -
 include/crypto/akcipher.h   | 54 +--
 2 files changed, 89 insertions(+), 22 deletions(-)

diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index 3bc090b8adef..51dc1c858c7c 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -242,6 +242,7 @@ int public_key_verify_signature(const struct public_key 
*pkey,
char alg_name[CRYPTO_MAX_ALG_NAME];
void *output;
unsigned int outlen;
+   int verify2;
int ret;
 
pr_devel("==>%s()\n", __func__);
@@ -279,14 +280,23 @@ int public_key_verify_signature(const struct public_key 
*pkey,
if (ret)
goto error_free_req;
 
-   ret = -ENOMEM;
-   outlen = crypto_akcipher_maxsize(tfm);
-   output = kmalloc(outlen, GFP_KERNEL);
-   if (!output)
-   goto error_free_req;
-
+   verify2 = crypto_akcipher_have_verify2(req);
+   if (!verify2) {
+   /* verify2 does not need output buffer */
+   ret = -ENOMEM;
+   outlen = crypto_akcipher_maxsize(tfm);
+   output = kmalloc(outlen, GFP_KERNEL);
+   if (!output)
+   goto error_free_req;
+
+   sg_init_one(_sg, output, outlen);
+   } else {
+   /* dummy init digest_sg */
+   memset(_sg, 0, sizeof(digest_sg));
+   output = NULL;
+   outlen = 0;
+   }
sg_init_one(_sg, sig->s, sig->s_size);
-   sg_init_one(_sg, output, outlen);
akcipher_request_set_crypt(req, _sg, _sg, sig->s_size,
   outlen);
crypto_init_wait();
@@ -294,18 +304,27 @@ int public_key_verify_signature(const struct public_key 
*pkey,
  CRYPTO_TFM_REQ_MAY_SLEEP,
  crypto_req_done, );
 
-   /* Perform the verification calculation.  This doesn't actually do the
-* verification, but rather calculates the hash expected by the
-* signature and returns that to us.
-*/
-   ret = crypto_wait_req(crypto_akcipher_verify(req), );
-   if (ret)
-   goto out_free_output;
-
-   /* Do the actual verification step. */
-   if (req->dst_len != sig->digest_size ||
-   memcmp(sig->digest, output, sig->digest_size) != 0)
-   ret = -EKEYREJECTED;
+   if (!verify2) {
+   /* Perform the verification calculation.  This doesn't actually
+* do the verification, but rather calculates the hash expected
+* by the signature and returns that to us.
+*/
+   ret = crypto_wait_req(crypto_akcipher_verify(req), );
+   if (ret)
+   goto out_free_output;
+
+   /* Do the actual verification step. */
+   if (req->dst_len != sig->digest_size ||
+   memcmp(sig->digest, output, sig->digest_size) != 0)
+   ret = -EKEYREJECTED;
+   } else {
+   /* Perform full verification in one call. */
+   req->digest = sig->digest;
+   req->digest_len = sig->digest_size;
+   ret = crypto_wait_req(crypto_akcipher_verify2(req), );
+   if (ret)
+   goto out_free_output;
+   }
 
 out_free_output:
kfree(output);
diff --git a/include/crypto/akcipher.h b/include/crypto/akcipher.h
index 84d68dfb551a..b15a995f6118 100644
--- a/include/crypto/akcipher.h
+++ b/include/crypto/akcipher.h
@@ -28,6 +28,8 @@
  * result.
  * In case of error where the dst sgl size was insufficient,
  * it will be updated to the size required for the operation.
+ * @digest:Dige

Re: [RFC PATCH] akcipher: Introduce verify2 for public key algorithms

2019-01-04 Thread Vitaly Chikunov
On Thu, Dec 13, 2018 at 06:12:33PM +0800, Herbert Xu wrote:
> Vitaly Chikunov  wrote:
> > Current akcipher .verify() just decrypts signature to uncover message
> > hash, which is then verified in upper level public_key_verify_signature
> > by memcmp with the expected signature value, which is never passed into
> > verify().
> > 
> > This approach is incompatible with ECDSA algorithms, because, to verify
> > a signature ECDSA algorithm also needs a hash value as input; also, hash
> > is used in ECDSA (together with a signature divided into halves `r||s`),
> > not to produce hash, but to produce a number, which is then compared to
> > `r` (first part of the signature) to determine if the signature is
> > correct.  Thus, for ECDSA, nor requirements of .verify() itself, nor its
> > output expectations in public_key_verify_signature aren't satisfied.
> > 
> > Make alternative .verify2() call which gets hash value and produce
> > complete signature check (without any output, thus max_size() call will
> > not be needed for verify2() operation).
> > 
> > If .verify2() call is present, it should be used in place of .verify().
> > 
> > Signed-off-by: Vitaly Chikunov 
> 
> We should convert all existing users to this interface and not
> have both verify/verify2 forever.

This will be hard to do since there is at least tree device that use
this interface (and who know how much out of tree):

  drivers$ git grep cra_name.*rsa
  crypto/caam/caampkc.c:  .cra_name = "rsa",
  crypto/ccp/ccp-crypto-rsa.c:.cra_name = "rsa",
  crypto/qat/qat_common/qat_asym_algs.c:  .cra_name = "rsa",

Interface seems to be designed that verify() call is interchangeable
with encrypt().

Two verify does not seem that bad since there is common code for the old
interface that removes code duplication and simplifies driver
implementation (RSA drivers only need to implement encrypt).

But, I would remove scatterlist from the new interface. Signature
verification is not some multi-block encryption. And basically,
public_key_verify_signature just doing sg_init_one for both required
src/dst buffers.

ps. And also, in the future, I would allow akcipher to access `struct
public_key` and `struct public_key_signature` so it could distinguish
when the key is already validated and skip expensive validation other
time verify2 is used with the same key. Or maybe flag 'key validation is
needed' should be maintained outside of akcipher and passed to it in the
request.

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


Re: [RFC PATCH] akcipher: Introduce verify2 for public key algorithms

2018-12-13 Thread Vitaly Chikunov
Tudor,

On Thu, Dec 13, 2018 at 10:26:53AM +, tudor.amba...@microchip.com wrote:
> 
> On 12/11/2018 06:59 PM, Vitaly Chikunov wrote:
> > Current akcipher .verify() just decrypts signature to uncover message
> > hash, which is then verified in upper level public_key_verify_signature
> > by memcmp with the expected signature value, which is never passed into
> > verify().
> > 
> > This approach is incompatible with ECDSA algorithms, because, to verify
> 
> I would love to have ECDSA in kernel but unfortunately it hasn't reached 
> kernel
> because there is no in-kernel user for it. Do we have an agreement that we 
> will
> add support for it? If not, who will benefit of these patches?

I will post patchset for EC-RDSA support (which is slightly different from
ECDSA, but is the same algorithm family). This is intended for use in IMA.

Even though EC-RDSA is different from ECDSA it will require the same changes
that I propose in these RFCs. Basically, after EC-RDSA is implemented and
hooked into IMA it will be much easier to implement ECDSA.

An additional use case is future possibility to implement other signature
schemes out of tree, which is currently not possible because API is very
RSA-centric.

Thanks,

> 
> Thanks,
> ta


[RFC PATCH] akcipher: Introduce verify2 for public key algorithms

2018-12-11 Thread Vitaly Chikunov
Current akcipher .verify() just decrypts signature to uncover message
hash, which is then verified in upper level public_key_verify_signature
by memcmp with the expected signature value, which is never passed into
verify().

This approach is incompatible with ECDSA algorithms, because, to verify
a signature ECDSA algorithm also needs a hash value as input; also, hash
is used in ECDSA (together with a signature divided into halves `r||s`),
not to produce hash, but to produce a number, which is then compared to
`r` (first part of the signature) to determine if the signature is
correct.  Thus, for ECDSA, nor requirements of .verify() itself, nor its
output expectations in public_key_verify_signature aren't satisfied.

Make alternative .verify2() call which gets hash value and produce
complete signature check (without any output, thus max_size() call will
not be needed for verify2() operation).

If .verify2() call is present, it should be used in place of .verify().

Signed-off-by: Vitaly Chikunov 
---
 crypto/asymmetric_keys/public_key.c | 57 -
 include/crypto/akcipher.h   | 54 +--
 2 files changed, 89 insertions(+), 22 deletions(-)

diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index 3bc090b8adef..51dc1c858c7c 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -242,6 +242,7 @@ int public_key_verify_signature(const struct public_key 
*pkey,
char alg_name[CRYPTO_MAX_ALG_NAME];
void *output;
unsigned int outlen;
+   int verify2;
int ret;
 
pr_devel("==>%s()\n", __func__);
@@ -279,14 +280,23 @@ int public_key_verify_signature(const struct public_key 
*pkey,
if (ret)
goto error_free_req;
 
-   ret = -ENOMEM;
-   outlen = crypto_akcipher_maxsize(tfm);
-   output = kmalloc(outlen, GFP_KERNEL);
-   if (!output)
-   goto error_free_req;
-
+   verify2 = crypto_akcipher_have_verify2(req);
+   if (!verify2) {
+   /* verify2 does not need output buffer */
+   ret = -ENOMEM;
+   outlen = crypto_akcipher_maxsize(tfm);
+   output = kmalloc(outlen, GFP_KERNEL);
+   if (!output)
+   goto error_free_req;
+
+   sg_init_one(_sg, output, outlen);
+   } else {
+   /* dummy init digest_sg */
+   memset(_sg, 0, sizeof(digest_sg));
+   output = NULL;
+   outlen = 0;
+   }
sg_init_one(_sg, sig->s, sig->s_size);
-   sg_init_one(_sg, output, outlen);
akcipher_request_set_crypt(req, _sg, _sg, sig->s_size,
   outlen);
crypto_init_wait();
@@ -294,18 +304,27 @@ int public_key_verify_signature(const struct public_key 
*pkey,
  CRYPTO_TFM_REQ_MAY_SLEEP,
  crypto_req_done, );
 
-   /* Perform the verification calculation.  This doesn't actually do the
-* verification, but rather calculates the hash expected by the
-* signature and returns that to us.
-*/
-   ret = crypto_wait_req(crypto_akcipher_verify(req), );
-   if (ret)
-   goto out_free_output;
-
-   /* Do the actual verification step. */
-   if (req->dst_len != sig->digest_size ||
-   memcmp(sig->digest, output, sig->digest_size) != 0)
-   ret = -EKEYREJECTED;
+   if (!verify2) {
+   /* Perform the verification calculation.  This doesn't actually
+* do the verification, but rather calculates the hash expected
+* by the signature and returns that to us.
+*/
+   ret = crypto_wait_req(crypto_akcipher_verify(req), );
+   if (ret)
+   goto out_free_output;
+
+   /* Do the actual verification step. */
+   if (req->dst_len != sig->digest_size ||
+   memcmp(sig->digest, output, sig->digest_size) != 0)
+   ret = -EKEYREJECTED;
+   } else {
+   /* Perform full verification in one call. */
+   req->digest = sig->digest;
+   req->digest_len = sig->digest_size;
+   ret = crypto_wait_req(crypto_akcipher_verify2(req), );
+   if (ret)
+   goto out_free_output;
+   }
 
 out_free_output:
kfree(output);
diff --git a/include/crypto/akcipher.h b/include/crypto/akcipher.h
index d6aba84ed2c4..f1ad67474bc1 100644
--- a/include/crypto/akcipher.h
+++ b/include/crypto/akcipher.h
@@ -28,6 +28,8 @@
  * result.
  * In case of error where the dst sgl size was insufficient,
  * it will be updated to the size required for the operation.
+ * @digest:Dige

Re: [RFC PATCH] X.509: Parse public key parameters from x509 for akcipher

2018-12-10 Thread Vitaly Chikunov
On Sun, Dec 09, 2018 at 04:55:48PM +0300, Vitaly Chikunov wrote:
> Some public key algorithms (like ECDSA) keep in parameters field
> important data such as digest and curve OIDs (possibly more for
> different ECDSA variants). Thus, just setting a public key (as
> for RSA) is not enough.
> 
> Introduce set_params() callback for akcipher which will be used to
> pass BER encoded parameters array, with additional argument of
> algorithm OID.
> 
> This is done with the intent of adding support for EC-RDSA (ISO/IEC
> 14888-3:2018, RFC 7091, and basically ECDSA variant) public keys (which
> will be finally used in IMA subsystem). Thus, also oid_registry.h is
> updated.
> 
> Rationale:
> 
> - For such keys just setting public key without parameters is
>   meaningless, so it would be possible to add parameters in
>   crypto_akcipher_set_pub_key (and .set_pub_key) calls. But, this will
>   needlessly change API for RSA akcipher. Also, additional callback
>   making it possible to pass parameters after
>   crypto_akcipher_set_priv_key (and .set_priv_key) in the future.
> 
> - Algorithm OID is passed to be validated in .set_params callback,
>   otherwise, it could have the wrong value.
> 
> - Particular algorithm OIDs are checked in x509_note_params, (because
>   this is called from AlgorithmIdentifier (ASN.1) parser, which is
>   called multiple times, as it's used multiple times in X.509
>   certificate), to distinguish a public key call from a signature call.
> 
> Signed-off-by: Vitaly Chikunov 
> ---
>  crypto/asymmetric_keys/public_key.c   | 16 +++
>  crypto/asymmetric_keys/x509.asn1  |  2 +-
>  crypto/asymmetric_keys/x509_cert_parser.c | 27 +
>  crypto/testmgr.c  |  5 +
>  crypto/testmgr.h  |  3 +++
>  include/crypto/akcipher.h | 33 
> +++
>  include/crypto/public_key.h   |  4 
>  include/linux/oid_registry.h  |  6 ++
>  8 files changed, 95 insertions(+), 1 deletion(-)
> 
> diff --git a/crypto/asymmetric_keys/public_key.c 
> b/crypto/asymmetric_keys/public_key.c
> index f5d85b47fcc6..3bc090b8adef 100644
> --- a/crypto/asymmetric_keys/public_key.c
> +++ b/crypto/asymmetric_keys/public_key.c
> @@ -45,6 +45,7 @@ void public_key_free(struct public_key *key)
>  {
>   if (key) {
>   kfree(key->key);
> + kfree(key->params);
>   kfree(key);
>   }
>  }
> @@ -124,6 +125,11 @@ static int software_key_query(const struct 
> kernel_pkey_params *params,
>   if (ret < 0)
>   goto error_free_tfm;
>  
> + ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
> +  pkey->paramlen);
> + if (ret)
> + goto error_free_tfm;
> +
>   len = crypto_akcipher_maxsize(tfm);
>   info->key_size = len * 8;
>   info->max_data_size = len;
> @@ -182,6 +188,11 @@ static int software_key_eds_op(struct kernel_pkey_params 
> *params,
>   if (ret)
>   goto error_free_req;
>  
> + ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
> +  pkey->paramlen);
> + if (ret)
> + goto error_free_req;
> +
>   sg_init_one(_sg, in, params->in_len);
>   sg_init_one(_sg, out, params->out_len);
>   akcipher_request_set_crypt(req, _sg, _sg, params->in_len,
> @@ -263,6 +274,11 @@ int public_key_verify_signature(const struct public_key 
> *pkey,
>   if (ret)
>   goto error_free_req;
>  
> + ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
> +  pkey->paramlen);
> + if (ret)
> + goto error_free_req;
> +
>   ret = -ENOMEM;
>   outlen = crypto_akcipher_maxsize(tfm);
>   output = kmalloc(outlen, GFP_KERNEL);
> diff --git a/crypto/asymmetric_keys/x509.asn1 
> b/crypto/asymmetric_keys/x509.asn1
> index aae0cde414e2..5c9f4e4a5231 100644
> --- a/crypto/asymmetric_keys/x509.asn1
> +++ b/crypto/asymmetric_keys/x509.asn1
> @@ -22,7 +22,7 @@ CertificateSerialNumber ::= INTEGER
>  
>  AlgorithmIdentifier ::= SEQUENCE {
>   algorithm   OBJECT IDENTIFIER ({ x509_note_OID }),
> - parameters  ANY OPTIONAL
> + parameters  ANY OPTIONAL ({ x509_note_params })
>  }
>  
>  Name ::= SEQUENCE OF RelativeDistinguishedName
> diff --git a/crypto/asymmetric_keys/x509_cert_parser.c 
> b/crypto/asymmetric_keys/x509_cert_parser.c
> index 991f4d735a4e..16d8936d143b 100644

[RFC PATCH] X.509: Parse public key parameters from x509 for akcipher

2018-12-09 Thread Vitaly Chikunov
Some public key algorithms (like ECDSA) keep in parameters field
important data such as digest and curve OIDs (possibly more for
different ECDSA variants). Thus, just setting a public key (as
for RSA) is not enough.

Introduce set_params() callback for akcipher which will be used to
pass BER encoded parameters array, with additional argument of
algorithm OID.

This is done with the intent of adding support for EC-RDSA (ISO/IEC
14888-3:2018, RFC 7091, and basically ECDSA variant) public keys (which
will be finally used in IMA subsystem). Thus, also oid_registry.h is
updated.

Rationale:

- For such keys just setting public key without parameters is
  meaningless, so it would be possible to add parameters in
  crypto_akcipher_set_pub_key (and .set_pub_key) calls. But, this will
  needlessly change API for RSA akcipher. Also, additional callback
  making it possible to pass parameters after
  crypto_akcipher_set_priv_key (and .set_priv_key) in the future.

- Algorithm OID is passed to be validated in .set_params callback,
  otherwise, it could have the wrong value.

- Particular algorithm OIDs are checked in x509_note_params, (because
  this is called from AlgorithmIdentifier (ASN.1) parser, which is
  called multiple times, as it's used multiple times in X.509
  certificate), to distinguish a public key call from a signature call.

Signed-off-by: Vitaly Chikunov 
---
 crypto/asymmetric_keys/public_key.c   | 16 +++
 crypto/asymmetric_keys/x509.asn1  |  2 +-
 crypto/asymmetric_keys/x509_cert_parser.c | 27 +
 crypto/testmgr.c  |  5 +
 crypto/testmgr.h  |  3 +++
 include/crypto/akcipher.h | 33 +++
 include/crypto/public_key.h   |  4 
 include/linux/oid_registry.h  |  6 ++
 8 files changed, 95 insertions(+), 1 deletion(-)

diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index f5d85b47fcc6..3bc090b8adef 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -45,6 +45,7 @@ void public_key_free(struct public_key *key)
 {
if (key) {
kfree(key->key);
+   kfree(key->params);
kfree(key);
}
 }
@@ -124,6 +125,11 @@ static int software_key_query(const struct 
kernel_pkey_params *params,
if (ret < 0)
goto error_free_tfm;
 
+   ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
+pkey->paramlen);
+   if (ret)
+   goto error_free_tfm;
+
len = crypto_akcipher_maxsize(tfm);
info->key_size = len * 8;
info->max_data_size = len;
@@ -182,6 +188,11 @@ static int software_key_eds_op(struct kernel_pkey_params 
*params,
if (ret)
goto error_free_req;
 
+   ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
+pkey->paramlen);
+   if (ret)
+   goto error_free_req;
+
sg_init_one(_sg, in, params->in_len);
sg_init_one(_sg, out, params->out_len);
akcipher_request_set_crypt(req, _sg, _sg, params->in_len,
@@ -263,6 +274,11 @@ int public_key_verify_signature(const struct public_key 
*pkey,
if (ret)
goto error_free_req;
 
+   ret = crypto_akcipher_set_params(tfm, pkey->algo, pkey->params,
+pkey->paramlen);
+   if (ret)
+   goto error_free_req;
+
ret = -ENOMEM;
outlen = crypto_akcipher_maxsize(tfm);
output = kmalloc(outlen, GFP_KERNEL);
diff --git a/crypto/asymmetric_keys/x509.asn1 b/crypto/asymmetric_keys/x509.asn1
index aae0cde414e2..5c9f4e4a5231 100644
--- a/crypto/asymmetric_keys/x509.asn1
+++ b/crypto/asymmetric_keys/x509.asn1
@@ -22,7 +22,7 @@ CertificateSerialNumber ::= INTEGER
 
 AlgorithmIdentifier ::= SEQUENCE {
algorithm   OBJECT IDENTIFIER ({ x509_note_OID }),
-   parameters  ANY OPTIONAL
+   parameters  ANY OPTIONAL ({ x509_note_params })
 }
 
 Name ::= SEQUENCE OF RelativeDistinguishedName
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c 
b/crypto/asymmetric_keys/x509_cert_parser.c
index 991f4d735a4e..16d8936d143b 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -26,6 +26,9 @@ struct x509_parse_context {
const void  *cert_start;/* Start of cert content */
const void  *key;   /* Key data */
size_t  key_size;   /* Size of key data */
+   const void  *params;/* Key parameters */
+   size_t  params_size;/* Size of key parameters */
+   enum OIDkey_algo;   /* Publi