Re: [PATCH RFC v2 1/2] crypto: add PKE API

2015-06-08 Thread Kees Cook
On Wed, May 6, 2015 at 12:36 PM, Tadeusz Struk tadeusz.st...@intel.com wrote:
 Add Public Key Encryption API.

 Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
 ---
  crypto/Kconfig |6 +
  crypto/Makefile|1
  crypto/crypto_user.c   |   24 +++
  crypto/pkey.c  |  125 ++
  include/crypto/pkey.h  |  390 
 
  include/linux/crypto.h |1
  include/linux/cryptouser.h |7 +
  7 files changed, 554 insertions(+)
  create mode 100644 crypto/pkey.c
  create mode 100644 include/crypto/pkey.h

 diff --git a/crypto/Kconfig b/crypto/Kconfig
 index 8aaf298..daa9c07 100644
 --- a/crypto/Kconfig
 +++ b/crypto/Kconfig
 @@ -87,6 +87,12 @@ config CRYPTO_PCOMP2
 tristate
 select CRYPTO_ALGAPI2

 +config CRYPTO_PKEY
 +   tristate Public Key Algorithms API
 +   select CRYPTO_ALGAPI
 +   help
 + Crypto API interface for public key algorithms.
 +
  config CRYPTO_MANAGER
 tristate Cryptographic algorithm manager
 select CRYPTO_MANAGER2
 diff --git a/crypto/Makefile b/crypto/Makefile
 index 97b7d3a..1930f85 100644
 --- a/crypto/Makefile
 +++ b/crypto/Makefile
 @@ -27,6 +27,7 @@ crypto_hash-y += shash.o
  obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o

  obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
 +obj-$(CONFIG_CRYPTO_PKEY) += pkey.o

  cryptomgr-y := algboss.o testmgr.o

 diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
 index 41dfe76..ccc7f1d 100644
 --- a/crypto/crypto_user.c
 +++ b/crypto/crypto_user.c
 @@ -27,6 +27,7 @@
  #include net/net_namespace.h
  #include crypto/internal/aead.h
  #include crypto/internal/skcipher.h
 +#include crypto/pkey.h

  #include internal.h

 @@ -110,6 +111,23 @@ nla_put_failure:
 return -EMSGSIZE;
  }

 +static int crypto_report_pkey(struct sk_buff *skb, struct crypto_alg *alg)
 +{
 +   struct crypto_report_pkey rpkey;
 +
 +   strncpy(rpkey.type, pke, sizeof(rpkey.type));
 +   strncpy(rpkey.subtype, alg-cra_name, sizeof(rpkey.subtype));

While subtype and cra_name are the same length, it may be possible to
pass an unterminated cra_name? Should this use strlcpy instead of
strncpy?

 +   rpkey.capabilities = __crypto_pkey_alg(alg)-capabilities;
 +
 +   if (nla_put(skb, CRYPTOCFGA_REPORT_PKEY,
 +   sizeof(struct crypto_report_pkey), rpkey))
 +   goto nla_put_failure;
 +   return 0;
 +
 +nla_put_failure:
 +   return -EMSGSIZE;
 +}
 +
  static int crypto_report_one(struct crypto_alg *alg,
  struct crypto_user_alg *ualg, struct sk_buff 
 *skb)
  {
 @@ -154,6 +172,12 @@ static int crypto_report_one(struct crypto_alg *alg,
 goto nla_put_failure;

 break;
 +
 +   case CRYPTO_ALG_TYPE_PKEY:
 +   if (crypto_report_pkey(skb, alg))
 +   goto nla_put_failure;
 +
 +   break;
 }

  out:
 diff --git a/crypto/pkey.c b/crypto/pkey.c
 new file mode 100644
 index 000..ab8c0e9
 --- /dev/null
 +++ b/crypto/pkey.c
 @@ -0,0 +1,125 @@
 +/*
 + * Public Key Encryption
 + *
 + * Copyright (c) 2015, Intel Corporation
 + * Authors: Tadeusz Struk tadeusz.st...@intel.com
 + *
 + * This program is free software; you can redistribute it and/or modify it
 + * under the terms of the GNU General Public License as published by the Free
 + * Software Foundation; either version 2 of the License, or (at your option)
 + * any later version.
 + *
 + */
 +#include linux/errno.h
 +#include linux/kernel.h
 +#include linux/module.h
 +#include linux/seq_file.h
 +#include linux/slab.h
 +#include linux/string.h
 +#include linux/crypto.h
 +#include crypto/algapi.h
 +#include linux/cryptouser.h
 +#include net/netlink.h
 +#include crypto/pkey.h
 +#include internal.h
 +
 +#ifdef CONFIG_NET
 +static int crypto_pkey_report(struct sk_buff *skb, struct crypto_alg *alg)
 +{
 +   struct crypto_report_pkey rep_pkey;
 +
 +   strncpy(rep_pkey.type, pkey, sizeof(rep_pkey.type));
 +   strncpy(rep_pkey.subtype, alg-cra_name, sizeof(rep_pkey.subtype));
 +   rep_pkey.capabilities = __crypto_pkey_alg(alg)-capabilities;
 +
 +   if (nla_put(skb, CRYPTOCFGA_REPORT_PKEY,
 +   sizeof(struct crypto_report_pkey), rep_pkey))
 +   goto nla_put_failure;
 +   return 0;
 +
 +nla_put_failure:
 +   return -EMSGSIZE;
 +}
 +#else
 +static int crypto_pkey_report(struct sk_buff *skb, struct crypto_alg *alg)
 +{
 +   return -ENOSYS;
 +}
 +#endif

This is identical to crypto_user's crypto_pkey_report. Perhaps extract it?

 +
 +static void crypto_pkey_show(struct seq_file *m, struct crypto_alg *alg)
 +   __attribute__ ((unused));
 +static void crypto_pkey_show(struct seq_file *m, struct crypto_alg *alg)
 +{
 +   int cap = __crypto_pkey_alg(alg)-capabilities;
 +
 +   seq_puts(m, type : pke\n);
 +   seq_printf(m, subtype  : %s\n, 

Re: [PATCH RFC v2 1/2] crypto: add PKE API

2015-06-01 Thread Tadeusz Struk
On 05/31/2015 10:48 PM, Herbert Xu wrote:
 On Thu, May 28, 2015 at 09:54:41AM -0700, Tadeusz Struk wrote:

 If we do this that way then we will be able to pass only one input and one
 output parameter. There are cases when we will need more that this.
 For instance for ECDSA signature generation we need one input param hash(m)
 and two output parameters (r, s).
 
 There is no reason why you couldn't encode that within one stream.
 As far as as the user is concerned the output is one entity, i.e.,
 the signature.  The fact that it is made up of two numbers is of
 no concern to the API.  It's a technicality for the algorithm to
 sort out.
 
 So I have used the SG for that. This is not to deal with non-contiguous 
 memory,
 but to pass more in/out parameters. Each parameter will need to occupy 
 contiguous space in memory.
 I will update the comment to make it more clear.
 If you have other idea how to do this I will be happy to try it.
 
 If you really wanted to do this then you should be using a simple
 (u8 *, unsigned int) pair but I don't really think this is at all
 necessary.
 

Ok, I'll rework this to take one char *src and one *dst ptrs.
Thanks
T

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC v2 1/2] crypto: add PKE API

2015-05-31 Thread Herbert Xu
On Thu, May 28, 2015 at 09:54:41AM -0700, Tadeusz Struk wrote:
 
 If we do this that way then we will be able to pass only one input and one
 output parameter. There are cases when we will need more that this.
 For instance for ECDSA signature generation we need one input param hash(m)
 and two output parameters (r, s).

There is no reason why you couldn't encode that within one stream.
As far as as the user is concerned the output is one entity, i.e.,
the signature.  The fact that it is made up of two numbers is of
no concern to the API.  It's a technicality for the algorithm to
sort out.

 So I have used the SG for that. This is not to deal with non-contiguous 
 memory,
 but to pass more in/out parameters. Each parameter will need to occupy 
 contiguous space in memory.
 I will update the comment to make it more clear.
 If you have other idea how to do this I will be happy to try it.

If you really wanted to do this then you should be using a simple
(u8 *, unsigned int) pair but I don't really think this is at all
necessary.

Cheers,
-- 
Email: Herbert Xu herb...@gondor.apana.org.au
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC v2 1/2] crypto: add PKE API

2015-05-28 Thread Tadeusz Struk
On 05/27/2015 09:08 PM, Herbert Xu wrote:
 Do you have a specific piece of hardware in mind? What are its
 capabilities?

I'm going to use it with Intel's DH985xcc accelerator. It can accelerate
RSA, DH, ECDSA and ECDH just to name the most commonly used.
But I don't want to add anything that is device specific.
I just want it to be flexible enough so that new algorithms can be easily added.

 
 If we are going to go with just contiguous memory then we might
 as well just do u8 *src, *dst, unsigned int slen, dlen.
 
 The whole point of the SG complexity is to deal with non-contiguous
 memory (e.g., fragmented packets with IPsec).  If you can't do that
 then why add the SG complexity?

If we do this that way then we will be able to pass only one input and one
output parameter. There are cases when we will need more that this.
For instance for ECDSA signature generation we need one input param hash(m)
and two output parameters (r, s).
So I have used the SG for that. This is not to deal with non-contiguous memory,
but to pass more in/out parameters. Each parameter will need to occupy 
contiguous space in memory.
I will update the comment to make it more clear.
If you have other idea how to do this I will be happy to try it.
Regards,
T
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC v2 1/2] crypto: add PKE API

2015-05-27 Thread Herbert Xu
On Sat, May 23, 2015 at 07:20:15AM -0700, Tadeusz Struk wrote:

 The length would be redundant. It can be obtained by sg_nents(reg-inparams)
 I don't limit the number of parameters. You can pass as many as you want. For 
 instance to pass 3 in and 2 out you do:
 
   struct scatterlist in[3];
   struct scatterlist out[2];
 
   sg_init_table(in, 3);
   sg_init_table(out, 2);
 
   sg_set_buf(in, first_in_param, len_of_first_in_param);
   sg_set_buf(in + 1, second_in_param, len_of_second_in_param);
   sg_set_buf(in + 2, third_in_param, len_of_third_in_param);
   
   sg_set_buf(out, first_out_param, len_of_first_out_param);
   sg_set_buf(out + 1, second_out_param, len_of_second_out_param);
 
   akcipher_request_set_crypt(req, in, out);
 
 The limitation here is that one parameter can not span multiple sgs. This 
 should be ok as they will never be bigger than one page.
 In fact MPI limits it to 2K max with #define MAX_EXTERN_MPI_BITS 16384.
 I'm ok to rename it to src and dst.

Do you have a specific piece of hardware in mind? What are its
capabilities?

If we are going to go with just contiguous memory then we might
as well just do u8 *src, *dst, unsigned int slen, dlen.

The whole point of the SG complexity is to deal with non-contiguous
memory (e.g., fragmented packets with IPsec).  If you can't do that
then why add the SG complexity?

Cheers,
-- 
Email: Herbert Xu herb...@gondor.apana.org.au
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC v2 1/2] crypto: add PKE API

2015-05-22 Thread Tadeusz Struk
On 05/10/2015 11:32 PM, Herbert Xu wrote:
 On Wed, May 06, 2015 at 12:36:48PM -0700, Tadeusz Struk wrote:

 +const struct public_key_signature *signature;
 
 Doing this means that you aren't adding it to the crypto API
 properly.  You need to start from scratch and design a proper
 interface and not just wrap some existing opaque data strcture.
 
 Cheers,
 

Hi Herbert,
Thanks for your feedback.
How about this:

/**
 * struct akcipher_request - public key request
 *
 * @base:   Common attributes for async crypto requests
 * @inparams:   scatterlist of input parameters (one ent per parameter)
 *  for the operation as defined in RFC.
 *  For instance for rsa encrypt only one input param is required,
 *  (i.e. 'm' - message) as specified in RFC3447 sec 5.1.1
 *  (Note: the key belongs to the tfm)
 * @outparams:  scatterlist of output parameters (one ent per parameter)
 *  for the operation as defined in RFC.
 *  For instance for rsa encrypt only one output param will be
 *  produced (i.e. 'c' - cipher text) as specified in
 *  RFC3447 sec 5.1.1
 *
 * @__ctx:  Start of private context data
 */
struct akcipher_request {
struct crypto_async_request base;
struct scatterlist *inparams;
struct scatterlist *outparams;
void *__ctx[] CRYPTO_MINALIGN_ATTR;
};

/**
 * struct akcipher_alg - generic public key algorithm
 *
 * @sign:   Function performs a sign operation as defined by public key
 *  algorithm
 * @verify: Function performs a sign operation as defined by public key
 *  algorithm
 * @encrypt:Function performs an encrypt operation as defined by public key
 *  algorithm
 * @decrypt:Function performs a decrypt operation as defined by public key
 *  algorithm
 * @reqsize:Request context size required by algorithm implementation
 *
 * @base:   Common crypto API algorithm data structure
 */
struct akcipher_alg {
int (*sign)(struct akcipher_request *req);
int (*verify)(struct akcipher_request *req);
int (*encrypt)(struct akcipher_request *req);
int (*decrypt)(struct akcipher_request *req);

unsigned int reqsize;
struct crypto_alg base;
};

/**
 * struct crypto_akcipher - user-instantiated objects which encapsulate
 * algorithms and core processing logic
 *
 * @base:   Common crypto API algorithm data structure
 * @pkey:   Key representation. Note: this can be both public or private
 *  key, depending on the operation.
 * @__ctx:  Start of private context data
 */
struct crypto_akcipher {
struct crypto_tfm base;
const struct public_key *pkey;
void *__ctx[] CRYPTO_MINALIGN_ATTR;
};

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC v2 1/2] crypto: add PKE API

2015-05-11 Thread Herbert Xu
On Wed, May 06, 2015 at 12:36:48PM -0700, Tadeusz Struk wrote:

 diff --git a/crypto/Kconfig b/crypto/Kconfig
 index 8aaf298..daa9c07 100644
 --- a/crypto/Kconfig
 +++ b/crypto/Kconfig
 @@ -87,6 +87,12 @@ config CRYPTO_PCOMP2
   tristate
   select CRYPTO_ALGAPI2
  
 +config CRYPTO_PKEY

Please call this AKCIPHER instead of PKEY.  The existing ciphers
are already known as skcipher (although the conversion process is
by no means complete so other names such as blkcipher/ablkcipher
still exist).

Thanks,
-- 
Email: Herbert Xu herb...@gondor.apana.org.au
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html