All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC v5 0/4] crypto: Introduce Public Key Encryption API
@ 2015-06-15 20:18 Tadeusz Struk
  2015-06-15 20:18 ` [PATCH RFC v5 1/4] MPILIB: add mpi_read_buf() and mpi_get_size() helpers Tadeusz Struk
                   ` (3 more replies)
  0 siblings, 4 replies; 33+ messages in thread
From: Tadeusz Struk @ 2015-06-15 20:18 UTC (permalink / raw)
  To: herbert
  Cc: linux-kernel, keescook, jwboyer, smueller, 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_akcipher_type,
plus new struct akcipher_alg and struct crypto_akcipher, together with number
of helper functions to register akcipher 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 akcipher_request *req);
	int (*verify)(struct akcipher_request *req);
	int (*encrypt)(struct akcipher_request *req);
	int (*decrypt)(struct akcipher_request *req);

The benefits it gives 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 crypto_akcipher 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_akcipher *tfm = crypto_alloc_akcipher("rsa", 0, 0);
	struct akcipher_request *req = akcipher_request_alloc(tfm, GFP_KERNEL);
	akcipher_request_set_crypt(req, pub_key, signature);
	int ret = crypto_akcipher_verify(src, dst, src_len, dst_len, &res_len);
	akcipher_request_free(req);
	crypto_free_akcipher(tfm);
	return ret;

Changes in v5:
 - make mpi_get_size() function inline.
 - add a setkey function to the algorithm and rsa_parse_key() helper to
   parse rsa keys from BER encoded to MPI. The helper will also validate
   the given key if it is strong enough in case FIPS mode is enabled.
 - change the format of the key from struct public_key * to void * BER encoded
   buffer.
 - change the format of the rsa keys in testmgr to BER encoded form.
 - change mpi_free to use kzfree instead of kfree because it is used to free
   crypto keys

Changes in v4:
 - add an rsa generic implementation
 - don't convert the existing public_key implementation to the new interface.
   This will be done after the new interface is accepted.
 - add new mpi_get_buf(), mpi_copy() and mpi_get_size() mpi helpers 
 - on set key the ftm now will clone the key instead of just setting a ptr
 - add a check on enc/dec/sign/veryfi to make sure a valid (public or private)
   key is setup
 - add maxsize fn into algorith that will be used to query implementation
   what is the max size of a result for a give public key that the user needs
   to allocate
 - removed private ctx from crypto_akcipher as the crypto_tfm base has one
   already
 - add 2K bit RSA test vectors
 - add cipher text validation in crypto test mgr as (required for FIPS)

Changes in v3:
 - changed input and output parameters type from sgl to void *
   and added separate src_len & dst_len - requested by Herbert Xu
 - separated rsa implementation into cryptographic primitives and
   left encryption scheme details outside of the algorithm implementation
 - added SW implementation for RSA encrypt, decrypt and sign operation
 - added RSA test vectors 
   
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 (4):
      MPILIB: add mpi_read_buf(), mpi_copy() and mpi_get_size() helpers
      crypto: add PKE API
      crypto: rsa: add a new rsa generic implementation
      crypto: add tests vectors for RSA


 crypto/Kconfig                |   14 +
 crypto/Makefile               |    9 +
 crypto/akcipher.c             |  102 ++++++++++
 crypto/crypto_user.c          |   23 ++
 crypto/rsa.c                  |  295 ++++++++++++++++++++++++++++++
 crypto/rsa_helper.c           |  134 ++++++++++++++
 crypto/rsakey.asn1            |    5 +
 crypto/testmgr.c              |  149 +++++++++++++++
 crypto/testmgr.h              |  143 +++++++++++++++
 include/crypto/akcipher.h     |  404 +++++++++++++++++++++++++++++++++++++++++
 include/crypto/internal/rsa.h |   30 +++
 include/linux/crypto.h        |    1 
 include/linux/cryptouser.h    |    6 +
 include/linux/mpi.h           |   15 ++
 lib/mpi/mpicoder.c            |   87 +++++++--
 lib/mpi/mpiutil.c             |   38 ++++
 16 files changed, 1434 insertions(+), 21 deletions(-)
 create mode 100644 crypto/akcipher.c
 create mode 100644 crypto/rsa.c
 create mode 100644 crypto/rsa_helper.c
 create mode 100644 crypto/rsakey.asn1
 create mode 100644 include/crypto/akcipher.h
 create mode 100644 include/crypto/internal/rsa.h
-- 

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

* [PATCH RFC v5 1/4] MPILIB: add mpi_read_buf() and mpi_get_size() helpers
  2015-06-15 20:18 [PATCH RFC v5 0/4] crypto: Introduce Public Key Encryption API Tadeusz Struk
@ 2015-06-15 20:18 ` Tadeusz Struk
  2015-06-16  6:40   ` Herbert Xu
  2015-06-15 20:18 ` [PATCH RFC v5 2/4] crypto: add PKE API Tadeusz Struk
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 33+ messages in thread
From: Tadeusz Struk @ 2015-06-15 20:18 UTC (permalink / raw)
  To: herbert
  Cc: linux-kernel, keescook, jwboyer, smueller, richard,
	tadeusz.struk, steved, qat-linux, dhowells, linux-crypto,
	james.l.morris, jkosina, zohar, davem, vgoyal

Added a mpi_read_buf() helper function to export MPI to a buf provided by
the user, and a mpi_get_size() helper, that tells the user how big the buf is.
Changed mpi_free to use kzfree instead of kfree because it is used to free
crypto keys.

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
 include/linux/mpi.h |   15 +++++++++
 lib/mpi/mpicoder.c  |   87 ++++++++++++++++++++++++++++++++++++++++-----------
 lib/mpi/mpiutil.c   |    6 ++--
 3 files changed, 86 insertions(+), 22 deletions(-)

diff --git a/include/linux/mpi.h b/include/linux/mpi.h
index 5af1b81..641b7d6 100644
--- a/include/linux/mpi.h
+++ b/include/linux/mpi.h
@@ -81,6 +81,8 @@ MPI mpi_read_from_buffer(const void *buffer, unsigned *ret_nread);
 int mpi_fromstr(MPI val, const char *str);
 u32 mpi_get_keyid(MPI a, u32 *keyid);
 void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign);
+int mpi_read_buffer(MPI a, uint8_t *buf, unsigned buf_len, unsigned *nbytes,
+		    int *sign);
 void *mpi_get_secure_buffer(MPI a, unsigned *nbytes, int *sign);
 int mpi_set_buffer(MPI a, const void *buffer, unsigned nbytes, int sign);
 
@@ -142,4 +144,17 @@ int mpi_rshift(MPI x, MPI a, unsigned n);
 /*-- mpi-inv.c --*/
 int mpi_invm(MPI x, MPI u, MPI v);
 
+/* inline functions */
+
+/**
+ * mpi_get_size() - returns max size required to store the number
+ *
+ * @a:	A multi precision integer for which we want to allocate a bufer
+ *
+ * Return: size required to store the number
+ */
+static inline unsigned int mpi_get_size(MPI a)
+{
+	return a->nlimbs * BYTES_PER_MPI_LIMB;
+}
 #endif /*G10_MPI_H */
diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c
index 4cc6442..bc0a1da 100644
--- a/lib/mpi/mpicoder.c
+++ b/lib/mpi/mpicoder.c
@@ -128,28 +128,36 @@ leave:
 }
 EXPORT_SYMBOL_GPL(mpi_read_from_buffer);
 
-/****************
- * Return an allocated buffer with the MPI (msb first).
- * NBYTES receives the length of this buffer. Caller must free the
- * return string (This function does return a 0 byte buffer with NBYTES
- * set to zero if the value of A is zero. If sign is not NULL, it will
- * be set to the sign of the A.
+/**
+ * mpi_read_buffer() - read MPI to a bufer provided by user (msb first)
+ *
+ * @a:		a multi precision integer
+ * @buf:	bufer to which the output will be written to. Needs to be at
+ *		leaset mpi_get_size(a) long.
+ * @buf_len:	size of the buf.
+ * @nbytes:	receives the actual length of the data written.
+ * @sign:	if not NULL, it will be set to the sign of a.
+ *
+ * Return:	0 on success or error code in case of error
  */
-void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign)
+int mpi_read_buffer(MPI a, uint8_t *buf, unsigned buf_len, unsigned *nbytes,
+		    int *sign)
 {
-	uint8_t *p, *buffer;
+	uint8_t *p;
 	mpi_limb_t alimb;
+	unsigned int n = mpi_get_size(a);
 	int i;
-	unsigned int n;
+
+	if (buf_len < n || !buf)
+		return -EINVAL;
 
 	if (sign)
 		*sign = a->sign;
-	*nbytes = n = a->nlimbs * BYTES_PER_MPI_LIMB;
-	if (!n)
-		n++;		/* avoid zero length allocation */
-	p = buffer = kmalloc(n, GFP_KERNEL);
-	if (!p)
-		return NULL;
+
+	if (nbytes)
+		*nbytes = n;
+
+	p = buf;
 
 	for (i = a->nlimbs - 1; i >= 0; i--) {
 		alimb = a->d[i];
@@ -171,15 +179,56 @@ void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign)
 #error please implement for this limb size.
 #endif
 	}
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mpi_read_buffer);
+
+/*
+ * mpi_get_buffer() - Returns an allocated buffer with the MPI (msb first).
+ * Caller must free the return string.
+ * This function does return a 0 byte buffer with nbytes set to zero if the
+ * value of A is zero.
+ *
+ * @a:		a multi precision integer.
+ * @nbytes:	receives the length of this buffer.
+ * @sign:	if not NULL, it will be set to the sign of the a.
+ *
+ * Return:	Pointer to MPI buffer or NULL on error
+ */
+void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign)
+{
+	uint8_t *buf, *p;
+	unsigned int n;
+	int ret;
+
+	if (!nbytes)
+		return NULL;
+
+	n = mpi_get_size(a);
+
+	if (!n)
+		n++;
+
+	buf = kmalloc(n, GFP_KERNEL);
+
+	if (!buf)
+		return NULL;
+
+	ret = mpi_read_buffer(a, buf, n, nbytes, sign);
+
+	if (ret) {
+		kfree(buf);
+		return NULL;
+	}
 
 	/* this is sub-optimal but we need to do the shift operation
 	 * because the caller has to free the returned buffer */
-	for (p = buffer; !*p && *nbytes; p++, --*nbytes)
+	for (p = buf; !*p && *nbytes; p++, --*nbytes)
 		;
-	if (p != buffer)
-		memmove(buffer, p, *nbytes);
+	if (p != buf)
+		memmove(buf, p, *nbytes);
 
-	return buffer;
+	return buf;
 }
 EXPORT_SYMBOL_GPL(mpi_get_buffer);
 
diff --git a/lib/mpi/mpiutil.c b/lib/mpi/mpiutil.c
index bf076d2..314f4df 100644
--- a/lib/mpi/mpiutil.c
+++ b/lib/mpi/mpiutil.c
@@ -69,7 +69,7 @@ void mpi_free_limb_space(mpi_ptr_t a)
 	if (!a)
 		return;
 
-	kfree(a);
+	kzfree(a);
 }
 
 void mpi_assign_limb_space(MPI a, mpi_ptr_t ap, unsigned nlimbs)
@@ -95,7 +95,7 @@ int mpi_resize(MPI a, unsigned nlimbs)
 		if (!p)
 			return -ENOMEM;
 		memcpy(p, a->d, a->alloced * sizeof(mpi_limb_t));
-		kfree(a->d);
+		kzfree(a->d);
 		a->d = p;
 	} else {
 		a->d = kzalloc(nlimbs * sizeof(mpi_limb_t), GFP_KERNEL);
@@ -112,7 +112,7 @@ void mpi_free(MPI a)
 		return;
 
 	if (a->flags & 4)
-		kfree(a->d);
+		kzfree(a->d);
 	else
 		mpi_free_limb_space(a->d);
 

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

* [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-15 20:18 [PATCH RFC v5 0/4] crypto: Introduce Public Key Encryption API Tadeusz Struk
  2015-06-15 20:18 ` [PATCH RFC v5 1/4] MPILIB: add mpi_read_buf() and mpi_get_size() helpers Tadeusz Struk
@ 2015-06-15 20:18 ` Tadeusz Struk
  2015-06-15 23:46   ` Herbert Xu
                     ` (5 more replies)
  2015-06-15 20:18 ` [PATCH RFC v5 3/4] crypto: rsa: add a new rsa generic implementation Tadeusz Struk
  2015-06-15 20:18 ` [PATCH RFC v5 4/4] crypto: add tests vectors for RSA Tadeusz Struk
  3 siblings, 6 replies; 33+ messages in thread
From: Tadeusz Struk @ 2015-06-15 20:18 UTC (permalink / raw)
  To: herbert
  Cc: linux-kernel, keescook, jwboyer, smueller, 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/akcipher.c          |  102 +++++++++++
 crypto/crypto_user.c       |   23 +++
 include/crypto/akcipher.h  |  404 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/crypto.h     |    1 
 include/linux/cryptouser.h |    6 +
 7 files changed, 543 insertions(+)
 create mode 100644 crypto/akcipher.c
 create mode 100644 include/crypto/akcipher.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index f6fc054..ed413d9 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -91,6 +91,12 @@ config CRYPTO_PCOMP2
 	tristate
 	select CRYPTO_ALGAPI2
 
+config CRYPTO_AKCIPHER
+	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 c842035..6f2940a 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -28,6 +28,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
+obj-$(CONFIG_CRYPTO_AKCIPHER) += akcipher.o
 
 cryptomgr-y := algboss.o testmgr.o
 
diff --git a/crypto/akcipher.c b/crypto/akcipher.c
new file mode 100644
index 0000000..be65374
--- /dev/null
+++ b/crypto/akcipher.c
@@ -0,0 +1,102 @@
+/*
+ * 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/akcipher.h>
+#include <crypto/public_key.h>
+#include "internal.h"
+
+#ifdef CONFIG_NET
+static int crypto_akcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+	struct crypto_report_akcipher rakcipher;
+
+	strncpy(rakcipher.type, "akcipher", sizeof(rakcipher.type));
+	strncpy(rakcipher.subtype, alg->cra_name, sizeof(rakcipher.subtype));
+
+	if (nla_put(skb, CRYPTOCFGA_REPORT_AKCIPHER,
+		    sizeof(struct crypto_report_akcipher), &rakcipher))
+		goto nla_put_failure;
+	return 0;
+
+nla_put_failure:
+	return -EMSGSIZE;
+}
+#else
+static int crypto_akcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+	return -ENOSYS;
+}
+#endif
+
+static void crypto_akcipher_show(struct seq_file *m, struct crypto_alg *alg)
+	__attribute__ ((unused));
+
+static void crypto_akcipher_show(struct seq_file *m, struct crypto_alg *alg)
+{
+	seq_puts(m, "type         : akcipher\n");
+	seq_printf(m, "subtype      : %s\n", alg->cra_name);
+}
+
+static int crypto_akcipher_init_tfm(struct crypto_tfm *tfm)
+{
+	return 0;
+}
+
+static const struct crypto_type crypto_akcipher_type = {
+	.extsize = crypto_alg_extsize,
+	.init_tfm = crypto_akcipher_init_tfm,
+#ifdef CONFIG_PROC_FS
+	.show = crypto_akcipher_show,
+#endif
+	.report = crypto_akcipher_report,
+	.maskclear = ~CRYPTO_ALG_TYPE_MASK,
+	.maskset = CRYPTO_ALG_TYPE_MASK,
+	.type = CRYPTO_ALG_TYPE_AKCIPHER,
+	.tfmsize = offsetof(struct crypto_akcipher, base),
+};
+
+struct crypto_akcipher *crypto_alloc_akcipher(const char *alg_name, u32 type,
+					      u32 mask)
+{
+	return crypto_alloc_tfm(alg_name, &crypto_akcipher_type, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_alloc_akcipher);
+
+int crypto_register_akcipher(struct akcipher_alg *alg)
+{
+	struct crypto_alg *base = &alg->base;
+
+	base->cra_type = &crypto_akcipher_type;
+	base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
+	base->cra_flags |= CRYPTO_ALG_TYPE_AKCIPHER;
+	return crypto_register_alg(base);
+}
+EXPORT_SYMBOL_GPL(crypto_register_akcipher);
+
+void crypto_unregister_akcipher(struct akcipher_alg *alg)
+{
+	crypto_unregister_alg(&alg->base);
+}
+EXPORT_SYMBOL_GPL(crypto_unregister_akcipher);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic public key cihper type");
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 41dfe76..508e71d 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/akcipher.h>
 
 #include "internal.h"
 
@@ -110,6 +111,22 @@ nla_put_failure:
 	return -EMSGSIZE;
 }
 
+static int crypto_report_akcipher(struct sk_buff *skb, struct crypto_alg *alg)
+{
+	struct crypto_report_akcipher rakcipher;
+
+	strncpy(rakcipher.type, "akcipher", sizeof(rakcipher.type));
+	strncpy(rakcipher.subtype, alg->cra_name, sizeof(rakcipher.subtype));
+
+	if (nla_put(skb, CRYPTOCFGA_REPORT_AKCIPHER,
+		    sizeof(struct crypto_report_akcipher), &rakcipher))
+		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 +171,12 @@ static int crypto_report_one(struct crypto_alg *alg,
 			goto nla_put_failure;
 
 		break;
+
+	case CRYPTO_ALG_TYPE_AKCIPHER:
+		if (crypto_report_akcipher(skb, alg))
+			goto nla_put_failure;
+
+		break;
 	}
 
 out:
diff --git a/include/crypto/akcipher.h b/include/crypto/akcipher.h
new file mode 100644
index 0000000..0f0ed75
--- /dev/null
+++ b/include/crypto/akcipher.h
@@ -0,0 +1,404 @@
+/*
+ * 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_AKCIPHER_H
+#define _CRYPTO_AKCIPHER_H
+#include <linux/crypto.h>
+
+/**
+ * struct akcipher_request - public key request
+ *
+ * @base:	Common attributes for async crypto requests
+ * @src:	Pointer to memory containing the input parameters
+ *		The format of the parameter(s) is expeted to be Octet String
+ * @dst:	Pointer to memory whare the result will be stored
+ * @src_len:	Size of the input parameter
+ * @dst_len:	Size of the output buffer. It needs to be at leaset
+ *		as big as the expected result depending	on the operation
+ * @result_len: If not NULL this will be updated by the implementation to
+ *		reflect the acctual size of the result
+ * @__ctx:	Start of private context data
+ */
+struct akcipher_request {
+	struct crypto_async_request base;
+	void *src;
+	void *dst;
+	unsigned int src_len;
+	unsigned int dst_len;
+	unsigned int *result_len;
+	void *__ctx[] CRYPTO_MINALIGN_ATTR;
+};
+
+/**
+ * struct crypto_akcipher - user-instantiated objects which encapsulate
+ * algorithms and core processing logic
+ *
+ * @key:	Key representation. Note: this can be both public or private
+ *		key, depending on the operation.
+ * @base:	Common crypto API algorithm data structure
+ */
+struct crypto_akcipher {
+	void *key;
+	struct crypto_tfm base;
+};
+
+/**
+ * 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 encrytp operation as defined by public key
+ *		algorithm
+ * @decrypt:	Function performs a decrypt operation as defined by public key
+ *		algorithm
+ * @maxsize:	Returns bufer size required to store a result of an operation
+ *		User should allocate a buf of this size and pass it in req->dst
+ * @setkey:	Function invokes the algorithm specific set key function, which
+ *		knows how to decode and interpret the BER encoded key
+ *
+ * @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);
+	int (*maxsize)(struct crypto_akcipher *tfm);
+	int (*setkey)(struct crypto_akcipher *tfm, const void *key,
+		      unsigned int keylen);
+
+	unsigned int reqsize;
+	struct crypto_alg base;
+};
+
+/**
+ * DOC: Generic Public Key API
+ *
+ * The Public Key API is used with the algorithms of type
+ * CRYPTO_ALG_TYPE_AKCIPHER (listed as type "akcipher" in /proc/crypto)
+ */
+
+/**
+ * crypto_alloc_akcipher() -- allocate AKCIPHER 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_akcipher 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_akcipher *crypto_alloc_akcipher(const char *alg_name, u32 type,
+					      u32 mask);
+
+/*
+ * Transform internal helpers.
+ */
+static inline struct akcipher_alg *__crypto_akcipher_alg(struct crypto_alg *alg)
+{
+	return container_of(alg, struct akcipher_alg, base);
+}
+
+static inline struct crypto_akcipher *__crypto_akcipher_tfm(
+	struct crypto_tfm *tfm)
+{
+	return container_of(tfm, struct crypto_akcipher, base);
+}
+
+static inline struct crypto_tfm *crypto_akcipher_tfm(
+	struct crypto_akcipher *tfm)
+{
+	return &tfm->base;
+}
+
+static inline struct akcipher_alg *crypto_akcipher_alg(
+	struct crypto_akcipher *tfm)
+{
+	return __crypto_akcipher_alg(crypto_akcipher_tfm(tfm)->__crt_alg);
+}
+
+/**
+ * crypto_free_akcipher() -- free AKCIPHER tfm handle
+ *
+ * @tfm: AKCIPHER tfm handle allocated with crypto_alloc_akcipher()
+ */
+static inline void crypto_free_akcipher(struct crypto_akcipher *tfm)
+{
+	crypto_destroy_tfm(tfm, crypto_akcipher_tfm(tfm));
+}
+
+static inline unsigned int crypto_akcipher_reqsize(struct crypto_akcipher *tfm)
+{
+	return crypto_akcipher_alg(tfm)->reqsize;
+}
+
+static inline void akcipher_request_set_tfm(struct akcipher_request *req,
+					    struct crypto_akcipher *tfm)
+{
+	req->base.tfm = crypto_akcipher_tfm(tfm);
+}
+
+/**
+ * akcipher_request_alloc() -- allocates public key request
+ *
+ * @tfm:	AKCIPHER tfm handle allocated with crypto_alloc_akcipher()
+ * @gfp:	allocation flags
+ *
+ * Return: allocated handle in case of success or NULL in case of an error.
+ */
+static inline struct akcipher_request *akcipher_request_alloc(
+	struct crypto_akcipher *tfm, gfp_t gfp)
+{
+	struct akcipher_request *req;
+
+	req = kmalloc(sizeof(*req) + crypto_akcipher_reqsize(tfm), gfp);
+	if (likely(req))
+		akcipher_request_set_tfm(req, tfm);
+
+	return req;
+}
+
+/**
+ * akcipher_request_get_tfm() -- return the AKCIPHER tfm handle from akcipher
+ *				 request
+ *
+ * @req:	akcipher request
+ *
+ * Return: AKCIPHER tfm handle.
+ */
+static inline struct crypto_akcipher *akcipher_request_get_tfm(
+	struct akcipher_request *req)
+{
+	return __crypto_akcipher_tfm(req->base.tfm);
+}
+
+static inline void *akcipher_request_ctx(struct akcipher_request *req)
+{
+	return req->__ctx;
+}
+
+static inline void *akcipher_tfm_ctx(struct crypto_akcipher *tfm)
+{
+	return tfm->base.__crt_ctx;
+}
+
+/**
+ * akcipher_request_free() -- zeroize and free public key request
+ *
+ * @req:	request to free
+ */
+static inline void akcipher_request_free(struct akcipher_request *req)
+{
+	kzfree(req);
+}
+
+/**
+ * akcipher_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 akcipher_request_set_callback(struct akcipher_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 akcipher_request_complete(struct akcipher_request *req,
+					     int err)
+{
+	req->base.complete(&req->base, err);
+}
+
+/**
+ * akcipher_request_set_crypt() -- Sets reqest parameters
+ *
+ * Sets parameters required by crypto operation
+ *
+ * @req:	public key request
+ * @src:	ptr to input parameter
+ * @dst:	ptr of output parameter
+ * @src_len:	size of the input buffer
+ * @dst_len:	size of the output buffer
+ * parameter:	Optional parameter. If not NULL this will be updated
+ *		by the implementation to reflect the acctual size of the result
+ */
+static inline void akcipher_request_set_crypt(struct akcipher_request *req,
+					      void *src, void *dst,
+					      unsigned int src_len,
+					      unsigned int dst_len,
+					      unsigned int *result_len)
+{
+	req->src = src;
+	req->dst = dst;
+	req->src_len = src_len;
+	req->dst_len = dst_len;
+	req->result_len = result_len;
+}
+
+/**
+ * akcipher_alg_name() -- 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 *akcipher_alg_name(struct crypto_akcipher *tfm)
+{
+	return crypto_akcipher_tfm(tfm)->__crt_alg->cra_name;
+}
+
+/**
+ * crypto_akcipher_encrypt() -- Invoke public key encrypt operation
+ *
+ * Function invokes the specific public key encrypt operation for a given
+ * public key algorithm
+ *
+ * @req:	asymmetric key request
+ *
+ * Return: zero on success; error code in case of error
+ */
+static inline int crypto_akcipher_encrypt(struct akcipher_request *req)
+{
+	struct crypto_akcipher *tfm = __crypto_akcipher_tfm(req->base.tfm);
+	struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
+
+	return alg->encrypt(req);
+}
+
+/**
+ * crypto_akcipher_decrypt() -- Invoke public key decrypt operation
+ *
+ * Function invokes the specific public key decrypt operation for a given
+ * public key algorithm
+ *
+ * @req:	asymmetric key request
+ *
+ * Return: zero on success; error code in case of error
+ */
+static inline int crypto_akcipher_decrypt(struct akcipher_request *req)
+{
+	struct crypto_akcipher *tfm = __crypto_akcipher_tfm(req->base.tfm);
+	struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
+
+	return alg->decrypt(req);
+}
+
+/**
+ * crypto_akcipher_sign() -- Invoke public key sign operation
+ *
+ * Function invokes the specific public key sign operation for a given
+ * public key algorithm
+ *
+ * @req:	asymmetric key request
+ *
+ * Return: zero on success; error code in case of error
+ */
+static inline int crypto_akcipher_sign(struct akcipher_request *req)
+{
+	struct crypto_akcipher *tfm = __crypto_akcipher_tfm(req->base.tfm);
+	struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
+
+	return alg->sign(req);
+}
+
+/**
+ * crypto_akcipher_verify() -- Invoke public key verify operation
+ *
+ * Function invokes the specific public key verify operation for a given
+ * public key algorithm
+ *
+ * @req:	asymmetric key request
+ *
+ * Return: zero on success; error code in case of error
+ */
+static inline int crypto_akcipher_verify(struct akcipher_request *req)
+{
+	struct crypto_akcipher *tfm = __crypto_akcipher_tfm(req->base.tfm);
+	struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
+
+	return alg->verify(req);
+}
+
+/**
+ * crypto_akcipher_maxsize() -- Get max size required to store result for give
+ *				implementation
+ *
+ * @tfm:	tfm handle
+ *
+ * Return: size required to store result or error code in case of error
+ */
+static inline int crypto_akcipher_maxsize(struct crypto_akcipher *tfm)
+{
+	struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
+
+	return alg->maxsize(tfm);
+}
+
+/**
+ * crypto_akcipher_setkey() -- Invoke public key setkey operation
+ *
+ * Function invokes the algorithm specific set key function, which knows
+ * how to decode and interpret the encoded key
+ *
+ * @tfm:	tfm handle
+ * @key:	BER encoded private or public key
+ * @keylen:	length of the key
+ *
+ * Return: size required to store result or error code in case of error
+ */
+static inline int crypto_akcipher_setkey(struct crypto_akcipher *tfm, void *key,
+					 unsigned int keylen)
+{
+	struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
+
+	return alg->setkey(tfm, key, keylen);
+}
+
+/**
+ * crypto_register_akcipher() -- 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_akcipher(struct akcipher_alg *alg);
+
+/**
+ * crypto_unregister_akcipher() -- Unregister public key algorithm
+ *
+ * Function unregisters an implementation of a public key verify algorithm
+ *
+ * @alg:	algorithm definition
+ */
+void crypto_unregister_akcipher(struct akcipher_alg *alg);
+#endif
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 25a4b71..0e3f71a 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_AKCIPHER	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..8448ef8 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_AKCIPHER,	/* struct crypto_report_akcipher */
 	__CRYPTOCFGA_MAX
 
 #define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
@@ -101,5 +102,10 @@ struct crypto_report_rng {
 	unsigned int seedsize;
 };
 
+struct crypto_report_akcipher {
+	char type[CRYPTO_MAX_NAME];
+	char subtype[CRYPTO_MAX_NAME];
+};
+
 #define CRYPTO_REPORT_MAXSIZE (sizeof(struct crypto_user_alg) + \
 			       sizeof(struct crypto_report_blkcipher))

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

* [PATCH RFC v5 3/4] crypto: rsa: add a new rsa generic implementation
  2015-06-15 20:18 [PATCH RFC v5 0/4] crypto: Introduce Public Key Encryption API Tadeusz Struk
  2015-06-15 20:18 ` [PATCH RFC v5 1/4] MPILIB: add mpi_read_buf() and mpi_get_size() helpers Tadeusz Struk
  2015-06-15 20:18 ` [PATCH RFC v5 2/4] crypto: add PKE API Tadeusz Struk
@ 2015-06-15 20:18 ` Tadeusz Struk
  2015-06-15 23:23   ` Stephan Mueller
  2015-06-15 20:18 ` [PATCH RFC v5 4/4] crypto: add tests vectors for RSA Tadeusz Struk
  3 siblings, 1 reply; 33+ messages in thread
From: Tadeusz Struk @ 2015-06-15 20:18 UTC (permalink / raw)
  To: herbert
  Cc: linux-kernel, keescook, jwboyer, smueller, richard,
	tadeusz.struk, steved, qat-linux, dhowells, linux-crypto,
	james.l.morris, jkosina, zohar, davem, vgoyal

Add a new rsa generic SW implementation.
This implements only cryptographic primitives.

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
 crypto/Kconfig                |    7 +
 crypto/Makefile               |    8 +
 crypto/rsa.c                  |  295 +++++++++++++++++++++++++++++++++++++++++
 crypto/rsa_helper.c           |  134 +++++++++++++++++++
 crypto/rsakey.asn1            |    5 +
 include/crypto/internal/rsa.h |   30 ++++
 6 files changed, 479 insertions(+)
 create mode 100644 crypto/rsa.c
 create mode 100644 crypto/rsa_helper.c
 create mode 100644 crypto/rsakey.asn1
 create mode 100644 include/crypto/internal/rsa.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index ed413d9..a09404b 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -97,6 +97,13 @@ config CRYPTO_AKCIPHER
 	help
 	  Crypto API interface for public key algorithms.
 
+config CRYPTO_RSA
+	tristate "RSA algorithm"
+	select AKCIPHER
+	select MPILIB
+	help
+	  Generic implementation of the RSA public key algorithm.
+
 config CRYPTO_MANAGER
 	tristate "Cryptographic algorithm manager"
 	select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 6f2940a..c6217ea 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -30,6 +30,14 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
 obj-$(CONFIG_CRYPTO_AKCIPHER) += akcipher.o
 
+$(obj)/rsakey-asn1.o: $(obj)/rsakey-asn1.c $(obj)/rsakey-asn1.h
+clean-files += rsakey-asn1.c rsakey-asn1.h
+
+rsa_generic-y := rsakey-asn1.o
+rsa_generic-y += rsa.o
+rsa_generic-y += rsa_helper.o
+obj-$(CONFIG_CRYPTO_RSA) += rsa_generic.o
+
 cryptomgr-y := algboss.o testmgr.o
 
 obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o
diff --git a/crypto/rsa.c b/crypto/rsa.c
new file mode 100644
index 0000000..176f565
--- /dev/null
+++ b/crypto/rsa.c
@@ -0,0 +1,295 @@
+/* RSA asymmetric public-key algorithm [RFC3447]
+ *
+ * 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 Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <crypto/internal/rsa.h>
+#include <crypto/akcipher.h>
+
+/*
+ * RSAEP function [RFC3447 sec 5.1.1]
+ * c = m^e mod n;
+ */
+static int _rsa_enc(const struct rsa_key *key, MPI c, MPI m)
+{
+	/* (1) Validate 0 <= m < n */
+	if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0)
+		return -EINVAL;
+
+	/* (2) c = m^e mod n */
+	return mpi_powm(c, m, key->e, key->n);
+}
+
+/*
+ * RSADP function [RFC3447 sec 5.1.2]
+ * m = c^d mod n;
+ */
+static int _rsa_dec(const struct rsa_key *key, MPI m, MPI c)
+{
+	/* (1) Validate 0 <= c < n */
+	if (mpi_cmp_ui(c, 0) < 0 || mpi_cmp(c, key->n) >= 0)
+		return -EINVAL;
+
+	/* (2) m = c^d mod n */
+	return mpi_powm(m, c, key->d, key->n);
+}
+
+/*
+ * RSASP1 function [RFC3447 sec 5.2.1]
+ * s = m^d mod n
+ */
+static int _rsa_sign(const struct rsa_key *key, MPI s, MPI m)
+{
+	/* (1) Validate 0 <= m < n */
+	if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0)
+		return -EINVAL;
+
+	/* (2) s = m^d mod n */
+	return mpi_powm(s, m, key->d, key->n);
+}
+
+/*
+ * RSAVP1 function [RFC3447 sec 5.2.2]
+ * m = s^e mod n;
+ */
+static int _rsa_verify(const struct rsa_key *key, MPI m, MPI s)
+{
+	/* (1) Validate 0 <= s < n */
+	if (mpi_cmp_ui(s, 0) < 0 || mpi_cmp(s, key->n) >= 0)
+		return -EINVAL;
+
+	/* (2) m = s^e mod n */
+	return mpi_powm(m, s, key->e, key->n);
+}
+
+static int rsa_enc(struct akcipher_request *req)
+{
+	struct crypto_akcipher *tfm = akcipher_request_get_tfm(req);
+	const struct rsa_key *pkey = rsa_get_key(tfm);
+	MPI m, c = mpi_alloc(0);
+	unsigned int len;
+	int ret = 0;
+	int sign;
+
+	if (!c)
+		return -ENOMEM;
+
+	if (!pkey->n || !pkey->e || req->dst_len < mpi_get_size(pkey->n))
+		return -EINVAL;
+
+	m = mpi_read_raw_data(req->src, req->src_len);
+	if (!m) {
+		ret = -ENOMEM;
+		goto err_free_c;
+	}
+
+	ret = _rsa_enc(pkey, c, m);
+	if (ret)
+		goto err_free_m;
+
+	ret = mpi_read_buffer(c, req->dst, req->dst_len, &len, &sign);
+	if (ret)
+		goto err_free_m;
+
+	if (sign < 0) {
+		ret = -EBADMSG;
+		goto err_free_m;
+	}
+
+	if (req->result_len)
+		*req->result_len = len;
+
+err_free_m:
+	mpi_free(m);
+err_free_c:
+	mpi_free(c);
+	return ret;
+}
+
+static int rsa_dec(struct akcipher_request *req)
+{
+	struct crypto_akcipher *tfm = akcipher_request_get_tfm(req);
+	const struct rsa_key *pkey = rsa_get_key(tfm);
+	MPI c, m = mpi_alloc(0);
+	unsigned int len;
+	int ret = 0;
+	int sign;
+
+	if (!m)
+		return -ENOMEM;
+
+	if (!pkey->n || !pkey->d || req->dst_len < mpi_get_size(pkey->n))
+		return -EINVAL;
+
+	c = mpi_read_raw_data(req->src, req->src_len);
+	if (!c) {
+		ret = -ENOMEM;
+		goto err_free_m;
+	}
+
+	ret = _rsa_dec(pkey, m, c);
+	if (ret)
+		goto err_free_c;
+
+	ret = mpi_read_buffer(m, req->dst, req->dst_len, &len, &sign);
+	if (ret)
+		goto err_free_c;
+
+	if (sign < 0) {
+		ret = -EBADMSG;
+		goto err_free_c;
+	}
+
+	if (req->result_len)
+		*req->result_len = len;
+
+err_free_c:
+	mpi_free(c);
+err_free_m:
+	mpi_free(m);
+	return ret;
+}
+
+static int rsa_sign(struct akcipher_request *req)
+{
+	struct crypto_akcipher *tfm = akcipher_request_get_tfm(req);
+	const struct rsa_key *pkey  = rsa_get_key(tfm);
+	MPI m, s = mpi_alloc(0);
+	unsigned int len;
+	int ret = 0;
+	int sign;
+
+	if (!s)
+		return -ENOMEM;
+
+	if (!pkey->n || !pkey->d || req->dst_len < mpi_get_size(pkey->n))
+		return -EINVAL;
+
+	m = mpi_read_raw_data(req->src, req->src_len);
+	if (!m) {
+		ret = -ENOMEM;
+		goto err_free_s;
+	}
+
+	ret = _rsa_sign(pkey, s, m);
+	if (ret)
+		goto err_free_m;
+
+	ret = mpi_read_buffer(s, req->dst, req->dst_len, &len, &sign);
+	if (ret)
+		goto err_free_m;
+
+	if (sign < 0) {
+		ret = -EBADMSG;
+		goto err_free_m;
+	}
+
+	if (req->result_len)
+		*req->result_len = len;
+
+err_free_m:
+	mpi_free(m);
+err_free_s:
+	mpi_free(s);
+	return ret;
+}
+
+static int rsa_verify(struct akcipher_request *req)
+{
+	struct crypto_akcipher *tfm = akcipher_request_get_tfm(req);
+	const struct rsa_key *pkey = rsa_get_key(tfm);
+	MPI s, m = mpi_alloc(0);
+	unsigned int len;
+	int ret = 0;
+	int sign;
+
+	if (!m)
+		return -ENOMEM;
+
+	if (!pkey->n || !pkey->e || req->dst_len < mpi_get_size(pkey->n))
+		return -EINVAL;
+
+	s = mpi_read_raw_data(req->src, req->src_len);
+	if (!s) {
+		ret = -ENOMEM;
+		goto err_free_m;
+	}
+
+	ret = _rsa_verify(pkey, m, s);
+	if (ret)
+		goto err_free_s;
+
+	ret = mpi_read_buffer(m, req->dst, req->dst_len, &len, &sign);
+	if (ret)
+		goto err_free_s;
+
+	if (sign < 0) {
+		ret = -EBADMSG;
+		goto err_free_s;
+	}
+
+	if (req->result_len)
+		*req->result_len = len;
+
+err_free_s:
+	mpi_free(s);
+err_free_m:
+	mpi_free(m);
+	return ret;
+}
+
+static int rsa_maxsize(struct crypto_akcipher *tfm)
+{
+	const struct rsa_key *pkey = rsa_get_key(tfm);
+
+	if (pkey && pkey->n)
+		return mpi_get_size(pkey->n);
+
+	return -EINVAL;
+}
+
+static int rsa_setkey(struct crypto_akcipher *tfm, const void *key,
+		      unsigned int keylen)
+{
+	return rsa_parse_key(tfm, key, keylen);
+}
+
+static struct akcipher_alg rsa = {
+	.encrypt = rsa_enc,
+	.decrypt = rsa_dec,
+	.sign = rsa_sign,
+	.verify = rsa_verify,
+	.maxsize = rsa_maxsize,
+	.setkey = rsa_setkey,
+	.base = {
+		.cra_name = "rsa",
+		.cra_driver_name = "rsa-generic",
+		.cra_priority = 100,
+		.cra_ctxsize = 0,
+		.cra_alignmask = 0,
+		.cra_module = THIS_MODULE,
+	},
+};
+
+static int rsa_init(void)
+{
+	return crypto_register_akcipher(&rsa);
+}
+
+static void rsa_exit(void)
+{
+	crypto_unregister_akcipher(&rsa);
+}
+
+module_init(rsa_init);
+module_exit(rsa_exit);
+MODULE_ALIAS_CRYPTO("rsa");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("RSA generic algorithm");
diff --git a/crypto/rsa_helper.c b/crypto/rsa_helper.c
new file mode 100644
index 0000000..6569b02
--- /dev/null
+++ b/crypto/rsa_helper.c
@@ -0,0 +1,134 @@
+/*
+ * RSA key extract helper
+ *
+ * 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/fips.h>
+#include <crypto/internal/rsa.h>
+#include "rsakey-asn1.h"
+
+int rsa_get_n(void *context, size_t hdrlen, unsigned char tag,
+	      const void *value, size_t vlen)
+{
+	struct crypto_akcipher *tfm = context;
+	struct rsa_key *key = tfm->key;
+
+	key->n = mpi_read_raw_data(value, vlen);
+
+	if (!key->n)
+		return -ENOMEM;
+
+	/* In FIPS mode only allow key size minimum 2K */
+	if (fips_enabled && (mpi_get_size(key->n) < 256)) {
+		pr_err("RSA: key size not allowed in FIPS mode\n");
+		mpi_free(key->n);
+		key->n = NULL;
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int rsa_get_e(void *context, size_t hdrlen, unsigned char tag,
+	      const void *value, size_t vlen)
+{
+	struct crypto_akcipher *tfm = context;
+	struct rsa_key *key = tfm->key;
+
+	key->e = mpi_read_raw_data(value, vlen);
+
+	if (!key->e)
+		return -ENOMEM;
+
+	return 0;
+}
+
+int rsa_get_d(void *context, size_t hdrlen, unsigned char tag,
+	      const void *value, size_t vlen)
+{
+	struct crypto_akcipher *tfm = context;
+	struct rsa_key *key = tfm->key;
+
+	key->d = mpi_read_raw_data(value, vlen);
+
+	if (!key->d)
+		return -ENOMEM;
+
+	/* In FIPS mode only allow key size minimum 2K */
+	if (fips_enabled && (mpi_get_size(key->d) < 256)) {
+		pr_err("RSA: key size not allowed in FIPS mode\n");
+		mpi_free(key->d);
+		key->d = NULL;
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static void free_mpis(struct rsa_key *key)
+{
+	if (key->n)
+		mpi_free(key->n);
+
+	if (key->e)
+		mpi_free(key->e);
+
+	if (key->d)
+		mpi_free(key->d);
+
+	key->n = NULL;
+	key->e = NULL;
+	key->d = NULL;
+}
+
+static void rsa_free_key(struct crypto_tfm *tfm_base)
+{
+	struct crypto_akcipher *tfm = __crypto_akcipher_tfm(tfm_base);
+	struct crypto_alg *alg = tfm_base->__crt_alg;
+
+	if (alg->cra_exit)
+		alg->cra_exit(tfm_base);
+
+	free_mpis(tfm->key);
+	kfree(tfm->key);
+	tfm->key = NULL;
+}
+
+/**
+ * rsa_parse_key() - extracts an rsa key from BER encoded buffer
+ *		     and stores it in tfm
+ *
+ * @tfm:	akcipher handler
+ * @key:	key in BER format
+ * @key_len:	length of key
+ *
+ * Return:	0 on success or error code in case of error
+ */
+int rsa_parse_key(struct crypto_akcipher *tfm, const void *key,
+		  unsigned int key_len)
+{
+	int ret;
+
+	if (!tfm->key) {
+		tfm->key = kzalloc(sizeof(struct rsa_key), GFP_KERNEL);
+		tfm->base.exit = rsa_free_key;
+	} else {
+		free_mpis(tfm->key);
+	}
+
+	ret = asn1_ber_decoder(&rsakey_decoder, tfm, key, key_len);
+	if (ret < 0)
+		goto error;
+
+	return 0;
+error:
+	free_mpis(tfm->key);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(rsa_parse_key);
diff --git a/crypto/rsakey.asn1 b/crypto/rsakey.asn1
new file mode 100644
index 0000000..3c7b5df
--- /dev/null
+++ b/crypto/rsakey.asn1
@@ -0,0 +1,5 @@
+RsaKey ::= SEQUENCE {
+	n INTEGER ({ rsa_get_n }),
+	e INTEGER ({ rsa_get_e }),
+	d INTEGER ({ rsa_get_d })
+}
diff --git a/include/crypto/internal/rsa.h b/include/crypto/internal/rsa.h
new file mode 100644
index 0000000..475d52b
--- /dev/null
+++ b/include/crypto/internal/rsa.h
@@ -0,0 +1,30 @@
+/*
+ * RSA internal helpers
+ *
+ * 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 _RSA_HELPER_
+#define _RSA_HELPER_
+#include <linux/mpi.h>
+#include <crypto/akcipher.h>
+
+struct rsa_key {
+	MPI n;
+	MPI e;
+	MPI d;
+};
+
+int rsa_parse_key(struct crypto_akcipher *tfm, const void *key,
+		  unsigned int key_len);
+static inline struct rsa_key *rsa_get_key(struct crypto_akcipher *tfm)
+{
+	return tfm->key;
+}
+#endif

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

* [PATCH RFC v5 4/4] crypto: add tests vectors for RSA
  2015-06-15 20:18 [PATCH RFC v5 0/4] crypto: Introduce Public Key Encryption API Tadeusz Struk
                   ` (2 preceding siblings ...)
  2015-06-15 20:18 ` [PATCH RFC v5 3/4] crypto: rsa: add a new rsa generic implementation Tadeusz Struk
@ 2015-06-15 20:18 ` Tadeusz Struk
  2015-06-16  0:37   ` Herbert Xu
  3 siblings, 1 reply; 33+ messages in thread
From: Tadeusz Struk @ 2015-06-15 20:18 UTC (permalink / raw)
  To: herbert
  Cc: linux-kernel, keescook, jwboyer, smueller, richard,
	tadeusz.struk, steved, qat-linux, dhowells, linux-crypto,
	james.l.morris, jkosina, zohar, davem, vgoyal

New test vectors for RSA algorithm.

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
 crypto/Kconfig   |    1 
 crypto/testmgr.c |  149 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 crypto/testmgr.h |  143 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 293 insertions(+)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index a09404b..90c1f77 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -107,6 +107,7 @@ config CRYPTO_RSA
 config CRYPTO_MANAGER
 	tristate "Cryptographic algorithm manager"
 	select CRYPTO_MANAGER2
+	select CRYPTO_AKCIPHER
 	help
 	  Create default cryptographic template instantiations such as
 	  cbc(aes).
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index ccd19cf..ff41714 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -30,6 +30,7 @@
 #include <linux/string.h>
 #include <crypto/rng.h>
 #include <crypto/drbg.h>
+#include <crypto/akcipher.h>
 
 #include "internal.h"
 
@@ -116,6 +117,11 @@ struct drbg_test_suite {
 	unsigned int count;
 };
 
+struct akcipher_test_suite {
+	struct akcipher_testvec *vecs;
+	unsigned int count;
+};
+
 struct alg_test_desc {
 	const char *alg;
 	int (*test)(const struct alg_test_desc *desc, const char *driver,
@@ -130,6 +136,7 @@ struct alg_test_desc {
 		struct hash_test_suite hash;
 		struct cprng_test_suite cprng;
 		struct drbg_test_suite drbg;
+		struct akcipher_test_suite akcipher;
 	} suite;
 };
 
@@ -1825,6 +1832,138 @@ static int alg_test_drbg(const struct alg_test_desc *desc, const char *driver,
 
 }
 
+static int do_test_rsa(struct crypto_akcipher *tfm,
+		       struct akcipher_testvec *vecs)
+{
+	struct akcipher_request *req;
+	void *outbuf_enc = NULL;
+	void *outbuf_dec = NULL;
+	struct tcrypt_result result;
+	unsigned int max_out_len, out_len;
+	int err = -ENOMEM;
+
+	req = akcipher_request_alloc(tfm, GFP_KERNEL);
+	if (!req)
+		return err;
+
+	init_completion(&result.completion);
+	err = crypto_akcipher_setkey(tfm, vecs->key, vecs->key_len);
+	if (err)
+		goto free_req;
+
+	err = -EINVAL;
+	max_out_len = crypto_akcipher_maxsize(tfm);
+	if (!(max_out_len > 0))
+		goto free_req;
+
+	err = -ENOMEM;
+	outbuf_enc = kzalloc(max_out_len, GFP_KERNEL);
+	if (!outbuf_enc)
+		goto free_req;
+
+	akcipher_request_set_crypt(req, vecs->m, outbuf_enc, vecs->m_size,
+				   max_out_len, &out_len);
+	akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+				      tcrypt_complete, &result);
+
+	/* Run RSA encrypt - c = m^e mod n;*/
+	err = wait_async_op(&result, crypto_akcipher_encrypt(req));
+	if (err) {
+		pr_err("alg: rsa: encrypt test failed. err %d\n", err);
+		goto free_all;
+	}
+
+	if (out_len != vecs->c_size) {
+		err = -EINVAL;
+		goto free_all;
+	}
+	/* verify that encrypted message is equal to expected */
+	if (memcmp(vecs->c, outbuf_enc, vecs->c_size)) {
+		pr_err("alg: rsa: encrypt test failed. Invalid output\n");
+		err = -EINVAL;
+		goto free_all;
+	}
+
+	outbuf_dec = kzalloc(max_out_len, GFP_KERNEL);
+	if (!outbuf_dec) {
+		err = -ENOMEM;
+		goto free_all;
+	}
+
+	init_completion(&result.completion);
+	akcipher_request_set_crypt(req, outbuf_enc, outbuf_dec, vecs->c_size,
+				   max_out_len, &out_len);
+
+	/* Run RSA decrypt - m = c^d mod n;*/
+	err = wait_async_op(&result, crypto_akcipher_decrypt(req));
+	if (err) {
+		pr_err("alg: rsa: decrypt test failed. err %d\n", err);
+		goto free_all;
+	}
+
+	if (out_len != vecs->m_size) {
+		err = -EINVAL;
+		goto free_all;
+	}
+
+	/* verify that decrypted message is equal to the original msg */
+	if (memcmp(vecs->m, outbuf_dec, vecs->m_size)) {
+		pr_err("alg: rsa: encrypt test failed. Invalid output\n");
+		err = -EINVAL;
+	}
+free_all:
+	kfree(outbuf_dec);
+	kfree(outbuf_enc);
+free_req:
+	akcipher_request_free(req);
+	return err;
+}
+
+static int test_rsa(struct crypto_akcipher *tfm, struct akcipher_testvec *vecs,
+		    unsigned int tcount)
+{
+	int ret, i;
+
+	for (i = 0; i < tcount; i++) {
+		ret = do_test_rsa(tfm, vecs++);
+		if (ret) {
+			pr_err("alg: rsa: test failed on vector %d, err=%d\n",
+			       i + 1, ret);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+static int test_akcipher(struct crypto_akcipher *tfm, const char *alg,
+			 struct akcipher_testvec *vecs, unsigned int tcount)
+{
+	if (strncmp(alg, "rsa", 3) == 0)
+		return test_rsa(tfm, vecs, tcount);
+
+	return 0;
+}
+
+static int alg_test_akcipher(const struct alg_test_desc *desc,
+			     const char *driver, u32 type, u32 mask)
+{
+	struct crypto_akcipher *tfm;
+	int err = 0;
+
+	tfm = crypto_alloc_akcipher(driver, type | CRYPTO_ALG_INTERNAL, mask);
+	if (IS_ERR(tfm)) {
+		pr_err("alg: akcipher: Failed to load tfm for %s: %ld\n",
+		       driver, PTR_ERR(tfm));
+		return PTR_ERR(tfm);
+	}
+	if (desc->suite.akcipher.vecs)
+		err = test_akcipher(tfm, desc->alg, desc->suite.akcipher.vecs,
+				    desc->suite.akcipher.count);
+
+	crypto_free_akcipher(tfm);
+	return err;
+}
+
 static int alg_test_null(const struct alg_test_desc *desc,
 			     const char *driver, u32 type, u32 mask)
 {
@@ -3453,6 +3592,16 @@ static const struct alg_test_desc alg_test_descs[] = {
 			}
 		}
 	}, {
+		.alg = "rsa",
+		.test = alg_test_akcipher,
+		.fips_allowed = 1,
+		.suite = {
+			.akcipher = {
+				.vecs = rsa_tv_template,
+				.count = RSA_TEST_VECTORS
+			}
+		}
+	}, {
 		.alg = "salsa20",
 		.test = alg_test_skcipher,
 		.suite = {
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 4c2b3e5..8aad507 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -125,9 +125,152 @@ struct drbg_testvec {
 	size_t expectedlen;
 };
 
+struct akcipher_testvec {
+	unsigned char *key;
+	unsigned char *m;
+	unsigned char *c;
+	unsigned int key_len;
+	unsigned int m_size;
+	unsigned int c_size;
+};
+
 static char zeroed_string[48];
 
 /*
+ * RSA test vectors. Borrowed from openSSL.
+ */
+#ifdef CONFIG_CRYPTO_FIPS
+#define RSA_TEST_VECTORS	1
+#else
+#define RSA_TEST_VECTORS	3
+#endif
+static struct akcipher_testvec rsa_tv_template[] = {
+	{
+#ifndef CONFIG_CRYPTO_FIPS
+	.key =
+	"\x30\x81\x88" /* sequence of 136 bytes */
+	"\x02\x41" /* modulus - integer of 65 bytes */
+	"\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F"
+	"\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5"
+	"\xAD\xB3\x00\xA0\x28\x5E\x53\x01\x93\x0E\x0C\x70\xFB\x68\x76\x93"
+	"\x9C\xE6\x16\xCE\x62\x4A\x11\xE0\x08\x6D\x34\x1E\xBC\xAC\xA0\xA1"
+	"\xF5"
+	"\x02\x01\x11" /* public key - integer of 1 byte */
+	"\x02\x40" /* private key - integer of 64 bytes */
+	"\x0A\x03\x37\x48\x62\x64\x87\x69\x5F\x5F\x30\xBC\x38\xB9\x8B\x44"
+	"\xC2\xCD\x2D\xFF\x43\x40\x98\xCD\x20\xD8\xA1\x38\xD0\x90\xBF\x64"
+	"\x79\x7C\x3F\xA7\xA2\xCD\xCB\x3C\xD1\xE0\xBD\xBA\x26\x54\xB4\xF9"
+	"\xDF\x8E\x8A\xE5\x9D\x73\x3D\x9F\x33\xB3\x01\x62\x4A\xFD\x1D\x51",
+	.m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a",
+	.c =
+	"\x63\x1c\xcd\x7b\xe1\x7e\xe4\xde\xc9\xa8\x89\xa1\x74\xcb\x3c\x63"
+	"\x7d\x24\xec\x83\xc3\x15\xe4\x7f\x73\x05\x34\xd1\xec\x22\xbb\x8a"
+	"\x5e\x32\x39\x6d\xc1\x1d\x7d\x50\x3b\x9f\x7a\xad\xf0\x2e\x25\x53"
+	"\x9f\x6e\xbd\x4c\x55\x84\x0c\x9b\xcf\x1a\x4b\x51\x1e\x9e\x0c\x06",
+	.key_len = 139,
+	.m_size = 8,
+	.c_size = 64,
+	}, {
+	.key =
+	"\x30\x82\x01\x0B" /* sequence of 267 bytes */
+	"\x02\x81\x81" /* modulus - integer of 129 bytes */
+	"\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71"
+	"\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5"
+	"\x1F\xB8\xDF\xBA\xAF\x03\x5C\x02\xAB\x61\xEA\x48\xCE\xEB\x6F\xCD"
+	"\x48\x76\xED\x52\x0D\x60\xE1\xEC\x46\x19\x71\x9D\x8A\x5B\x8B\x80"
+	"\x7F\xAF\xB8\xE0\xA3\xDF\xC7\x37\x72\x3E\xE6\xB4\xB7\xD9\x3A\x25"
+	"\x84\xEE\x6A\x64\x9D\x06\x09\x53\x74\x88\x34\xB2\x45\x45\x98\x39"
+	"\x4E\xE0\xAA\xB1\x2D\x7B\x61\xA5\x1F\x52\x7A\x9A\x41\xF6\xC1\x68"
+	"\x7F\xE2\x53\x72\x98\xCA\x2A\x8F\x59\x46\xF8\xE5\xFD\x09\x1D\xBD"
+	"\xCB"
+	"\x02\x01\x11" /* public key - integer of 1 byte */
+	"\x02\x81\x81"  /* private key - integer of 129 bytes */
+	"\x00\xA5\xDA\xFC\x53\x41\xFA\xF2\x89\xC4\xB9\x88\xDB\x30\xC1\xCD"
+	"\xF8\x3F\x31\x25\x1E\x06\x68\xB4\x27\x84\x81\x38\x01\x57\x96\x41"
+	"\xB2\x94\x10\xB3\xC7\x99\x8D\x6B\xC4\x65\x74\x5E\x5C\x39\x26\x69"
+	"\xD6\x87\x0D\xA2\xC0\x82\xA9\x39\xE3\x7F\xDC\xB8\x2E\xC9\x3E\xDA"
+	"\xC9\x7F\xF3\xAD\x59\x50\xAC\xCF\xBC\x11\x1C\x76\xF1\xA9\x52\x94"
+	"\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A"
+	"\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94"
+	"\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3"
+	"\xC1",
+	.key_len = 271,
+	.m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a",
+	.c =
+	"\x74\x1b\x55\xac\x47\xb5\x08\x0a\x6e\x2b\x2d\xf7\x94\xb8\x8a\x95"
+	"\xed\xa3\x6b\xc9\x29\xee\xb2\x2c\x80\xc3\x39\x3b\x8c\x62\x45\x72"
+	"\xc2\x7f\x74\x81\x91\x68\x44\x48\x5a\xdc\xa0\x7e\xa7\x0b\x05\x7f"
+	"\x0e\xa0\x6c\xe5\x8f\x19\x4d\xce\x98\x47\x5f\xbd\x5f\xfe\xe5\x34"
+	"\x59\x89\xaf\xf0\xba\x44\xd7\xf1\x1a\x50\x72\xef\x5e\x4a\xb6\xb7"
+	"\x54\x34\xd1\xc4\x83\x09\xdf\x0f\x91\x5f\x7d\x91\x70\x2f\xd4\x13"
+	"\xcc\x5e\xa4\x6c\xc3\x4d\x28\xef\xda\xaf\xec\x14\x92\xfc\xa3\x75"
+	"\x13\xb4\xc1\xa1\x11\xfc\x40\x2f\x4c\x9d\xdf\x16\x76\x11\x20\x6b",
+	.m_size = 8,
+	.c_size = 128,
+	}, {
+#endif
+	.key =
+	"\x30\x82\x02\x0D" /* sequence of 525 bytes */
+	"\x02\x82\x01\x00" /* modulus - integer of 256 bytes */
+	"\xDB\x10\x1A\xC2\xA3\xF1\xDC\xFF\x13\x6B\xED\x44\xDF\xF0\x02\x6D"
+	"\x13\xC7\x88\xDA\x70\x6B\x54\xF1\xE8\x27\xDC\xC3\x0F\x99\x6A\xFA"
+	"\xC6\x67\xFF\x1D\x1E\x3C\x1D\xC1\xB5\x5F\x6C\xC0\xB2\x07\x3A\x6D"
+	"\x41\xE4\x25\x99\xAC\xFC\xD2\x0F\x02\xD3\xD1\x54\x06\x1A\x51\x77"
+	"\xBD\xB6\xBF\xEA\xA7\x5C\x06\xA9\x5D\x69\x84\x45\xD7\xF5\x05\xBA"
+	"\x47\xF0\x1B\xD7\x2B\x24\xEC\xCB\x9B\x1B\x10\x8D\x81\xA0\xBE\xB1"
+	"\x8C\x33\xE4\x36\xB8\x43\xEB\x19\x2A\x81\x8D\xDE\x81\x0A\x99\x48"
+	"\xB6\xF6\xBC\xCD\x49\x34\x3A\x8F\x26\x94\xE3\x28\x82\x1A\x7C\x8F"
+	"\x59\x9F\x45\xE8\x5D\x1A\x45\x76\x04\x56\x05\xA1\xD0\x1B\x8C\x77"
+	"\x6D\xAF\x53\xFA\x71\xE2\x67\xE0\x9A\xFE\x03\xA9\x85\xD2\xC9\xAA"
+	"\xBA\x2A\xBC\xF4\xA0\x08\xF5\x13\x98\x13\x5D\xF0\xD9\x33\x34\x2A"
+	"\x61\xC3\x89\x55\xF0\xAE\x1A\x9C\x22\xEE\x19\x05\x8D\x32\xFE\xEC"
+	"\x9C\x84\xBA\xB7\xF9\x6C\x3A\x4F\x07\xFC\x45\xEB\x12\xE5\x7B\xFD"
+	"\x55\xE6\x29\x69\xD1\xC2\xE8\xB9\x78\x59\xF6\x79\x10\xC6\x4E\xEB"
+	"\x6A\x5E\xB9\x9A\xC7\xC4\x5B\x63\xDA\xA3\x3F\x5E\x92\x7A\x81\x5E"
+	"\xD6\xB0\xE2\x62\x8F\x74\x26\xC2\x0C\xD3\x9A\x17\x47\xE6\x8E\xAB"
+	"\x02\x03\x01\x00\x01" /* public key - integer of 3 bytes */
+	"\x02\x82\x01\x00" /* private key - integer of 256 bytes */
+	"\x52\x41\xF4\xDA\x7B\xB7\x59\x55\xCA\xD4\x2F\x0F\x3A\xCB\xA4\x0D"
+	"\x93\x6C\xCC\x9D\xC1\xB2\xFB\xFD\xAE\x40\x31\xAC\x69\x52\x21\x92"
+	"\xB3\x27\xDF\xEA\xEE\x2C\x82\xBB\xF7\x40\x32\xD5\x14\xC4\x94\x12"
+	"\xEC\xB8\x1F\xCA\x59\xE3\xC1\x78\xF3\x85\xD8\x47\xA5\xD7\x02\x1A"
+	"\x65\x79\x97\x0D\x24\xF4\xF0\x67\x6E\x75\x2D\xBF\x10\x3D\xA8\x7D"
+	"\xEF\x7F\x60\xE4\xE6\x05\x82\x89\x5D\xDF\xC6\xD2\x6C\x07\x91\x33"
+	"\x98\x42\xF0\x02\x00\x25\x38\xC5\x85\x69\x8A\x7D\x2F\x95\x6C\x43"
+	"\x9A\xB8\x81\xE2\xD0\x07\x35\xAA\x05\x41\xC9\x1E\xAF\xE4\x04\x3B"
+	"\x19\xB8\x73\xA2\xAC\x4B\x1E\x66\x48\xD8\x72\x1F\xAC\xF6\xCB\xBC"
+	"\x90\x09\xCA\xEC\x0C\xDC\xF9\x2C\xD7\xEB\xAE\xA3\xA4\x47\xD7\x33"
+	"\x2F\x8A\xCA\xBC\x5E\xF0\x77\xE4\x97\x98\x97\xC7\x10\x91\x7D\x2A"
+	"\xA6\xFF\x46\x83\x97\xDE\xE9\xE2\x17\x03\x06\x14\xE2\xD7\xB1\x1D"
+	"\x77\xAF\x51\x27\x5B\x5E\x69\xB8\x81\xE6\x11\xC5\x43\x23\x81\x04"
+	"\x62\xFF\xE9\x46\xB8\xD8\x44\xDB\xA5\xCC\x31\x54\x34\xCE\x3E\x82"
+	"\xD6\xBF\x7A\x0B\x64\x21\x6D\x88\x7E\x5B\x45\x12\x1E\x63\x8D\x49"
+	"\xA7\x1D\xD9\x1E\x06\xCD\xE8\xBA\x2C\x8C\x69\x32\xEA\xBE\x60\x71",
+	.key_len = 529,
+	.m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a",
+	.c =
+	"\xb2\x97\x76\xb4\xae\x3e\x38\x3c\x7e\x64\x1f\xcc\xa2\x7f\xf6\xbe"
+	"\xcf\x49\xbc\x48\xd3\x6c\x8f\x0a\x0e\xc1\x73\xbd\x7b\x55\x79\x36"
+	"\x0e\xa1\x87\x88\xb9\x2c\x90\xa6\x53\x5e\xe9\xef\xc4\xe2\x4d\xdd"
+	"\xf7\xa6\x69\x82\x3f\x56\xa4\x7b\xfb\x62\xe0\xae\xb8\xd3\x04\xb3"
+	"\xac\x5a\x15\x2a\xe3\x19\x9b\x03\x9a\x0b\x41\xda\x64\xec\x0a\x69"
+	"\xfc\xf2\x10\x92\xf3\xc1\xbf\x84\x7f\xfd\x2c\xae\xc8\xb5\xf6\x41"
+	"\x70\xc5\x47\x03\x8a\xf8\xff\x6f\x3f\xd2\x6f\x09\xb4\x22\xf3\x30"
+	"\xbe\xa9\x85\xcb\x9c\x8d\xf9\x8f\xeb\x32\x91\xa2\x25\x84\x8f\xf5"
+	"\xdc\xc7\x06\x9c\x2d\xe5\x11\x2c\x09\x09\x87\x09\xa9\xf6\x33\x73"
+	"\x90\xf1\x60\xf2\x65\xdd\x30\xa5\x66\xce\x62\x7b\xd0\xf8\x2d\x3d"
+	"\x19\x82\x77\xe3\x0a\x5f\x75\x2f\x8e\xb1\xe5\xe8\x91\x35\x1b\x3b"
+	"\x33\xb7\x66\x92\xd1\xf2\x8e\x6f\xe5\x75\x0c\xad\x36\xfb\x4e\xd0"
+	"\x66\x61\xbd\x49\xfe\xf4\x1a\xa2\x2b\x49\xfe\x03\x4c\x74\x47\x8d"
+	"\x9a\x66\xb2\x49\x46\x4d\x77\xea\x33\x4d\x6b\x3c\xb4\x49\x4a\xc6"
+	"\x7d\x3d\xb5\xb9\x56\x41\x15\x67\x0f\x94\x3c\x93\x65\x27\xe0\x21"
+	"\x5d\x59\xc3\x62\xd5\xa6\xda\x38\x26\x22\x5e\x34\x1c\x94\xaf\x98",
+	.m_size = 8,
+	.c_size = 256,
+	}
+};
+
+/*
  * MD4 test vectors from RFC1320
  */
 #define MD4_TEST_VECTORS	7

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

* Re: [PATCH RFC v5 3/4] crypto: rsa: add a new rsa generic implementation
  2015-06-15 20:18 ` [PATCH RFC v5 3/4] crypto: rsa: add a new rsa generic implementation Tadeusz Struk
@ 2015-06-15 23:23   ` Stephan Mueller
  2015-06-16  1:49     ` Tadeusz Struk
  0 siblings, 1 reply; 33+ messages in thread
From: Stephan Mueller @ 2015-06-15 23:23 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: herbert, linux-kernel, keescook, jwboyer, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

Am Montag, 15. Juni 2015, 13:18:47 schrieb Tadeusz Struk:

Hi Tadeusz,

> Add a new rsa generic SW implementation.
> This implements only cryptographic primitives.

Thank you, that seems to address the issues around the FIPS side including the 
self test code.

Though, I have one question:

> +
> +int rsa_get_n(void *context, size_t hdrlen, unsigned char tag,
> +	      const void *value, size_t vlen)
> +{
> +	struct crypto_akcipher *tfm = context;
> +	struct rsa_key *key = tfm->key;
> +
> +	key->n = mpi_read_raw_data(value, vlen);
> +
> +	if (!key->n)
> +		return -ENOMEM;
> +
> +	/* In FIPS mode only allow key size minimum 2K */
> +	if (fips_enabled && (mpi_get_size(key->n) < 256)) {

Considering my previous email, shouldn't that check rather be

if (fips_enabled &&
    ((mpi_get_size(key->n) != 256) || (mpi_get_size(key->n) != 384))

?

> +		pr_err("RSA: key size not allowed in FIPS mode\n");
> +		mpi_free(key->n);
> +		key->n = NULL;
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +int rsa_get_e(void *context, size_t hdrlen, unsigned char tag,
> +	      const void *value, size_t vlen)
> +{
> +	struct crypto_akcipher *tfm = context;
> +	struct rsa_key *key = tfm->key;
> +
> +	key->e = mpi_read_raw_data(value, vlen);
> +
> +	if (!key->e)
> +		return -ENOMEM;
> +
> +	return 0;
> +}
> +
> +int rsa_get_d(void *context, size_t hdrlen, unsigned char tag,
> +	      const void *value, size_t vlen)
> +{
> +	struct crypto_akcipher *tfm = context;
> +	struct rsa_key *key = tfm->key;
> +
> +	key->d = mpi_read_raw_data(value, vlen);
> +
> +	if (!key->d)
> +		return -ENOMEM;
> +
> +	/* In FIPS mode only allow key size minimum 2K */
> +	if (fips_enabled && (mpi_get_size(key->d) < 256)) {

dto.

> +		pr_err("RSA: key size not allowed in FIPS mode\n");
> +		mpi_free(key->d);
> +		key->d = NULL;
> +		return -EINVAL;
> +	}
> +	return 0;
> +}
> +

Thanks
-- 
Ciao
Stephan

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

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-15 20:18 ` [PATCH RFC v5 2/4] crypto: add PKE API Tadeusz Struk
@ 2015-06-15 23:46   ` Herbert Xu
  2015-06-15 23:49   ` Herbert Xu
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 33+ messages in thread
From: Herbert Xu @ 2015-06-15 23:46 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On Mon, Jun 15, 2015 at 01:18:42PM -0700, Tadeusz Struk wrote:
>
> +struct akcipher_request {
> +	struct crypto_async_request base;
> +	void *src;
> +	void *dst;
> +	unsigned int src_len;
> +	unsigned int dst_len;
> +	unsigned int *result_len;
> +	void *__ctx[] CRYPTO_MINALIGN_ATTR;
> +};

result_len is redundant.  You can write to dst_len after the
operation is done.

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] 33+ messages in thread

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-15 20:18 ` [PATCH RFC v5 2/4] crypto: add PKE API Tadeusz Struk
  2015-06-15 23:46   ` Herbert Xu
@ 2015-06-15 23:49   ` Herbert Xu
  2015-06-15 23:50   ` Herbert Xu
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 33+ messages in thread
From: Herbert Xu @ 2015-06-15 23:49 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On Mon, Jun 15, 2015 at 01:18:42PM -0700, Tadeusz Struk wrote:
>
> +/**
> + * crypto_akcipher_setkey() -- Invoke public key setkey operation
> + *
> + * Function invokes the algorithm specific set key function, which knows
> + * how to decode and interpret the encoded key
> + *
> + * @tfm:	tfm handle
> + * @key:	BER encoded private or public key
> + * @keylen:	length of the key
> + *
> + * Return: size required to store result or error code in case of error

cut-n-paste error?
-- 
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] 33+ messages in thread

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-15 20:18 ` [PATCH RFC v5 2/4] crypto: add PKE API Tadeusz Struk
  2015-06-15 23:46   ` Herbert Xu
  2015-06-15 23:49   ` Herbert Xu
@ 2015-06-15 23:50   ` Herbert Xu
  2015-06-15 23:54   ` Herbert Xu
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 33+ messages in thread
From: Herbert Xu @ 2015-06-15 23:50 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On Mon, Jun 15, 2015 at 01:18:42PM -0700, Tadeusz Struk wrote:
>
> +/**
> + * crypto_register_akcipher() -- 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_akcipher(struct akcipher_alg *alg);
> +
> +/**
> + * crypto_unregister_akcipher() -- Unregister public key algorithm
> + *
> + * Function unregisters an implementation of a public key verify algorithm
> + *
> + * @alg:	algorithm definition
> + */
> +void crypto_unregister_akcipher(struct akcipher_alg *alg);

These two functions and anything else that's specific to public key
implementors should go into crypto/internal.

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] 33+ messages in thread

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-15 20:18 ` [PATCH RFC v5 2/4] crypto: add PKE API Tadeusz Struk
                     ` (2 preceding siblings ...)
  2015-06-15 23:50   ` Herbert Xu
@ 2015-06-15 23:54   ` Herbert Xu
  2015-06-15 23:59   ` Herbert Xu
  2015-06-16  0:05   ` Herbert Xu
  5 siblings, 0 replies; 33+ messages in thread
From: Herbert Xu @ 2015-06-15 23:54 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On Mon, Jun 15, 2015 at 01:18:42PM -0700, Tadeusz Struk wrote:
>
> +static int crypto_akcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
> +{
> +	struct crypto_report_akcipher rakcipher;
> +
> +	strncpy(rakcipher.type, "akcipher", sizeof(rakcipher.type));
> +	strncpy(rakcipher.subtype, alg->cra_name, sizeof(rakcipher.subtype));

There is no point in reporting cra_name.  That's already taken care
of by crypto_user.c.

> +static void crypto_akcipher_show(struct seq_file *m, struct crypto_alg *alg)
> +	__attribute__ ((unused));
> +
> +static void crypto_akcipher_show(struct seq_file *m, struct crypto_alg *alg)
> +{
> +	seq_puts(m, "type         : akcipher\n");
> +	seq_printf(m, "subtype      : %s\n", alg->cra_name);

Ditto please drop subtype.

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] 33+ messages in thread

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-15 20:18 ` [PATCH RFC v5 2/4] crypto: add PKE API Tadeusz Struk
                     ` (3 preceding siblings ...)
  2015-06-15 23:54   ` Herbert Xu
@ 2015-06-15 23:59   ` Herbert Xu
  2015-06-16  2:21     ` Tadeusz Struk
  2015-06-16  0:05   ` Herbert Xu
  5 siblings, 1 reply; 33+ messages in thread
From: Herbert Xu @ 2015-06-15 23:59 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On Mon, Jun 15, 2015 at 01:18:42PM -0700, Tadeusz Struk wrote:
>
> +struct crypto_akcipher {
> +	void *key;

Having a void * pointer here is useless.  The normal way of doing
it is to place the key into the tfm context.

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] 33+ messages in thread

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-15 20:18 ` [PATCH RFC v5 2/4] crypto: add PKE API Tadeusz Struk
                     ` (4 preceding siblings ...)
  2015-06-15 23:59   ` Herbert Xu
@ 2015-06-16  0:05   ` Herbert Xu
  2015-06-16  2:03     ` Tadeusz Struk
  2015-06-16  2:29     ` Tadeusz Struk
  5 siblings, 2 replies; 33+ messages in thread
From: Herbert Xu @ 2015-06-16  0:05 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On Mon, Jun 15, 2015 at 01:18:42PM -0700, Tadeusz Struk wrote:
>
> + * @setkey:	Function invokes the algorithm specific set key function, which
> + *		knows how to decode and interpret the BER encoded key

We should split this into two functions: setpubkey and setprivkey.

> + *
> + * @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);
> +	int (*maxsize)(struct crypto_akcipher *tfm);

Hmm, we could actually get rid of maxsize by just having each
function check the dst_len and if it is insufficient write the
required length in it and then return an error.

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] 33+ messages in thread

* Re: [PATCH RFC v5 4/4] crypto: add tests vectors for RSA
  2015-06-15 20:18 ` [PATCH RFC v5 4/4] crypto: add tests vectors for RSA Tadeusz Struk
@ 2015-06-16  0:37   ` Herbert Xu
  2015-06-16  6:26     ` Tadeusz Struk
  0 siblings, 1 reply; 33+ messages in thread
From: Herbert Xu @ 2015-06-16  0:37 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On Mon, Jun 15, 2015 at 01:18:53PM -0700, Tadeusz Struk wrote:
> New test vectors for RSA algorithm.
> 
> Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
> ---
>  crypto/Kconfig   |    1 
>  crypto/testmgr.c |  149 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  crypto/testmgr.h |  143 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 293 insertions(+)
> 
> diff --git a/crypto/Kconfig b/crypto/Kconfig
> index a09404b..90c1f77 100644
> --- a/crypto/Kconfig
> +++ b/crypto/Kconfig
> @@ -107,6 +107,7 @@ config CRYPTO_RSA
>  config CRYPTO_MANAGER
>  	tristate "Cryptographic algorithm manager"
>  	select CRYPTO_MANAGER2
> +	select CRYPTO_AKCIPHER

Please add this to CRYPTO_MANAGER2 instead.

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] 33+ messages in thread

* Re: [PATCH RFC v5 3/4] crypto: rsa: add a new rsa generic implementation
  2015-06-15 23:23   ` Stephan Mueller
@ 2015-06-16  1:49     ` Tadeusz Struk
  2015-06-16  2:19       ` Stephan Mueller
  0 siblings, 1 reply; 33+ messages in thread
From: Tadeusz Struk @ 2015-06-16  1:49 UTC (permalink / raw)
  To: Stephan Mueller
  Cc: herbert, linux-kernel, keescook, jwboyer, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On 06/15/2015 04:23 PM, Stephan Mueller wrote:
>> +	/* In FIPS mode only allow key size minimum 2K */
>> > +	if (fips_enabled && (mpi_get_size(key->n) < 256)) {
> Considering my previous email, shouldn't that check rather be
> 
> if (fips_enabled &&
>     ((mpi_get_size(key->n) != 256) || (mpi_get_size(key->n) != 384))

I'm not familiar with the FIPS requirements. I checked the NIST recommendations witch states that
RSA: |n| >= 2048 is acceptable. If FIPS allows 2K and 3K only then we need to change it.

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

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-16  0:05   ` Herbert Xu
@ 2015-06-16  2:03     ` Tadeusz Struk
  2015-06-16  2:27       ` Herbert Xu
  2015-06-16  2:29     ` Tadeusz Struk
  1 sibling, 1 reply; 33+ messages in thread
From: Tadeusz Struk @ 2015-06-16  2:03 UTC (permalink / raw)
  To: Herbert Xu
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On 06/15/2015 05:05 PM, Herbert Xu wrote:
>> > + * @setkey:	Function invokes the algorithm specific set key function, which
>> > + *		knows how to decode and interpret the BER encoded key
> We should split this into two functions: setpubkey and setprivkey.
> 

The two functions will be almost identical. We can do it this way if we want to check
if all the required elements of the key are provided. Currently I'm checking this in the
actual operation.

>> > + *
>> > + * @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);
>> > +	int (*maxsize)(struct crypto_akcipher *tfm);
> Hmm, we could actually get rid of maxsize by just having each
> function check the dst_len and if it is insufficient write the
> required length in it and then return an error.

Can do it that way too.
Thanks for your feedback. I will send v6 soon.
Thanks
T

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

* Re: [PATCH RFC v5 3/4] crypto: rsa: add a new rsa generic implementation
  2015-06-16  1:49     ` Tadeusz Struk
@ 2015-06-16  2:19       ` Stephan Mueller
  2015-06-16  2:26         ` Tadeusz Struk
  0 siblings, 1 reply; 33+ messages in thread
From: Stephan Mueller @ 2015-06-16  2:19 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: herbert, linux-kernel, keescook, jwboyer, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

Am Montag, 15. Juni 2015, 18:49:15 schrieb Tadeusz Struk:

Hi Tadeusz,

> On 06/15/2015 04:23 PM, Stephan Mueller wrote:
> >> +	/* In FIPS mode only allow key size minimum 2K */
> >> 
> >> > +	if (fips_enabled && (mpi_get_size(key->n) < 256)) {
> > 
> > Considering my previous email, shouldn't that check rather be
> > 
> > if (fips_enabled &&
> > 
> >     ((mpi_get_size(key->n) != 256) || (mpi_get_size(key->n) != 384))
> 
> I'm not familiar with the FIPS requirements. I checked the NIST
> recommendations witch states that RSA: |n| >= 2048 is acceptable. If FIPS
> allows 2K and 3K only then we need to change it.

The reason for exclusive 2k/3k is the CAVS testing: there is only the ability 
to test 2/3k. Longer key sizes are even not allowed as per SP800-131A in favor 
of EC.


-- 
Ciao
Stephan

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

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-15 23:59   ` Herbert Xu
@ 2015-06-16  2:21     ` Tadeusz Struk
  2015-06-16  2:29       ` Herbert Xu
  0 siblings, 1 reply; 33+ messages in thread
From: Tadeusz Struk @ 2015-06-16  2:21 UTC (permalink / raw)
  To: Herbert Xu
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On 06/15/2015 04:59 PM, Herbert Xu wrote:
>> > +struct crypto_akcipher {
>> > +	void *key;
> Having a void * pointer here is useless.  The normal way of doing
> it is to place the key into the tfm context.

I thought that the ctx needs to be available for implementations to store private data.
This way we can allocate and store any type of key in the <alg>_parse_key() helper and still have the cxt
available for implementations to use for their stuff (e.g. HW context).

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

* Re: [PATCH RFC v5 3/4] crypto: rsa: add a new rsa generic implementation
  2015-06-16  2:19       ` Stephan Mueller
@ 2015-06-16  2:26         ` Tadeusz Struk
  0 siblings, 0 replies; 33+ messages in thread
From: Tadeusz Struk @ 2015-06-16  2:26 UTC (permalink / raw)
  To: Stephan Mueller
  Cc: herbert, linux-kernel, keescook, jwboyer, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On 06/15/2015 07:19 PM, Stephan Mueller wrote:
>> I'm not familiar with the FIPS requirements. I checked the NIST
>> > recommendations witch states that RSA: |n| >= 2048 is acceptable. If FIPS
>> > allows 2K and 3K only then we need to change it.
> The reason for exclusive 2k/3k is the CAVS testing: there is only the ability 
> to test 2/3k. Longer key sizes are even not allowed as per SP800-131A in favor 
> of EC.

Ok I'll update it to only accept 2K & 3K. Thanks

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

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-16  2:03     ` Tadeusz Struk
@ 2015-06-16  2:27       ` Herbert Xu
  2015-06-16  2:41         ` Tadeusz Struk
  0 siblings, 1 reply; 33+ messages in thread
From: Herbert Xu @ 2015-06-16  2:27 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On Mon, Jun 15, 2015 at 07:03:11PM -0700, Tadeusz Struk wrote:
> On 06/15/2015 05:05 PM, Herbert Xu wrote:
> >> > + * @setkey:	Function invokes the algorithm specific set key function, which
> >> > + *		knows how to decode and interpret the BER encoded key
> > We should split this into two functions: setpubkey and setprivkey.
> > 
> 
> The two functions will be almost identical. We can do it this way if we want to check
> if all the required elements of the key are provided. Currently I'm checking this in the
> actual operation.

Right now your RSA setkey function only works if you supply both
the public key and the private key.  If the user supplies only one
key how are you going to tell whether it's public or private?

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] 33+ messages in thread

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-16  0:05   ` Herbert Xu
  2015-06-16  2:03     ` Tadeusz Struk
@ 2015-06-16  2:29     ` Tadeusz Struk
  2015-06-16  2:32       ` Herbert Xu
  1 sibling, 1 reply; 33+ messages in thread
From: Tadeusz Struk @ 2015-06-16  2:29 UTC (permalink / raw)
  To: Herbert Xu
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On 06/15/2015 05:05 PM, Herbert Xu wrote:
> Hmm, we could actually get rid of maxsize by just having each
> function check the dst_len and if it is insufficient write the
> required length in it and then return an error.

Actually I think it is useful. Without it the user will need to allocate
a buffer, and invoke an operation only to find out that the buffer need to be
bigger.

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

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-16  2:21     ` Tadeusz Struk
@ 2015-06-16  2:29       ` Herbert Xu
  2015-06-16  2:46         ` Tadeusz Struk
  0 siblings, 1 reply; 33+ messages in thread
From: Herbert Xu @ 2015-06-16  2:29 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On Mon, Jun 15, 2015 at 07:21:48PM -0700, Tadeusz Struk wrote:
>
> I thought that the ctx needs to be available for implementations to store private data.
> This way we can allocate and store any type of key in the <alg>_parse_key() helper and still have the cxt
> available for implementations to use for their stuff (e.g. HW context).

No for symmetric key algorithms we always store the key in the
context and never in the tfm proper.

Think about it, the generic tfm doesn't have any idea on what
the key contains so how can it store it? Only the implementation
knows the key format and can store it in a useful way.

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] 33+ messages in thread

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-16  2:29     ` Tadeusz Struk
@ 2015-06-16  2:32       ` Herbert Xu
  0 siblings, 0 replies; 33+ messages in thread
From: Herbert Xu @ 2015-06-16  2:32 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On Mon, Jun 15, 2015 at 07:29:45PM -0700, Tadeusz Struk wrote:
>
> Actually I think it is useful. Without it the user will need to allocate
> a buffer, and invoke an operation only to find out that the buffer need to be
> bigger.

No the user could simply supply NULL/0 and get the requisite
information if they have no idea what the proper size is.

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] 33+ messages in thread

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-16  2:27       ` Herbert Xu
@ 2015-06-16  2:41         ` Tadeusz Struk
  2015-06-16  3:25           ` Herbert Xu
  0 siblings, 1 reply; 33+ messages in thread
From: Tadeusz Struk @ 2015-06-16  2:41 UTC (permalink / raw)
  To: Herbert Xu
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On 06/15/2015 07:27 PM, Herbert Xu wrote:
>> The two functions will be almost identical. We can do it this way if we want to check
>> > if all the required elements of the key are provided. Currently I'm checking this in the
>> > actual operation.
> Right now your RSA setkey function only works if you supply both
> the public key and the private key.  If the user supplies only one
> key how are you going to tell whether it's public or private?

User can supply only public key and invoke encrypt() or verify() without any problem.
When the user invokes decrypt() or sign() then it will work only after the setkey was
given a private key. This is checked in the actual operation.
So the user is responsible for providing an appropriate key for given operation.
We can split it if you think this is the right thing to do, but currently it works fine.

 

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

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-16  2:29       ` Herbert Xu
@ 2015-06-16  2:46         ` Tadeusz Struk
  2015-06-16  2:50           ` Herbert Xu
  0 siblings, 1 reply; 33+ messages in thread
From: Tadeusz Struk @ 2015-06-16  2:46 UTC (permalink / raw)
  To: Herbert Xu
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On 06/15/2015 07:29 PM, Herbert Xu wrote:
>> I thought that the ctx needs to be available for implementations to store private data.
>> > This way we can allocate and store any type of key in the <alg>_parse_key() helper and still have the cxt
>> > available for implementations to use for their stuff (e.g. HW context).
> No for symmetric key algorithms we always store the key in the
> context and never in the tfm proper.
> 
> Think about it, the generic tfm doesn't have any idea on what
> the key contains so how can it store it? Only the implementation
> knows the key format and can store it in a useful way.

Ok I wanted to handle everything in the parse_key helper without any help from the implementation.
I can change the helper to return the key and implementation will store it in the ctx. Is this
what you are suggesting?

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

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-16  2:46         ` Tadeusz Struk
@ 2015-06-16  2:50           ` Herbert Xu
  2015-06-16  2:55             ` Tadeusz Struk
  0 siblings, 1 reply; 33+ messages in thread
From: Herbert Xu @ 2015-06-16  2:50 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On Mon, Jun 15, 2015 at 07:46:28PM -0700, Tadeusz Struk wrote:
>
> Ok I wanted to handle everything in the parse_key helper without any help from the implementation.
> I can change the helper to return the key and implementation will store it in the ctx. Is this
> what you are suggesting?

If you want to keep the helper generic what you can do is have
it take struct rsa_key instead of struct crypto_ablkcipher.

It definitely should just be an optional helper as opposed to
a required part of crypto_akcipher since you could have a piece
of hardware that takes the encoded key directly in which case
you wouldn't need the helper at all.

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] 33+ messages in thread

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-16  2:50           ` Herbert Xu
@ 2015-06-16  2:55             ` Tadeusz Struk
  0 siblings, 0 replies; 33+ messages in thread
From: Tadeusz Struk @ 2015-06-16  2:55 UTC (permalink / raw)
  To: Herbert Xu
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On 06/15/2015 07:50 PM, Herbert Xu wrote:
> If you want to keep the helper generic what you can do is have
> it take struct rsa_key instead of struct crypto_ablkcipher.

Ok I'll do it that way.

> 
> It definitely should just be an optional helper as opposed to
> a required part of crypto_akcipher since you could have a piece
> of hardware that takes the encoded key directly in which case
> you wouldn't need the helper at all.

Oh yes, it is definitely optional.
Thanks

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

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-16  2:41         ` Tadeusz Struk
@ 2015-06-16  3:25           ` Herbert Xu
  2015-06-16  3:36             ` Tadeusz Struk
  0 siblings, 1 reply; 33+ messages in thread
From: Herbert Xu @ 2015-06-16  3:25 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On Mon, Jun 15, 2015 at 07:41:14PM -0700, Tadeusz Struk wrote:
>
> User can supply only public key and invoke encrypt() or verify() without any problem.
> When the user invokes decrypt() or sign() then it will work only after the setkey was
> given a private key. This is checked in the actual operation.

The current parse_key function requires all three number to be
present, n, e, and d, no?

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] 33+ messages in thread

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-16  3:25           ` Herbert Xu
@ 2015-06-16  3:36             ` Tadeusz Struk
  2015-06-16  4:06               ` Herbert Xu
  0 siblings, 1 reply; 33+ messages in thread
From: Tadeusz Struk @ 2015-06-16  3:36 UTC (permalink / raw)
  To: Herbert Xu
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On 06/15/2015 08:25 PM, Herbert Xu wrote:
> The current parse_key function requires all three number to be
> present, n, e, and d, no?

No, it will handle whatever it will find. So if a public key will be passed it will only set "n" and "e".
If a private key will be passed it will set all three "n", "e", and "d".
Then during operation I check if there is everything that's required.

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

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-16  3:36             ` Tadeusz Struk
@ 2015-06-16  4:06               ` Herbert Xu
  2015-06-16  4:48                 ` Tadeusz Struk
  0 siblings, 1 reply; 33+ messages in thread
From: Herbert Xu @ 2015-06-16  4:06 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On Mon, Jun 15, 2015 at 08:36:06PM -0700, Tadeusz Struk wrote:
> On 06/15/2015 08:25 PM, Herbert Xu wrote:
> > The current parse_key function requires all three number to be
> > present, n, e, and d, no?
> 
> No, it will handle whatever it will find. So if a public key will be passed it will only set "n" and "e".
> If a private key will be passed it will set all three "n", "e", and "d".
> Then during operation I check if there is everything that's required.

AFAICS the ASN1 parser will call all three functions and bomb out
if any one of them fails.  If you did make them all optional then
you'd need to check to ensure that at least n and e are present.

Also all your test vectors contain private keys.  Please add at
least one that contains a public key only to test this.

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] 33+ messages in thread

* Re: [PATCH RFC v5 2/4] crypto: add PKE API
  2015-06-16  4:06               ` Herbert Xu
@ 2015-06-16  4:48                 ` Tadeusz Struk
  0 siblings, 0 replies; 33+ messages in thread
From: Tadeusz Struk @ 2015-06-16  4:48 UTC (permalink / raw)
  To: Herbert Xu
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On 06/15/2015 09:06 PM, Herbert Xu wrote:
>> No, it will handle whatever it will find. So if a public key will be passed it will only set "n" and "e".
>> > If a private key will be passed it will set all three "n", "e", and "d".
>> > Then during operation I check if there is everything that's required.
> AFAICS the ASN1 parser will call all three functions and bomb out
> if any one of them fails.  If you did make them all optional then
> you'd need to check to ensure that at least n and e are present.
> 
> Also all your test vectors contain private keys.  Please add at
> least one that contains a public key only to test this.

I've just tested it and it works fine for both private and public keys.
I'll add one vector to test only public key case.
Thanks

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

* Re: [PATCH RFC v5 4/4] crypto: add tests vectors for RSA
  2015-06-16  0:37   ` Herbert Xu
@ 2015-06-16  6:26     ` Tadeusz Struk
  2015-06-16  6:28       ` Herbert Xu
  0 siblings, 1 reply; 33+ messages in thread
From: Tadeusz Struk @ 2015-06-16  6:26 UTC (permalink / raw)
  To: Herbert Xu
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On 06/15/2015 05:37 PM, Herbert Xu wrote:
>>  config CRYPTO_MANAGER
>> >  	tristate "Cryptographic algorithm manager"
>> >  	select CRYPTO_MANAGER2
>> > +	select CRYPTO_AKCIPHER
> Please add this to CRYPTO_MANAGER2 instead.

This causes a recursive dependency error

crypto/Kconfig:115:error: recursive dependency detected!
crypto/Kconfig:115:	symbol CRYPTO_MANAGER2 default value contains CRYPTO_ALGAPI
crypto/Kconfig:34:	symbol CRYPTO_ALGAPI is selected by CRYPTO_AKCIPHER
crypto/Kconfig:94:	symbol CRYPTO_AKCIPHER is selected by CRYPTO_MANAGER2

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

* Re: [PATCH RFC v5 4/4] crypto: add tests vectors for RSA
  2015-06-16  6:26     ` Tadeusz Struk
@ 2015-06-16  6:28       ` Herbert Xu
  0 siblings, 0 replies; 33+ messages in thread
From: Herbert Xu @ 2015-06-16  6:28 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On Mon, Jun 15, 2015 at 11:26:58PM -0700, Tadeusz Struk wrote:
> On 06/15/2015 05:37 PM, Herbert Xu wrote:
> >>  config CRYPTO_MANAGER
> >> >  	tristate "Cryptographic algorithm manager"
> >> >  	select CRYPTO_MANAGER2
> >> > +	select CRYPTO_AKCIPHER
> > Please add this to CRYPTO_MANAGER2 instead.
> 
> This causes a recursive dependency error
> 
> crypto/Kconfig:115:error: recursive dependency detected!
> crypto/Kconfig:115:	symbol CRYPTO_MANAGER2 default value contains CRYPTO_ALGAPI
> crypto/Kconfig:34:	symbol CRYPTO_ALGAPI is selected by CRYPTO_AKCIPHER
> crypto/Kconfig:94:	symbol CRYPTO_AKCIPHER is selected by CRYPTO_MANAGER2

That's because you need to split AKCIPHER into AKCIPHER and
AKCIPHER2 just like every other type.

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] 33+ messages in thread

* Re: [PATCH RFC v5 1/4] MPILIB: add mpi_read_buf() and mpi_get_size() helpers
  2015-06-15 20:18 ` [PATCH RFC v5 1/4] MPILIB: add mpi_read_buf() and mpi_get_size() helpers Tadeusz Struk
@ 2015-06-16  6:40   ` Herbert Xu
  0 siblings, 0 replies; 33+ messages in thread
From: Herbert Xu @ 2015-06-16  6:40 UTC (permalink / raw)
  To: Tadeusz Struk
  Cc: linux-kernel, keescook, jwboyer, smueller, richard, steved,
	qat-linux, dhowells, linux-crypto, james.l.morris, jkosina,
	zohar, davem, vgoyal

On Mon, Jun 15, 2015 at 01:18:36PM -0700, Tadeusz Struk wrote:
> Added a mpi_read_buf() helper function to export MPI to a buf provided by
> the user, and a mpi_get_size() helper, that tells the user how big the buf is.
> Changed mpi_free to use kzfree instead of kfree because it is used to free
> crypto keys.
> 
> Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>

Patch applied.  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] 33+ messages in thread

end of thread, other threads:[~2015-06-16  6:40 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-15 20:18 [PATCH RFC v5 0/4] crypto: Introduce Public Key Encryption API Tadeusz Struk
2015-06-15 20:18 ` [PATCH RFC v5 1/4] MPILIB: add mpi_read_buf() and mpi_get_size() helpers Tadeusz Struk
2015-06-16  6:40   ` Herbert Xu
2015-06-15 20:18 ` [PATCH RFC v5 2/4] crypto: add PKE API Tadeusz Struk
2015-06-15 23:46   ` Herbert Xu
2015-06-15 23:49   ` Herbert Xu
2015-06-15 23:50   ` Herbert Xu
2015-06-15 23:54   ` Herbert Xu
2015-06-15 23:59   ` Herbert Xu
2015-06-16  2:21     ` Tadeusz Struk
2015-06-16  2:29       ` Herbert Xu
2015-06-16  2:46         ` Tadeusz Struk
2015-06-16  2:50           ` Herbert Xu
2015-06-16  2:55             ` Tadeusz Struk
2015-06-16  0:05   ` Herbert Xu
2015-06-16  2:03     ` Tadeusz Struk
2015-06-16  2:27       ` Herbert Xu
2015-06-16  2:41         ` Tadeusz Struk
2015-06-16  3:25           ` Herbert Xu
2015-06-16  3:36             ` Tadeusz Struk
2015-06-16  4:06               ` Herbert Xu
2015-06-16  4:48                 ` Tadeusz Struk
2015-06-16  2:29     ` Tadeusz Struk
2015-06-16  2:32       ` Herbert Xu
2015-06-15 20:18 ` [PATCH RFC v5 3/4] crypto: rsa: add a new rsa generic implementation Tadeusz Struk
2015-06-15 23:23   ` Stephan Mueller
2015-06-16  1:49     ` Tadeusz Struk
2015-06-16  2:19       ` Stephan Mueller
2015-06-16  2:26         ` Tadeusz Struk
2015-06-15 20:18 ` [PATCH RFC v5 4/4] crypto: add tests vectors for RSA Tadeusz Struk
2015-06-16  0:37   ` Herbert Xu
2015-06-16  6:26     ` Tadeusz Struk
2015-06-16  6:28       ` Herbert Xu

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.