All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC v2 0/2] crypto: Introduce Public Key Encryption API
@ 2015-05-06 19:36 Tadeusz Struk
  2015-05-06 19:36 ` [PATCH RFC v2 1/2] crypto: add PKE API Tadeusz Struk
  2015-05-06 19:36 ` [PATCH RFC v2 2/2] crypto: RSA: KEYS: convert rsa and public key to new " Tadeusz Struk
  0 siblings, 2 replies; 19+ messages in thread
From: Tadeusz Struk @ 2015-05-06 19:36 UTC (permalink / raw)
  To: herbert
  Cc: linux-kernel, keescook, jwboyer, richard, tadeusz.struk, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

This patch set introduces a Public Key Encryption API.
What is proposed is a new crypto type called crypto_pkey_type
plus new struct pkey_alg and struct pkey_tfm together with number
of helper functions to register pkey type algorithms and allocate
tfm instances. This is to make it similar to how the existing crypto
API works for the ablkcipher, ahash, and aead types.
The operations the new interface will allow to provide are:

	int (*sign)(struct pkey_request *pkeyreq);
	int (*verify)(struct pkey_request *pkeyreq);
	int (*encrypt)(struct pkey_request *pkeyreq);
	int (*decrypt)(struct pkey_request *pkeyreq);

The benefits it gives comparing to the struct public_key_algorithm
interface are:
- drivers can add many implementations of RSA or DSA
  algorithms and user will allocate instances (tfms) of these, base on
  algorithm priority, in the same way as it is with the symmetric ciphers.
- the new interface allows for asynchronous implementations that
  can use crypto hardware to offload the calculations to.
- integrating it with linux crypto api allows using all its benefits
  i.e. managing algorithms using NETLINK_CRYPTO, monitoring implementations
  using /proc/crypto. etc

New helper functions have been added to allocate pkey_tfm instances
and invoke the operations to make it easier to use.
For instance to verify a public_signature against a public_key using
the RSA algorithm a user would do:

	struct crypto_pkey *tfm = crypto_alloc_pkey("rsa", 0, 0);
	struct pkey_request *req = pkey_request_alloc(tfm, GFP_KERNEL);
	pkey_request_set_crypt(req, pub_key, signature);
	int ret = crypto_pkey_verify(req);
	pkey_request_free(req);
	crypto_free_pkey(tfm);
	return ret;

Additionally existing public_key and rsa code have been reworked to
use the new interface for verifying signed modules.
As part of the rework the struct public_key_algorithm type has been removed.
Algorithm instance is allocated using crypto_alloc_pkey() and name defined in
pkey_algo_name table indexed by pkey_algo enum that comes from the public key.
In future this can be replaced by the name can be obtained directly from
the public key cert.

Changes in v2:
 - remodeled not to use obsolete cra_u and crt_u unions
 - changed type/funct names from pke_* to pkey_*
 - retained the enum pkey_algo type for it is external to the kernel
 - added documentation

---
Tadeusz Struk (2):
      crypto: add PKEY API
      crypto: RSA: KEYS: convert rsa and public key to new PKEY API


 crypto/Kconfig                            |    6 
 crypto/Makefile                           |    1 
 crypto/asymmetric_keys/Kconfig            |    1 
 crypto/asymmetric_keys/pkcs7_parser.c     |    2 
 crypto/asymmetric_keys/pkcs7_trust.c      |    2 
 crypto/asymmetric_keys/pkcs7_verify.c     |    3 
 crypto/asymmetric_keys/public_key.c       |   89 ++++---
 crypto/asymmetric_keys/public_key.h       |   36 ---
 crypto/asymmetric_keys/rsa.c              |   43 ++-
 crypto/asymmetric_keys/x509_cert_parser.c |    3 
 crypto/asymmetric_keys/x509_public_key.c  |    6 
 crypto/crypto_user.c                      |   24 ++
 crypto/pkey.c                             |  125 +++++++++
 include/crypto/pkey.h                     |  390 +++++++++++++++++++++++++++++
 include/crypto/public_key.h               |   10 -
 include/linux/crypto.h                    |    1 
 include/linux/cryptouser.h                |    7 +
 17 files changed, 657 insertions(+), 92 deletions(-)
 delete mode 100644 crypto/asymmetric_keys/public_key.h
 create mode 100644 crypto/pkey.c
 create mode 100644 include/crypto/pkey.h
-- 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH RFC v2 1/2] crypto: add PKE API
  2015-05-06 19:36 [PATCH RFC v2 0/2] crypto: Introduce Public Key Encryption API Tadeusz Struk
@ 2015-05-06 19:36 ` Tadeusz Struk
  2015-05-11  6:03   ` Herbert Xu
                     ` (5 more replies)
  2015-05-06 19:36 ` [PATCH RFC v2 2/2] crypto: RSA: KEYS: convert rsa and public key to new " Tadeusz Struk
  1 sibling, 6 replies; 19+ messages in thread
From: Tadeusz Struk @ 2015-05-06 19:36 UTC (permalink / raw)
  To: herbert
  Cc: linux-kernel, keescook, jwboyer, richard, tadeusz.struk, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

Add Public Key Encryption API.

Signed-off-by: Tadeusz Struk <tadeusz.struk@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));
+	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 0000000..ab8c0e9
--- /dev/null
+++ b/crypto/pkey.c
@@ -0,0 +1,125 @@
+/*
+ * Public Key Encryption
+ *
+ * Copyright (c) 2015, Intel Corporation
+ * Authors: Tadeusz Struk <tadeusz.struk@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
+
+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", alg->cra_name);
+	seq_printf(m, "can encrypt  : %s\n",
+		   cap & PKEY_CAN_ENCRYPT ? "yes" : "no");
+	seq_printf(m, "can decrypt  : %s\n",
+		   cap & PKEY_CAN_DECRYPT ? "yes" : "no");
+	seq_printf(m, "can sign     : %s\n",
+		   cap & PKEY_CAN_SIGN ? "yes" : "no");
+	seq_printf(m, "can verify   : %s\n",
+		   cap & PKEY_CAN_VERIFY ? "yes" : "no");
+}
+
+static int crypto_pkey_init(struct crypto_tfm *tfm)
+{
+	return 0;
+}
+
+static const struct crypto_type crypto_pkey_type = {
+	.extsize = crypto_alg_extsize,
+	.init_tfm = crypto_pkey_init,
+#ifdef CONFIG_PROC_FS
+	.show = crypto_pkey_show,
+#endif
+	.report = crypto_pkey_report,
+	.maskclear = ~CRYPTO_ALG_TYPE_MASK,
+	.maskset = CRYPTO_ALG_TYPE_MASK,
+	.type = CRYPTO_ALG_TYPE_PKEY,
+	.tfmsize = offsetof(struct crypto_pkey, base),
+};
+
+struct crypto_pkey *crypto_alloc_pkey(const char *alg_name, u32 type, u32 mask)
+{
+	return crypto_alloc_tfm(alg_name, &crypto_pkey_type, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_alloc_pkey);
+
+int crypto_register_pkey(struct pkey_alg *alg)
+{
+	struct crypto_alg *base = &alg->base;
+
+	if (alg->n_pub_mpi > 5 || alg->n_sec_mpi > 5 || alg->n_sig_mpi > 2)
+		return -EINVAL;
+
+	if ((alg->capabilities & PKEY_CAN_ENCRYPT) && !alg->encrypt)
+		return -EINVAL;
+
+	if ((alg->capabilities & PKEY_CAN_DECRYPT) && !alg->decrypt)
+		return -EINVAL;
+
+	if ((alg->capabilities & PKEY_CAN_SIGN) && !alg->sign)
+		return -EINVAL;
+
+	if ((alg->capabilities & PKEY_CAN_VERIFY) && !alg->verify)
+		return -EINVAL;
+
+	base->cra_type = &crypto_pkey_type;
+	base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
+	base->cra_flags |= CRYPTO_ALG_TYPE_PKEY;
+
+	return crypto_register_alg(base);
+}
+EXPORT_SYMBOL_GPL(crypto_register_pkey);
+
+void crypto_unregister_pkey(struct pkey_alg *alg)
+{
+	crypto_unregister_alg(&alg->base);
+}
+EXPORT_SYMBOL_GPL(crypto_unregister_pkey);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic public key type");
diff --git a/include/crypto/pkey.h b/include/crypto/pkey.h
new file mode 100644
index 0000000..abcdb11
--- /dev/null
+++ b/include/crypto/pkey.h
@@ -0,0 +1,390 @@
+/*
+ * Public Key Encryption
+ *
+ * Copyright (c) 2015, Intel Corporation
+ * Authors: Tadeusz Struk <tadeusz.struk@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.
+ *
+ */
+#ifndef _CRYPTO_PKEY_H
+#define _CRYPTO_PKEY_H
+#include <linux/crypto.h>
+
+struct public_key;
+struct public_key_signature;
+
+/**
+ * struct pkey_request - public key request
+ *
+ * @base:	Common attributes for async crypto requests
+ * @pkey:	Public key data for the subtype of the asymmetric key.
+ *		It may include private part of the key as well as
+ *		the public part.
+ * @signature:	Public key signature data.
+ * @__ctx:	Start of private context data.
+ */
+struct pkey_request {
+	struct crypto_async_request base;
+	const struct public_key *pkey;
+	const struct public_key_signature *signature;
+	void *__ctx[] CRYPTO_MINALIGN_ATTR;
+};
+
+/**
+ * struct pkey_alg - generic public key algorithm
+ *
+ * @sign:	Function performs a sign operation as defined by public key
+ *		algorithm. PKEY_CAN_SIGN bit in capabilities mask denotes
+ *		if it is provided by algorithm.
+ * @verify:	Function performs a sign operation as defined by public key
+ *		algorithm. PKEY_CAN_VERIFY bit in capabilities mask denotes
+ *		if it is provided by algorithm.
+ * @encrypt:	Function performs an encrytp operation as defined by public key
+ *		algorithm. PKEY_CAN_ENCRYPT bit in capabilities maks denotes
+ *		if it is provided by algorithm.
+ * @decrypt:	Function performs a decrypt operation as defined by public key
+ *		algorithm. PKEY_CAN_DECRYPT bit in capabilities maks denotes
+ *		if it is provided by algorithm.
+ * @n_pub_mpi:	Minimun number of MPIs (Multi Precision Integers) in public key
+ *		parameter in the pkey request as expected by the algorithm.
+ * @n_sec_mpi:	Minimun number of MPIs (Multi Precision Integers) in secret key
+ *		parameter in the pkey request as expected by the algorithm.
+ * @n_sig_mpi:	Minimun number of MPIs (Multi Precision Integers) in signature
+ *		parameter in the pkey request as expected by the algorithm.
+ * @capabilities:
+ *		Specifies what operations are provided by the algorithm
+ *		implementation.
+ * @reqsize:	Request context size required by algorithm implementation.
+ * @base:	Common crypto API algorithm data structure.
+ */
+struct pkey_alg {
+	int (*sign)(struct pkey_request *pkeyreq);
+	int (*verify)(struct pkey_request *pkeyreq);
+	int (*encrypt)(struct pkey_request *pkeyreq);
+	int (*decrypt)(struct pkey_request *pkeyreq);
+
+	u8 n_pub_mpi;
+	u8 n_sec_mpi;
+	u8 n_sig_mpi;
+#define PKEY_CAN_ENCRYPT	0x01
+#define PKEY_CAN_DECRYPT	0x02
+#define PKEY_CAN_SIGN		0x04
+#define PKEY_CAN_VERIFY		0x08
+	u8 capabilities;
+	unsigned int reqsize;
+	struct crypto_alg base;
+};
+
+/**
+ * struct crypto_pkey - user-instantiated objects which encapsulate algorithms
+ * and core processing logic.
+ *
+ * @base:	Common crypto API algorithm data structure.
+ * @__ctx:	Start of private context data
+ */
+struct crypto_pkey {
+	struct crypto_tfm base;
+	void *__ctx[] CRYPTO_MINALIGN_ATTR;
+};
+
+/**
+ * DOC: Generic Public Key API
+ *
+ * The Public Key API is used with the algorithms of type
+ * CRYPTO_ALG_TYPE_PKEY (listed as type "pkey" in /proc/crypto)
+ */
+
+/**
+ * crypto_alloc_pkey() -- allocate PKEY tfm handle
+ * @alg_name: is the cra_name / name or cra_driver_name / driver name of the
+ *	      public key algorithm e.g. "rsa"
+ * @type: specifies the type of the algorithm
+ * @mask: specifies the mask for the algorithm
+ *
+ * Allocate a handle for public key algorithm. The returned struct
+ * crypto_pkey is the handle that is required for any subsequent
+ * API invocation for the public key operations.
+ *
+ * Return: allocated handle in case of success; IS_ERR() is true in case
+ *	   of an error, PTR_ERR() returns the error code.
+ */
+struct crypto_pkey *crypto_alloc_pkey(const char *alg_name, u32 type, u32 mask);
+
+/*
+ * Transform internal helpers.
+ */
+static inline struct pkey_alg *__crypto_pkey_alg(struct crypto_alg *alg)
+{
+	return container_of(alg, struct pkey_alg, base);
+}
+
+static inline struct crypto_pkey *__crypto_pkey_tfm(struct crypto_tfm *tfm)
+{
+	return container_of(tfm, struct crypto_pkey, base);
+}
+
+static inline struct crypto_tfm *crypto_pkey_tfm(struct crypto_pkey *tfm)
+{
+	return &tfm->base;
+}
+
+static inline struct pkey_alg *crypto_pkey_alg(struct crypto_pkey *tfm)
+{
+	return __crypto_pkey_alg(crypto_pkey_tfm(tfm)->__crt_alg);
+}
+
+/**
+ * crypto_free_pkey() -- free PKEY tfm handle
+ *
+ * @tfm: PKEY tfm handle allocated with crypto_alloc_pkey()
+ */
+static inline void crypto_free_pkey(struct crypto_pkey *tfm)
+{
+	crypto_destroy_tfm(tfm, crypto_pkey_tfm(tfm));
+}
+
+static inline unsigned int crypto_pkey_reqsize(struct crypto_pkey *tfm)
+{
+	return crypto_pkey_alg(tfm)->reqsize;
+}
+
+static inline void pkey_request_set_tfm(struct pkey_request *req,
+					struct crypto_pkey *tfm)
+{
+	req->base.tfm = crypto_pkey_tfm(tfm);
+}
+
+/**
+ * pkey_request_alloc() -- allocates public key request
+ *
+ * @tfm:	PKEY tfm handle allocated with crypto_alloc_pkey()
+ * @gfp:	allocation flags
+ *
+ * Return: allocated handle in case of success or NULL in case of an error.
+ */
+static inline struct pkey_request *pkey_request_alloc(struct crypto_pkey *tfm,
+						      gfp_t gfp)
+{
+	struct pkey_request *req;
+
+	req = kmalloc(sizeof(*req) + crypto_pkey_reqsize(tfm), gfp);
+	if (likely(req))
+		pkey_request_set_tfm(req, tfm);
+
+	return req;
+}
+
+static inline void *pkey_request_ctx(struct pkey_request *req)
+{
+	return req->__ctx;
+}
+
+/**
+ * pkey_request_free() -- zeroize and free public key request
+ *
+ * @req:	request to free
+ */
+static inline void pkey_request_free(struct pkey_request *req)
+{
+	kzfree(req);
+}
+
+/**
+ * pkey_request_set_callback() -- Sets an asynchronous callback.
+ *
+ * Callback will be called when an asynchronous operation on a given
+ * request is finished.
+ *
+ * @req:	request that the callback will be set for.
+ * @flgs:	specify for instance if the operation may backlog.
+ * @cmlp:	callback which will be called.
+ * @data:	private data used by the caller.
+ */
+static inline void pkey_request_set_callback(struct pkey_request *req, u32 flgs,
+					     crypto_completion_t cmpl,
+					     void *data)
+{
+	req->base.complete = cmpl;
+	req->base.data = data;
+	req->base.flags = flgs;
+}
+
+static inline void pkey_request_complete(struct pkey_request *req, int err)
+{
+	req->base.complete(&req->base, err);
+}
+
+/**
+ * pkey_request_set_crypt() -- Sets reqest parameters.
+ *
+ * Sets parameters required by crypto operation.
+ *
+ * @req:	public key.
+ * @sig:	public key signature.
+ */
+static inline void pkey_request_set_crypt(struct pkey_request *req,
+					  const struct public_key *pkey,
+					  const struct public_key_signature *sg)
+{
+	req->pkey = pkey;
+	req->signature = sg;
+}
+
+/**
+ * pkey_num_sig_mpi() -- Returns number of MPIs in signature
+ *
+ * Function returns number of MPIs (Multi Precision Integers) in signature
+ * parameter as expected by the algorithm.
+ *
+ * @tfm:	tfm handle.
+ *
+ * Return: number of MPIs in signature.
+ */
+static inline u8 pkey_num_sig_mpi(struct crypto_pkey *tfm)
+{
+	return crypto_pkey_alg(tfm)->n_sig_mpi;
+}
+
+/**
+ * pkey_num_pub_mpi() -- Returns number of MPIs in public key
+ *
+ * Function returns number of MPIs (Multi Precision Integers) in public key
+ * parameter as expected by the algorithm.
+ *
+ * @tfm:	tfm handle.
+ *
+ * Return: number of MPIs in public key.
+ */
+static inline u8 pkey_num_pub_mpi(struct crypto_pkey *tfm)
+{
+	return crypto_pkey_alg(tfm)->n_pub_mpi;
+}
+
+/**
+ * pkey_num_sec_mpi() -- Returns number of MPIs in secret key
+ *
+ * Function returns number of MPIs (Multi Precision Integers) in secret key
+ * parameter as expected by the algorithm.
+ *
+ * @tfm:	tfm handle.
+ *
+ * Return: number of MPIs in secret key.
+ */
+static inline u8 pkey_num_sec_mpi(struct crypto_pkey *tfm)
+{
+	return crypto_pkey_alg(tfm)->n_sec_mpi;
+}
+
+/**
+ * pkey_capabilities() -- Returns cababilities
+ *
+ * Function returns bitmask of capabilities denoting what public key operations
+ * are supported by the algorithm.
+ *
+ * @tfm:	tfm handle.
+ *
+ * Return: capabilities mask.
+ */
+static inline u8 pkey_capabilities(struct crypto_pkey *tfm)
+{
+	return crypto_pkey_alg(tfm)->capabilities;
+}
+
+/**
+ * pkey_capab() -- Returns algorithm name
+ *
+ * Function returns public key algorithm name e.g.g "rsa".
+ *
+ * @tfm:	tfm handle.
+ *
+ * Return: public key algorithm name.
+ */
+static inline const char *pkey_alg_name(struct crypto_pkey *tfm)
+{
+	return crypto_pkey_tfm(tfm)->__crt_alg->cra_name;
+}
+
+/**
+ * crypto_pkey_encrypt() -- Invoke public key encrypt operation
+ *
+ * Function invokes the specific public key encrypt operation for a given
+ * public key algorithm.
+ *
+ * @tfm:	tfm handle.
+ *
+ * Return: zero on success; error code in case of error.
+ */
+static inline int crypto_pkey_encrypt(struct pkey_request *req)
+{
+	return crypto_pkey_alg(__crypto_pkey_tfm(req->base.tfm))->encrypt(req);
+}
+
+/**
+ * crypto_pkey_encrypt() -- Invoke public key decrypt operation
+ *
+ * Function invokes the specific public key decrypt operation for a given
+ * public key algorithm.
+ *
+ * @tfm:	tfm handle.
+ *
+ * Return: zero on success; error code in case of error.
+ */
+static inline int crypto_pkey_decrypt(struct pkey_request *req)
+{
+	return crypto_pkey_alg(__crypto_pkey_tfm(req->base.tfm))->decrypt(req);
+}
+
+/**
+ * crypto_pkey_encrypt() -- Invoke public key sign operation
+ *
+ * Function invokes the specific public key sign operation for a given
+ * public key algorithm.
+ *
+ * @tfm:	tfm handle.
+ *
+ * Return: zero on success; error code in case of error.
+ */
+static inline int crypto_pkey_sign(struct pkey_request *req)
+{
+	return crypto_pkey_alg(__crypto_pkey_tfm(req->base.tfm))->sign(req);
+}
+
+/**
+ * crypto_pkey_encrypt() -- Invoke public key verify operation
+ *
+ * Function invokes the specific public key verify operation for a given
+ * public key algorithm.
+ *
+ * @tfm:	tfm handle.
+ *
+ * Return: zero on success; error code in case of error.
+ */
+static inline int crypto_pkey_verify(struct pkey_request *req)
+{
+	return crypto_pkey_alg(__crypto_pkey_tfm(req->base.tfm))->verify(req);
+}
+
+/**
+ * crypto_register_pkey() -- Register public key algorithm
+ *
+ * Function registers an implementation of a public key verify algorithm.
+ *
+ * @alg:	algorithm definition.
+ *
+ * Return: zero on success; error code in case of error.
+ */
+int crypto_register_pkey(struct pkey_alg *alg);
+
+/**
+ * crypto_unregister_pkey() -- Unregister public key algorithm
+ *
+ * Function unregisters an implementation of a public key verify algorithm.
+ *
+ * @alg:	algorithm definition.
+ */
+void crypto_unregister_pkey(struct pkey_alg *alg);
+#endif
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index ee14140..61842c9 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -53,6 +53,7 @@
 #define CRYPTO_ALG_TYPE_SHASH		0x00000009
 #define CRYPTO_ALG_TYPE_AHASH		0x0000000a
 #define CRYPTO_ALG_TYPE_RNG		0x0000000c
+#define CRYPTO_ALG_TYPE_PKEY		0x0000000d
 #define CRYPTO_ALG_TYPE_PCOMPRESS	0x0000000f
 
 #define CRYPTO_ALG_TYPE_HASH_MASK	0x0000000e
diff --git a/include/linux/cryptouser.h b/include/linux/cryptouser.h
index 4abf2ea..fdf9120 100644
--- a/include/linux/cryptouser.h
+++ b/include/linux/cryptouser.h
@@ -43,6 +43,7 @@ enum crypto_attr_type_t {
 	CRYPTOCFGA_REPORT_COMPRESS,	/* struct crypto_report_comp */
 	CRYPTOCFGA_REPORT_RNG,		/* struct crypto_report_rng */
 	CRYPTOCFGA_REPORT_CIPHER,	/* struct crypto_report_cipher */
+	CRYPTOCFGA_REPORT_PKEY,		/* struct crypto_report_pkey */
 	__CRYPTOCFGA_MAX
 
 #define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
@@ -101,5 +102,11 @@ struct crypto_report_rng {
 	unsigned int seedsize;
 };
 
+struct crypto_report_pkey {
+	char type[CRYPTO_MAX_NAME];
+	char subtype[CRYPTO_MAX_NAME];
+	unsigned int capabilities;
+};
+
 #define CRYPTO_REPORT_MAXSIZE (sizeof(struct crypto_user_alg) + \
 			       sizeof(struct crypto_report_blkcipher))

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH RFC v2 2/2] crypto: RSA: KEYS: convert rsa and public key to new PKE API
  2015-05-06 19:36 [PATCH RFC v2 0/2] crypto: Introduce Public Key Encryption API Tadeusz Struk
  2015-05-06 19:36 ` [PATCH RFC v2 1/2] crypto: add PKE API Tadeusz Struk
@ 2015-05-06 19:36 ` Tadeusz Struk
  1 sibling, 0 replies; 19+ messages in thread
From: Tadeusz Struk @ 2015-05-06 19:36 UTC (permalink / raw)
  To: herbert
  Cc: linux-kernel, keescook, jwboyer, richard, tadeusz.struk, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

Change the existing rsa and public key code to integrate it
with the new Public Key Encryption API.

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
 crypto/asymmetric_keys/Kconfig            |    1 
 crypto/asymmetric_keys/pkcs7_parser.c     |    2 -
 crypto/asymmetric_keys/pkcs7_trust.c      |    2 -
 crypto/asymmetric_keys/pkcs7_verify.c     |    3 +
 crypto/asymmetric_keys/public_key.c       |   89 +++++++++++++++++++----------
 crypto/asymmetric_keys/public_key.h       |   36 ------------
 crypto/asymmetric_keys/rsa.c              |   43 +++++++++++---
 crypto/asymmetric_keys/x509_cert_parser.c |    3 +
 crypto/asymmetric_keys/x509_public_key.c  |    6 +-
 include/crypto/public_key.h               |   11 +---
 10 files changed, 104 insertions(+), 92 deletions(-)
 delete mode 100644 crypto/asymmetric_keys/public_key.h

diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
index 4870f28..1b7d7d6 100644
--- a/crypto/asymmetric_keys/Kconfig
+++ b/crypto/asymmetric_keys/Kconfig
@@ -23,6 +23,7 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
 config PUBLIC_KEY_ALGO_RSA
 	tristate "RSA public-key algorithm"
 	select MPILIB
+	select CRYPTO_PKEY
 	help
 	  This option enables support for the RSA algorithm (PKCS#1, RFC3447).
 
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c
index 3bd5a1e..054f110 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -15,7 +15,7 @@
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/oid_registry.h>
-#include "public_key.h"
+#include <crypto/public_key.h>
 #include "pkcs7_parser.h"
 #include "pkcs7-asn1.h"
 
diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c
index 1d29376..68ebae2 100644
--- a/crypto/asymmetric_keys/pkcs7_trust.c
+++ b/crypto/asymmetric_keys/pkcs7_trust.c
@@ -17,7 +17,7 @@
 #include <linux/asn1.h>
 #include <linux/key.h>
 #include <keys/asymmetric-type.h>
-#include "public_key.h"
+#include <crypto/public_key.h>
 #include "pkcs7_parser.h"
 
 /**
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index cd45545..9f1035c 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -16,7 +16,8 @@
 #include <linux/err.h>
 #include <linux/asn1.h>
 #include <crypto/hash.h>
-#include "public_key.h"
+#include <crypto/public_key.h>
+#include <crypto/pkey.h>
 #include "pkcs7_parser.h"
 
 /*
diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
index 2f6e4fb..d147ee0 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -18,30 +18,28 @@
 #include <linux/slab.h>
 #include <linux/seq_file.h>
 #include <keys/asymmetric-subtype.h>
-#include "public_key.h"
+#include <crypto/public_key.h>
+#include <crypto/pkey.h>
 
 MODULE_LICENSE("GPL");
 
 const char *const pkey_algo_name[PKEY_ALGO__LAST] = {
-	[PKEY_ALGO_DSA]		= "DSA",
-	[PKEY_ALGO_RSA]		= "RSA",
+	[PKEY_ALGO_DSA]		= "dsa",
+	[PKEY_ALGO_RSA]		= "rsa",
 };
 EXPORT_SYMBOL_GPL(pkey_algo_name);
 
-const struct public_key_algorithm *pkey_algo[PKEY_ALGO__LAST] = {
-#if defined(CONFIG_PUBLIC_KEY_ALGO_RSA) || \
-	defined(CONFIG_PUBLIC_KEY_ALGO_RSA_MODULE)
-	[PKEY_ALGO_RSA]		= &RSA_public_key_algorithm,
-#endif
-};
-EXPORT_SYMBOL_GPL(pkey_algo);
-
 const char *const pkey_id_type_name[PKEY_ID_TYPE__LAST] = {
 	[PKEY_ID_PGP]		= "PGP",
 	[PKEY_ID_X509]		= "X509",
 };
 EXPORT_SYMBOL_GPL(pkey_id_type_name);
 
+struct public_key_completion {
+	struct completion completion;
+	int err;
+};
+
 /*
  * Provide a part of a description of the key for /proc/keys.
  */
@@ -52,7 +50,8 @@ static void public_key_describe(const struct key *asymmetric_key,
 
 	if (key)
 		seq_printf(m, "%s.%s",
-			   pkey_id_type_name[key->id_type], key->algo->name);
+			   pkey_id_type_name[key->id_type],
+			   pkey_algo_name[key->pkey_algo]);
 }
 
 /*
@@ -71,40 +70,68 @@ void public_key_destroy(void *payload)
 }
 EXPORT_SYMBOL_GPL(public_key_destroy);
 
+static void public_key_verify_done(struct crypto_async_request *req, int err)
+{
+	struct public_key_completion *compl = req->data;
+
+	if (err == -EINPROGRESS)
+		return;
+
+	compl->err = err;
+	complete(&compl->completion);
+}
+
 /*
  * Verify a signature using a public key.
  */
-int public_key_verify_signature(const struct public_key *pk,
+int public_key_verify_signature(const struct public_key *pkey,
 				const struct public_key_signature *sig)
 {
-	const struct public_key_algorithm *algo;
-
-	BUG_ON(!pk);
-	BUG_ON(!pk->mpi[0]);
-	BUG_ON(!pk->mpi[1]);
+	struct crypto_pkey *tfm;
+	struct pkey_request *req;
+	struct public_key_completion compl;
+	int ret;
+
+	BUG_ON(!pkey);
+	BUG_ON(!pkey->mpi[0]);
+	BUG_ON(!pkey->mpi[1]);
 	BUG_ON(!sig);
 	BUG_ON(!sig->digest);
 	BUG_ON(!sig->mpi[0]);
 
-	algo = pk->algo;
-	if (!algo) {
-		if (pk->pkey_algo >= PKEY_ALGO__LAST)
-			return -ENOPKG;
-		algo = pkey_algo[pk->pkey_algo];
-		if (!algo)
-			return -ENOPKG;
-	}
+	if (pkey->pkey_algo >= PKEY_ALGO__LAST)
+		return -ENOPKG;
 
-	if (!algo->verify_signature)
-		return -ENOTSUPP;
+	tfm = crypto_alloc_pkey(pkey_algo_name[pkey->pkey_algo], 0, 0);
+	if (IS_ERR(tfm))
+		return -ENOMEM;
 
-	if (sig->nr_mpi != algo->n_sig_mpi) {
+	if (!(pkey_capabilities(tfm) & PKEY_CAN_VERIFY))
+		return -EINVAL;
+
+	if (sig->nr_mpi != pkey_num_sig_mpi(tfm)) {
 		pr_debug("Signature has %u MPI not %u\n",
-			 sig->nr_mpi, algo->n_sig_mpi);
+			 sig->nr_mpi, pkey_num_sig_mpi(tfm));
 		return -EINVAL;
 	}
 
-	return algo->verify_signature(pk, sig);
+	req = pkey_request_alloc(tfm, GFP_KERNEL);
+	if (!req)
+		return -ENOMEM;
+
+	init_completion(&compl.completion);
+	pkey_request_set_crypt(req, pkey, sig);
+	pkey_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
+				 CRYPTO_TFM_REQ_MAY_SLEEP,
+				 public_key_verify_done, &compl);
+	ret = crypto_pkey_verify(req);
+	if (ret == -EINPROGRESS) {
+		wait_for_completion(&compl.completion);
+		ret = compl.err;
+	}
+	pkey_request_free(req);
+	crypto_free_pkey(tfm);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(public_key_verify_signature);
 
diff --git a/crypto/asymmetric_keys/public_key.h b/crypto/asymmetric_keys/public_key.h
deleted file mode 100644
index 5c37a22..0000000
--- a/crypto/asymmetric_keys/public_key.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Public key algorithm internals
- *
- * See Documentation/crypto/asymmetric-keys.txt
- *
- * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-
-#include <crypto/public_key.h>
-
-extern struct asymmetric_key_subtype public_key_subtype;
-
-/*
- * Public key algorithm definition.
- */
-struct public_key_algorithm {
-	const char	*name;
-	u8		n_pub_mpi;	/* Number of MPIs in public key */
-	u8		n_sec_mpi;	/* Number of MPIs in secret key */
-	u8		n_sig_mpi;	/* Number of MPIs in a signature */
-	int (*verify_signature)(const struct public_key *key,
-				const struct public_key_signature *sig);
-};
-
-extern const struct public_key_algorithm RSA_public_key_algorithm;
-
-/*
- * public_key.c
- */
-extern int public_key_verify_signature(const struct public_key *pk,
-				       const struct public_key_signature *sig);
diff --git a/crypto/asymmetric_keys/rsa.c b/crypto/asymmetric_keys/rsa.c
index 459cf97..4282d30 100644
--- a/crypto/asymmetric_keys/rsa.c
+++ b/crypto/asymmetric_keys/rsa.c
@@ -14,7 +14,8 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <crypto/algapi.h>
-#include "public_key.h"
+#include <crypto/public_key.h>
+#include <crypto/pkey.h>
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("RSA Public Key Algorithm");
@@ -207,9 +208,10 @@ static int RSA_verify(const u8 *H, const u8 *EM, size_t k, size_t hash_size,
 /*
  * Perform the verification step [RFC3447 sec 8.2.2].
  */
-static int RSA_verify_signature(const struct public_key *key,
-				const struct public_key_signature *sig)
+static int RSA_verify_signature(struct pkey_request *req)
 {
+	const struct public_key *key = req->pkey;
+	const struct public_key_signature *sig = req->signature;
 	size_t tsize;
 	int ret;
 
@@ -268,11 +270,32 @@ error:
 	return ret;
 }
 
-const struct public_key_algorithm RSA_public_key_algorithm = {
-	.name		= "RSA",
-	.n_pub_mpi	= 2,
-	.n_sec_mpi	= 3,
-	.n_sig_mpi	= 1,
-	.verify_signature = RSA_verify_signature,
+static struct pkey_alg rsa = {
+	.verify = RSA_verify_signature,
+	.n_pub_mpi = 2,
+	.n_sec_mpi = 3,
+	.n_sig_mpi = 1,
+	.capabilities = PKEY_CAN_VERIFY,
+	.base = {
+		.cra_name = "rsa",
+		.cra_driver_name = "rsa-keys",
+		.cra_priority = 100,
+		.cra_ctxsize = 0,
+		.cra_alignmask = 0,
+		.cra_module = THIS_MODULE,
+	},
 };
-EXPORT_SYMBOL_GPL(RSA_public_key_algorithm);
+
+static int rsa_init(void)
+{
+	return crypto_register_pkey(&rsa);
+}
+
+static void rsa_exit(void)
+{
+	crypto_unregister_pkey(&rsa);
+}
+
+module_init(rsa_init);
+module_exit(rsa_exit);
+MODULE_ALIAS_CRYPTO("rsa");
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index a668d90..de81968 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -15,7 +15,8 @@
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/oid_registry.h>
-#include "public_key.h"
+#include <crypto/public_key.h>
+#include <crypto/pkey.h>
 #include "x509_parser.h"
 #include "x509-asn1.h"
 #include "x509_rsakey-asn1.h"
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index a6c4203..d705945 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -20,8 +20,9 @@
 #include <keys/asymmetric-parser.h>
 #include <keys/system_keyring.h>
 #include <crypto/hash.h>
+#include <crypto/public_key.h>
+#include <crypto/pkey.h>
 #include "asymmetric_keys.h"
-#include "public_key.h"
 #include "x509_parser.h"
 
 static bool use_builtin_keys;
@@ -250,8 +251,6 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
 	if (cert->pub->pkey_algo >= PKEY_ALGO__LAST ||
 	    cert->sig.pkey_algo >= PKEY_ALGO__LAST ||
 	    cert->sig.pkey_hash_algo >= PKEY_HASH__LAST ||
-	    !pkey_algo[cert->pub->pkey_algo] ||
-	    !pkey_algo[cert->sig.pkey_algo] ||
 	    !hash_algo_name[cert->sig.pkey_hash_algo]) {
 		ret = -ENOPKG;
 		goto error_free_cert;
@@ -270,7 +269,6 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
 		 pkey_algo_name[cert->sig.pkey_algo],
 		 hash_algo_name[cert->sig.pkey_hash_algo]);
 
-	cert->pub->algo = pkey_algo[cert->pub->pkey_algo];
 	cert->pub->id_type = PKEY_ID_X509;
 
 	/* Check the signature on the key if it appears to be self-signed */
diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
index 54add20..34b6fb8 100644
--- a/include/crypto/public_key.h
+++ b/include/crypto/public_key.h
@@ -25,7 +25,6 @@ enum pkey_algo {
 };
 
 extern const char *const pkey_algo_name[PKEY_ALGO__LAST];
-extern const struct public_key_algorithm *pkey_algo[PKEY_ALGO__LAST];
 
 /* asymmetric key implementation supports only up to SHA224 */
 #define PKEY_HASH__LAST		(HASH_ALGO_SHA224 + 1)
@@ -45,12 +44,6 @@ extern const char *const pkey_id_type_name[PKEY_ID_TYPE__LAST];
  * part.
  */
 struct public_key {
-	const struct public_key_algorithm *algo;
-	u8	capabilities;
-#define PKEY_CAN_ENCRYPT	0x01
-#define PKEY_CAN_DECRYPT	0x02
-#define PKEY_CAN_SIGN		0x04
-#define PKEY_CAN_VERIFY		0x08
 	enum pkey_algo pkey_algo : 8;
 	enum pkey_id_type id_type : 8;
 	union {
@@ -95,6 +88,7 @@ struct public_key_signature {
 	};
 };
 
+extern struct asymmetric_key_subtype public_key_subtype;
 struct key;
 extern int verify_signature(const struct key *key,
 			    const struct public_key_signature *sig);
@@ -104,4 +98,7 @@ extern struct key *x509_request_asymmetric_key(struct key *keyring,
 					       const struct asymmetric_key_id *kid,
 					       bool partial);
 
+int public_key_verify_signature(const struct public_key *pkey,
+				const struct public_key_signature *sig);
+
 #endif /* _LINUX_PUBLIC_KEY_H */

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH RFC v2 1/2] crypto: add PKE API
  2015-05-06 19:36 ` [PATCH RFC v2 1/2] crypto: add PKE API Tadeusz Struk
@ 2015-05-11  6:03   ` Herbert Xu
  2015-05-11  6:24   ` Herbert Xu
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 19+ messages in thread
From: Herbert Xu @ 2015-05-11  6:03 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: linux-kernel, keescook, jwboyer, richard, steved, qat-linux,
	dhowells, linux-crypto, james.l.morris, jkosina, zohar, davem,
	vgoyal

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 <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH RFC v2 1/2] crypto: add PKE API
  2015-05-06 19:36 ` [PATCH RFC v2 1/2] crypto: add PKE API Tadeusz Struk
  2015-05-11  6:03   ` Herbert Xu
@ 2015-05-11  6:24   ` Herbert Xu
  2015-05-11  6:27   ` Herbert Xu
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 19+ messages in thread
From: Herbert Xu @ 2015-05-11  6:24 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: linux-kernel, keescook, jwboyer, richard, steved, qat-linux,
	dhowells, linux-crypto, james.l.morris, jkosina, zohar, davem,
	vgoyal

On Wed, May 06, 2015 at 12:36:48PM -0700, Tadeusz Struk wrote:
> + * @capabilities:
> + *		Specifies what operations are provided by the algorithm
> + *		implementation.

Don't do this.  It's a nightmare for the user to have to deal with
multiple implementations with differing capabilities.

Make the implementor provide backups/fallbacks.

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH RFC v2 1/2] crypto: add PKE API
  2015-05-06 19:36 ` [PATCH RFC v2 1/2] crypto: add PKE API Tadeusz Struk
  2015-05-11  6:03   ` Herbert Xu
  2015-05-11  6:24   ` Herbert Xu
@ 2015-05-11  6:27   ` Herbert Xu
  2015-05-11  6:32   ` Herbert Xu
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 19+ messages in thread
From: Herbert Xu @ 2015-05-11  6:27 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: linux-kernel, keescook, jwboyer, richard, steved, qat-linux,
	dhowells, linux-crypto, james.l.morris, jkosina, zohar, davem,
	vgoyal

On Wed, May 06, 2015 at 12:36:48PM -0700, Tadeusz Struk wrote:
>
> +struct pkey_request {
> +	struct crypto_async_request base;
> +	const struct public_key *pkey;

The key should not come from the request.  It should go into the
tfm.

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH RFC v2 1/2] crypto: add PKE API
  2015-05-06 19:36 ` [PATCH RFC v2 1/2] crypto: add PKE API Tadeusz Struk
                     ` (2 preceding siblings ...)
  2015-05-11  6:27   ` Herbert Xu
@ 2015-05-11  6:32   ` Herbert Xu
  2015-05-22 18:37     ` Tadeusz Struk
  2015-05-11 13:45   ` David Howells
  2015-06-08 19:34   ` Kees Cook
  5 siblings, 1 reply; 19+ messages in thread
From: Herbert Xu @ 2015-05-11  6:32 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: linux-kernel, keescook, jwboyer, richard, steved, qat-linux,
	dhowells, linux-crypto, james.l.morris, jkosina, zohar, davem,
	vgoyal

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,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH RFC v2 1/2] crypto: add PKE API
  2015-05-06 19:36 ` [PATCH RFC v2 1/2] crypto: add PKE API Tadeusz Struk
                     ` (3 preceding siblings ...)
  2015-05-11  6:32   ` Herbert Xu
@ 2015-05-11 13:45   ` David Howells
  2015-05-12  1:21     ` Herbert Xu
  2015-05-13 15:03     ` David Howells
  2015-06-08 19:34   ` Kees Cook
  5 siblings, 2 replies; 19+ messages in thread
From: David Howells @ 2015-05-11 13:45 UTC (permalink / raw)
  To: Herbert Xu
  Cc: dhowells, Tadeusz Struk, linux-kernel, keescook, jwboyer,
	richard, steved, qat-linux, linux-crypto, james.l.morris,
	jkosina, zohar, davem, vgoyal

Herbert Xu <herbert@gondor.apana.org.au> wrote:

> > + * @capabilities:
> > + *		Specifies what operations are provided by the algorithm
> > + *		implementation.
> 
> Don't do this.  It's a nightmare for the user to have to deal with
> multiple implementations with differing capabilities.
> 
> Make the implementor provide backups/fallbacks.

What if the fallback doesn't exist?  For instance, a H/W contained key is
specifically limited to, say, just sign/verify and the not permitted to be
used for encrypt/decrypt.  How do you provide a fallback given you can't get
at the key?

David

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH RFC v2 1/2] crypto: add PKE API
  2015-05-11 13:45   ` David Howells
@ 2015-05-12  1:21     ` Herbert Xu
  2015-05-13 15:03     ` David Howells
  1 sibling, 0 replies; 19+ messages in thread
From: Herbert Xu @ 2015-05-12  1:21 UTC (permalink / raw)
  To: David Howells
  Cc: Tadeusz Struk, linux-kernel, keescook, jwboyer, richard, steved,
	qat-linux, linux-crypto, james.l.morris, jkosina, zohar, davem,
	vgoyal

On Mon, May 11, 2015 at 02:45:27PM +0100, David Howells wrote:
>
> What if the fallback doesn't exist?  For instance, a H/W contained key is
> specifically limited to, say, just sign/verify and the not permitted to be
> used for encrypt/decrypt.  How do you provide a fallback given you can't get
> at the key?

That's a transform with a specific key.  I don't see why such a
piece of hardware would even need to be exposed through the crypto
API which is about generic implementations that can take any
arbitrary key.

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH RFC v2 1/2] crypto: add PKE API
  2015-05-11 13:45   ` David Howells
  2015-05-12  1:21     ` Herbert Xu
@ 2015-05-13 15:03     ` David Howells
  2015-05-14  2:59       ` Herbert Xu
  1 sibling, 1 reply; 19+ messages in thread
From: David Howells @ 2015-05-13 15:03 UTC (permalink / raw)
  To: Herbert Xu
  Cc: dhowells, Tadeusz Struk, linux-kernel, keescook, jwboyer,
	richard, steved, qat-linux, linux-crypto, james.l.morris,
	jkosina, zohar, davem, vgoyal

Herbert Xu <herbert@gondor.apana.org.au> wrote:

> > What if the fallback doesn't exist?  For instance, a H/W contained key is
> > specifically limited to, say, just sign/verify and the not permitted to be
> > used for encrypt/decrypt.  How do you provide a fallback given you can't get
> > at the key?
> 
> That's a transform with a specific key.  I don't see why such a
> piece of hardware would even need to be exposed through the crypto
> API which is about generic implementations that can take any
> arbitrary key.

So what if we want to use a key that's stored in a TPM?  I presume then we
can't use the crypto interface, but must rather use the *key* as the primary
interface somehow.

David

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH RFC v2 1/2] crypto: add PKE API
  2015-05-13 15:03     ` David Howells
@ 2015-05-14  2:59       ` Herbert Xu
  0 siblings, 0 replies; 19+ messages in thread
From: Herbert Xu @ 2015-05-14  2:59 UTC (permalink / raw)
  To: David Howells
  Cc: Tadeusz Struk, linux-kernel, keescook, jwboyer, richard, steved,
	qat-linux, linux-crypto, james.l.morris, jkosina, zohar, davem,
	vgoyal

On Wed, May 13, 2015 at 04:03:55PM +0100, David Howells wrote:
>
> So what if we want to use a key that's stored in a TPM?  I presume then we
> can't use the crypto interface, but must rather use the *key* as the primary
> interface somehow.

Then it has nothing to do with what we're trying to do here.

The crypto API is providing a generic algorithmic interface for
operations that can then be accelerated by hardware devices.

So anything that cannot be done purely in software does not fall
under our purview.

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH RFC v2 1/2] crypto: add PKE API
  2015-05-11  6:32   ` Herbert Xu
@ 2015-05-22 18:37     ` Tadeusz Struk
  2015-05-23  5:47       ` Herbert Xu
  0 siblings, 1 reply; 19+ messages in thread
From: Tadeusz Struk @ 2015-05-22 18:37 UTC (permalink / raw)
  To: Herbert Xu
  Cc: Linux Kernel Developers List, keescook, jwboyer, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

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;
};

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH RFC v2 1/2] crypto: add PKE API
  2015-05-22 18:37     ` Tadeusz Struk
@ 2015-05-23  5:47       ` Herbert Xu
  2015-05-23 14:20         ` Tadeusz Struk
  0 siblings, 1 reply; 19+ messages in thread
From: Herbert Xu @ 2015-05-23  5:47 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: Linux Kernel Developers List, keescook, jwboyer, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On Fri, May 22, 2015 at 11:37:49AM -0700, Tadeusz Struk wrote:
>
> /**
>  * 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;
> };

I think you should rename them to src/dst and add a length argument.
Limiting them to one entry also seems strange.  When do you need more
one parameter?

> /**
>  * 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);

Looks good.  You'll also need a setkey (or perhaps two) function.

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH RFC v2 1/2] crypto: add PKE API
  2015-05-23  5:47       ` Herbert Xu
@ 2015-05-23 14:20         ` Tadeusz Struk
  2015-05-28  4:08           ` Herbert Xu
  0 siblings, 1 reply; 19+ messages in thread
From: Tadeusz Struk @ 2015-05-23 14:20 UTC (permalink / raw)
  To: Herbert Xu
  Cc: Linux Kernel Developers List, keescook, jwboyer, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On 05/22/2015 10:47 PM, Herbert Xu wrote:
>> struct akcipher_request {
>> > 	struct crypto_async_request base;
>> > 	struct scatterlist *inparams;
>> > 	struct scatterlist *outparams;
>> > 	void *__ctx[] CRYPTO_MINALIGN_ATTR;
>> > };
> I think you should rename them to src/dst and add a length argument.
> Limiting them to one entry also seems strange.  When do you need more
> one parameter?

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.

> 
>> 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);
> Looks good.  You'll also need a setkey (or perhaps two) function.

I have these two:

/**
 * crypto_akcipher_setkey() -- assign a public key to an AKCIPHER tfm handle
 *
 * @tfm: AKCIPHER tfm handle allocated with crypto_alloc_akcipher()
 * @pkey: public key
 */
static inline void crypto_akcipher_setkey(struct crypto_akcipher *tfm,
					  const struct public_key *pkey);

/**
 * crypto_akcipher_getkey() -- obtain a public key from an AKCIPHER tfm handle
 *
 * @tfm: AKCIPHER tfm handle allocated with crypto_alloc_akcipher()
 *
 * Return: public key
 */
static inline const struct public_key *crypto_akcipher_getkey(
	struct crypto_akcipher *tfm);

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH RFC v2 1/2] crypto: add PKE API
  2015-05-23 14:20         ` Tadeusz Struk
@ 2015-05-28  4:08           ` Herbert Xu
  2015-05-28 16:54             ` Tadeusz Struk
  0 siblings, 1 reply; 19+ messages in thread
From: Herbert Xu @ 2015-05-28  4:08 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: Linux Kernel Developers List, keescook, jwboyer, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

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 <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH RFC v2 1/2] crypto: add PKE API
  2015-05-28  4:08           ` Herbert Xu
@ 2015-05-28 16:54             ` Tadeusz Struk
  2015-06-01  5:48               ` Herbert Xu
  0 siblings, 1 reply; 19+ messages in thread
From: Tadeusz Struk @ 2015-05-28 16:54 UTC (permalink / raw)
  To: Herbert Xu
  Cc: Linux Kernel Developers List, keescook, jwboyer, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH RFC v2 1/2] crypto: add PKE API
  2015-05-28 16:54             ` Tadeusz Struk
@ 2015-06-01  5:48               ` Herbert Xu
  2015-06-01 17:52                 ` Tadeusz Struk
  0 siblings, 1 reply; 19+ messages in thread
From: Herbert Xu @ 2015-06-01  5:48 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: Linux Kernel Developers List, keescook, jwboyer, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

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 <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH RFC v2 1/2] crypto: add PKE API
  2015-06-01  5:48               ` Herbert Xu
@ 2015-06-01 17:52                 ` Tadeusz Struk
  0 siblings, 0 replies; 19+ messages in thread
From: Tadeusz Struk @ 2015-06-01 17:52 UTC (permalink / raw)
  To: Herbert Xu
  Cc: Linux Kernel Developers List, keescook, jwboyer, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

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

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH RFC v2 1/2] crypto: add PKE API
  2015-05-06 19:36 ` [PATCH RFC v2 1/2] crypto: add PKE API Tadeusz Struk
                     ` (4 preceding siblings ...)
  2015-05-11 13:45   ` David Howells
@ 2015-06-08 19:34   ` Kees Cook
  5 siblings, 0 replies; 19+ messages in thread
From: Kees Cook @ 2015-06-08 19:34 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: Herbert Xu, LKML, Josh Boyer, Richard Weinberger, steved,
	qat-linux, David Howells, linux-crypto, James Morris,
	Jiri Kosina, Mimi Zohar, David S. Miller, Vivek Goyal

On Wed, May 6, 2015 at 12:36 PM, Tadeusz Struk <tadeusz.struk@intel.com> wrote:
> Add Public Key Encryption API.
>
> Signed-off-by: Tadeusz Struk <tadeusz.struk@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 0000000..ab8c0e9
> --- /dev/null
> +++ b/crypto/pkey.c
> @@ -0,0 +1,125 @@
> +/*
> + * Public Key Encryption
> + *
> + * Copyright (c) 2015, Intel Corporation
> + * Authors: Tadeusz Struk <tadeusz.struk@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", alg->cra_name);
> +       seq_printf(m, "can encrypt  : %s\n",
> +                  cap & PKEY_CAN_ENCRYPT ? "yes" : "no");
> +       seq_printf(m, "can decrypt  : %s\n",
> +                  cap & PKEY_CAN_DECRYPT ? "yes" : "no");
> +       seq_printf(m, "can sign     : %s\n",
> +                  cap & PKEY_CAN_SIGN ? "yes" : "no");
> +       seq_printf(m, "can verify   : %s\n",
> +                  cap & PKEY_CAN_VERIFY ? "yes" : "no");
> +}
> +
> +static int crypto_pkey_init(struct crypto_tfm *tfm)
> +{
> +       return 0;
> +}
> +
> +static const struct crypto_type crypto_pkey_type = {
> +       .extsize = crypto_alg_extsize,
> +       .init_tfm = crypto_pkey_init,
> +#ifdef CONFIG_PROC_FS
> +       .show = crypto_pkey_show,
> +#endif
> +       .report = crypto_pkey_report,
> +       .maskclear = ~CRYPTO_ALG_TYPE_MASK,
> +       .maskset = CRYPTO_ALG_TYPE_MASK,
> +       .type = CRYPTO_ALG_TYPE_PKEY,
> +       .tfmsize = offsetof(struct crypto_pkey, base),
> +};
> +
> +struct crypto_pkey *crypto_alloc_pkey(const char *alg_name, u32 type, u32 mask)
> +{
> +       return crypto_alloc_tfm(alg_name, &crypto_pkey_type, type, mask);
> +}
> +EXPORT_SYMBOL_GPL(crypto_alloc_pkey);
> +
> +int crypto_register_pkey(struct pkey_alg *alg)
> +{
> +       struct crypto_alg *base = &alg->base;
> +
> +       if (alg->n_pub_mpi > 5 || alg->n_sec_mpi > 5 || alg->n_sig_mpi > 2)
> +               return -EINVAL;
> +
> +       if ((alg->capabilities & PKEY_CAN_ENCRYPT) && !alg->encrypt)
> +               return -EINVAL;
> +
> +       if ((alg->capabilities & PKEY_CAN_DECRYPT) && !alg->decrypt)
> +               return -EINVAL;
> +
> +       if ((alg->capabilities & PKEY_CAN_SIGN) && !alg->sign)
> +               return -EINVAL;
> +
> +       if ((alg->capabilities & PKEY_CAN_VERIFY) && !alg->verify)
> +               return -EINVAL;
> +
> +       base->cra_type = &crypto_pkey_type;
> +       base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
> +       base->cra_flags |= CRYPTO_ALG_TYPE_PKEY;
> +
> +       return crypto_register_alg(base);
> +}
> +EXPORT_SYMBOL_GPL(crypto_register_pkey);
> +
> +void crypto_unregister_pkey(struct pkey_alg *alg)
> +{
> +       crypto_unregister_alg(&alg->base);
> +}
> +EXPORT_SYMBOL_GPL(crypto_unregister_pkey);
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("Generic public key type");
> diff --git a/include/crypto/pkey.h b/include/crypto/pkey.h
> new file mode 100644
> index 0000000..abcdb11
> --- /dev/null
> +++ b/include/crypto/pkey.h
> @@ -0,0 +1,390 @@
> +/*
> + * Public Key Encryption
> + *
> + * Copyright (c) 2015, Intel Corporation
> + * Authors: Tadeusz Struk <tadeusz.struk@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.
> + *
> + */
> +#ifndef _CRYPTO_PKEY_H
> +#define _CRYPTO_PKEY_H
> +#include <linux/crypto.h>
> +
> +struct public_key;
> +struct public_key_signature;
> +
> +/**
> + * struct pkey_request - public key request
> + *
> + * @base:      Common attributes for async crypto requests
> + * @pkey:      Public key data for the subtype of the asymmetric key.
> + *             It may include private part of the key as well as
> + *             the public part.
> + * @signature: Public key signature data.
> + * @__ctx:     Start of private context data.
> + */
> +struct pkey_request {
> +       struct crypto_async_request base;
> +       const struct public_key *pkey;
> +       const struct public_key_signature *signature;
> +       void *__ctx[] CRYPTO_MINALIGN_ATTR;
> +};
> +
> +/**
> + * struct pkey_alg - generic public key algorithm
> + *
> + * @sign:      Function performs a sign operation as defined by public key
> + *             algorithm. PKEY_CAN_SIGN bit in capabilities mask denotes
> + *             if it is provided by algorithm.
> + * @verify:    Function performs a sign operation as defined by public key
> + *             algorithm. PKEY_CAN_VERIFY bit in capabilities mask denotes
> + *             if it is provided by algorithm.
> + * @encrypt:   Function performs an encrytp operation as defined by public key
> + *             algorithm. PKEY_CAN_ENCRYPT bit in capabilities maks denotes
> + *             if it is provided by algorithm.
> + * @decrypt:   Function performs a decrypt operation as defined by public key
> + *             algorithm. PKEY_CAN_DECRYPT bit in capabilities maks denotes
> + *             if it is provided by algorithm.
> + * @n_pub_mpi: Minimun number of MPIs (Multi Precision Integers) in public key
> + *             parameter in the pkey request as expected by the algorithm.
> + * @n_sec_mpi: Minimun number of MPIs (Multi Precision Integers) in secret key
> + *             parameter in the pkey request as expected by the algorithm.
> + * @n_sig_mpi: Minimun number of MPIs (Multi Precision Integers) in signature
> + *             parameter in the pkey request as expected by the algorithm.
> + * @capabilities:
> + *             Specifies what operations are provided by the algorithm
> + *             implementation.
> + * @reqsize:   Request context size required by algorithm implementation.
> + * @base:      Common crypto API algorithm data structure.
> + */
> +struct pkey_alg {
> +       int (*sign)(struct pkey_request *pkeyreq);
> +       int (*verify)(struct pkey_request *pkeyreq);
> +       int (*encrypt)(struct pkey_request *pkeyreq);
> +       int (*decrypt)(struct pkey_request *pkeyreq);
> +
> +       u8 n_pub_mpi;
> +       u8 n_sec_mpi;
> +       u8 n_sig_mpi;
> +#define PKEY_CAN_ENCRYPT       0x01
> +#define PKEY_CAN_DECRYPT       0x02
> +#define PKEY_CAN_SIGN          0x04
> +#define PKEY_CAN_VERIFY                0x08
> +       u8 capabilities;
> +       unsigned int reqsize;
> +       struct crypto_alg base;
> +};
> +
> +/**
> + * struct crypto_pkey - user-instantiated objects which encapsulate algorithms
> + * and core processing logic.
> + *
> + * @base:      Common crypto API algorithm data structure.
> + * @__ctx:     Start of private context data
> + */
> +struct crypto_pkey {
> +       struct crypto_tfm base;
> +       void *__ctx[] CRYPTO_MINALIGN_ATTR;
> +};
> +
> +/**
> + * DOC: Generic Public Key API
> + *
> + * The Public Key API is used with the algorithms of type
> + * CRYPTO_ALG_TYPE_PKEY (listed as type "pkey" in /proc/crypto)
> + */
> +
> +/**
> + * crypto_alloc_pkey() -- allocate PKEY tfm handle
> + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the
> + *           public key algorithm e.g. "rsa"
> + * @type: specifies the type of the algorithm
> + * @mask: specifies the mask for the algorithm
> + *
> + * Allocate a handle for public key algorithm. The returned struct
> + * crypto_pkey is the handle that is required for any subsequent
> + * API invocation for the public key operations.
> + *
> + * Return: allocated handle in case of success; IS_ERR() is true in case
> + *        of an error, PTR_ERR() returns the error code.
> + */
> +struct crypto_pkey *crypto_alloc_pkey(const char *alg_name, u32 type, u32 mask);
> +
> +/*
> + * Transform internal helpers.
> + */
> +static inline struct pkey_alg *__crypto_pkey_alg(struct crypto_alg *alg)
> +{
> +       return container_of(alg, struct pkey_alg, base);
> +}
> +
> +static inline struct crypto_pkey *__crypto_pkey_tfm(struct crypto_tfm *tfm)
> +{
> +       return container_of(tfm, struct crypto_pkey, base);
> +}
> +
> +static inline struct crypto_tfm *crypto_pkey_tfm(struct crypto_pkey *tfm)
> +{
> +       return &tfm->base;
> +}
> +
> +static inline struct pkey_alg *crypto_pkey_alg(struct crypto_pkey *tfm)
> +{
> +       return __crypto_pkey_alg(crypto_pkey_tfm(tfm)->__crt_alg);
> +}
> +
> +/**
> + * crypto_free_pkey() -- free PKEY tfm handle
> + *
> + * @tfm: PKEY tfm handle allocated with crypto_alloc_pkey()
> + */
> +static inline void crypto_free_pkey(struct crypto_pkey *tfm)
> +{
> +       crypto_destroy_tfm(tfm, crypto_pkey_tfm(tfm));
> +}
> +
> +static inline unsigned int crypto_pkey_reqsize(struct crypto_pkey *tfm)
> +{
> +       return crypto_pkey_alg(tfm)->reqsize;
> +}
> +
> +static inline void pkey_request_set_tfm(struct pkey_request *req,
> +                                       struct crypto_pkey *tfm)
> +{
> +       req->base.tfm = crypto_pkey_tfm(tfm);
> +}
> +
> +/**
> + * pkey_request_alloc() -- allocates public key request
> + *
> + * @tfm:       PKEY tfm handle allocated with crypto_alloc_pkey()
> + * @gfp:       allocation flags
> + *
> + * Return: allocated handle in case of success or NULL in case of an error.
> + */
> +static inline struct pkey_request *pkey_request_alloc(struct crypto_pkey *tfm,
> +                                                     gfp_t gfp)
> +{
> +       struct pkey_request *req;
> +
> +       req = kmalloc(sizeof(*req) + crypto_pkey_reqsize(tfm), gfp);
> +       if (likely(req))
> +               pkey_request_set_tfm(req, tfm);
> +
> +       return req;
> +}
> +
> +static inline void *pkey_request_ctx(struct pkey_request *req)
> +{
> +       return req->__ctx;
> +}
> +
> +/**
> + * pkey_request_free() -- zeroize and free public key request
> + *
> + * @req:       request to free
> + */
> +static inline void pkey_request_free(struct pkey_request *req)
> +{
> +       kzfree(req);
> +}
> +
> +/**
> + * pkey_request_set_callback() -- Sets an asynchronous callback.
> + *
> + * Callback will be called when an asynchronous operation on a given
> + * request is finished.
> + *
> + * @req:       request that the callback will be set for.
> + * @flgs:      specify for instance if the operation may backlog.
> + * @cmlp:      callback which will be called.
> + * @data:      private data used by the caller.
> + */
> +static inline void pkey_request_set_callback(struct pkey_request *req, u32 flgs,
> +                                            crypto_completion_t cmpl,
> +                                            void *data)
> +{
> +       req->base.complete = cmpl;
> +       req->base.data = data;
> +       req->base.flags = flgs;
> +}
> +
> +static inline void pkey_request_complete(struct pkey_request *req, int err)
> +{
> +       req->base.complete(&req->base, err);
> +}
> +
> +/**
> + * pkey_request_set_crypt() -- Sets reqest parameters.
> + *
> + * Sets parameters required by crypto operation.
> + *
> + * @req:       public key.
> + * @sig:       public key signature.
> + */
> +static inline void pkey_request_set_crypt(struct pkey_request *req,
> +                                         const struct public_key *pkey,
> +                                         const struct public_key_signature *sg)
> +{
> +       req->pkey = pkey;
> +       req->signature = sg;
> +}
> +
> +/**
> + * pkey_num_sig_mpi() -- Returns number of MPIs in signature
> + *
> + * Function returns number of MPIs (Multi Precision Integers) in signature
> + * parameter as expected by the algorithm.
> + *
> + * @tfm:       tfm handle.
> + *
> + * Return: number of MPIs in signature.
> + */
> +static inline u8 pkey_num_sig_mpi(struct crypto_pkey *tfm)
> +{
> +       return crypto_pkey_alg(tfm)->n_sig_mpi;
> +}
> +
> +/**
> + * pkey_num_pub_mpi() -- Returns number of MPIs in public key
> + *
> + * Function returns number of MPIs (Multi Precision Integers) in public key
> + * parameter as expected by the algorithm.
> + *
> + * @tfm:       tfm handle.
> + *
> + * Return: number of MPIs in public key.
> + */
> +static inline u8 pkey_num_pub_mpi(struct crypto_pkey *tfm)
> +{
> +       return crypto_pkey_alg(tfm)->n_pub_mpi;
> +}
> +
> +/**
> + * pkey_num_sec_mpi() -- Returns number of MPIs in secret key
> + *
> + * Function returns number of MPIs (Multi Precision Integers) in secret key
> + * parameter as expected by the algorithm.
> + *
> + * @tfm:       tfm handle.
> + *
> + * Return: number of MPIs in secret key.
> + */
> +static inline u8 pkey_num_sec_mpi(struct crypto_pkey *tfm)
> +{
> +       return crypto_pkey_alg(tfm)->n_sec_mpi;
> +}
> +
> +/**
> + * pkey_capabilities() -- Returns cababilities
> + *
> + * Function returns bitmask of capabilities denoting what public key operations
> + * are supported by the algorithm.
> + *
> + * @tfm:       tfm handle.
> + *
> + * Return: capabilities mask.
> + */
> +static inline u8 pkey_capabilities(struct crypto_pkey *tfm)
> +{
> +       return crypto_pkey_alg(tfm)->capabilities;
> +}
> +
> +/**
> + * pkey_capab() -- Returns algorithm name
> + *
> + * Function returns public key algorithm name e.g.g "rsa".
> + *
> + * @tfm:       tfm handle.
> + *
> + * Return: public key algorithm name.
> + */
> +static inline const char *pkey_alg_name(struct crypto_pkey *tfm)
> +{
> +       return crypto_pkey_tfm(tfm)->__crt_alg->cra_name;
> +}
> +
> +/**
> + * crypto_pkey_encrypt() -- Invoke public key encrypt operation
> + *
> + * Function invokes the specific public key encrypt operation for a given
> + * public key algorithm.
> + *
> + * @tfm:       tfm handle.
> + *
> + * Return: zero on success; error code in case of error.
> + */
> +static inline int crypto_pkey_encrypt(struct pkey_request *req)
> +{
> +       return crypto_pkey_alg(__crypto_pkey_tfm(req->base.tfm))->encrypt(req);
> +}
> +
> +/**
> + * crypto_pkey_encrypt() -- Invoke public key decrypt operation
> + *
> + * Function invokes the specific public key decrypt operation for a given
> + * public key algorithm.
> + *
> + * @tfm:       tfm handle.
> + *
> + * Return: zero on success; error code in case of error.
> + */
> +static inline int crypto_pkey_decrypt(struct pkey_request *req)
> +{
> +       return crypto_pkey_alg(__crypto_pkey_tfm(req->base.tfm))->decrypt(req);
> +}
> +
> +/**
> + * crypto_pkey_encrypt() -- Invoke public key sign operation
> + *
> + * Function invokes the specific public key sign operation for a given
> + * public key algorithm.
> + *
> + * @tfm:       tfm handle.
> + *
> + * Return: zero on success; error code in case of error.
> + */
> +static inline int crypto_pkey_sign(struct pkey_request *req)
> +{
> +       return crypto_pkey_alg(__crypto_pkey_tfm(req->base.tfm))->sign(req);
> +}
> +
> +/**
> + * crypto_pkey_encrypt() -- Invoke public key verify operation
> + *
> + * Function invokes the specific public key verify operation for a given
> + * public key algorithm.
> + *
> + * @tfm:       tfm handle.
> + *
> + * Return: zero on success; error code in case of error.
> + */
> +static inline int crypto_pkey_verify(struct pkey_request *req)
> +{
> +       return crypto_pkey_alg(__crypto_pkey_tfm(req->base.tfm))->verify(req);
> +}
> +
> +/**
> + * crypto_register_pkey() -- Register public key algorithm
> + *
> + * Function registers an implementation of a public key verify algorithm.
> + *
> + * @alg:       algorithm definition.
> + *
> + * Return: zero on success; error code in case of error.
> + */
> +int crypto_register_pkey(struct pkey_alg *alg);
> +
> +/**
> + * crypto_unregister_pkey() -- Unregister public key algorithm
> + *
> + * Function unregisters an implementation of a public key verify algorithm.
> + *
> + * @alg:       algorithm definition.
> + */
> +void crypto_unregister_pkey(struct pkey_alg *alg);
> +#endif
> diff --git a/include/linux/crypto.h b/include/linux/crypto.h
> index ee14140..61842c9 100644
> --- a/include/linux/crypto.h
> +++ b/include/linux/crypto.h
> @@ -53,6 +53,7 @@
>  #define CRYPTO_ALG_TYPE_SHASH          0x00000009
>  #define CRYPTO_ALG_TYPE_AHASH          0x0000000a
>  #define CRYPTO_ALG_TYPE_RNG            0x0000000c
> +#define CRYPTO_ALG_TYPE_PKEY           0x0000000d
>  #define CRYPTO_ALG_TYPE_PCOMPRESS      0x0000000f
>
>  #define CRYPTO_ALG_TYPE_HASH_MASK      0x0000000e
> diff --git a/include/linux/cryptouser.h b/include/linux/cryptouser.h
> index 4abf2ea..fdf9120 100644
> --- a/include/linux/cryptouser.h
> +++ b/include/linux/cryptouser.h
> @@ -43,6 +43,7 @@ enum crypto_attr_type_t {
>         CRYPTOCFGA_REPORT_COMPRESS,     /* struct crypto_report_comp */
>         CRYPTOCFGA_REPORT_RNG,          /* struct crypto_report_rng */
>         CRYPTOCFGA_REPORT_CIPHER,       /* struct crypto_report_cipher */
> +       CRYPTOCFGA_REPORT_PKEY,         /* struct crypto_report_pkey */
>         __CRYPTOCFGA_MAX
>
>  #define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
> @@ -101,5 +102,11 @@ struct crypto_report_rng {
>         unsigned int seedsize;
>  };
>
> +struct crypto_report_pkey {
> +       char type[CRYPTO_MAX_NAME];
> +       char subtype[CRYPTO_MAX_NAME];
> +       unsigned int capabilities;
> +};
> +
>  #define CRYPTO_REPORT_MAXSIZE (sizeof(struct crypto_user_alg) + \
>                                sizeof(struct crypto_report_blkcipher))
>

Thanks!

-Kees

-- 
Kees Cook
Chrome OS Security

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2015-06-08 19:34 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-06 19:36 [PATCH RFC v2 0/2] crypto: Introduce Public Key Encryption API Tadeusz Struk
2015-05-06 19:36 ` [PATCH RFC v2 1/2] crypto: add PKE API Tadeusz Struk
2015-05-11  6:03   ` Herbert Xu
2015-05-11  6:24   ` Herbert Xu
2015-05-11  6:27   ` Herbert Xu
2015-05-11  6:32   ` Herbert Xu
2015-05-22 18:37     ` Tadeusz Struk
2015-05-23  5:47       ` Herbert Xu
2015-05-23 14:20         ` Tadeusz Struk
2015-05-28  4:08           ` Herbert Xu
2015-05-28 16:54             ` Tadeusz Struk
2015-06-01  5:48               ` Herbert Xu
2015-06-01 17:52                 ` Tadeusz Struk
2015-05-11 13:45   ` David Howells
2015-05-12  1:21     ` Herbert Xu
2015-05-13 15:03     ` David Howells
2015-05-14  2:59       ` Herbert Xu
2015-06-08 19:34   ` Kees Cook
2015-05-06 19:36 ` [PATCH RFC v2 2/2] crypto: RSA: KEYS: convert rsa and public key to new " Tadeusz Struk

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.