All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] crypto: Updates to akcipher API
@ 2015-09-09 16:14 Tadeusz Struk
  2015-09-09 16:15 ` [PATCH 1/8] crypto: akcipher - return status from crypto_unregister_alg Tadeusz Struk
                   ` (7 more replies)
  0 siblings, 8 replies; 32+ messages in thread
From: Tadeusz Struk @ 2015-09-09 16:14 UTC (permalink / raw)
  To: herbert; +Cc: linux-crypto, qat-linux, tadeusz.struk

This series introduce updates to the akcipher API.
setkey function has been split into set_pub_key and
set_priv_key.
Input and output buffers are now sgl instread of void *
It also includes some minor updates like status check
from crypto_unregister_akcipher which was not checked
before.

---

Tadeusz Struk (8):
      crypto: akcipher - return status from crypto_unregister_alg
      crypto: rsa - check status returned from crypto_unregister_akcipher
      crypto: qat - check status returned from crypto_unregister_akcipher
      crypto: akcipher - Changes to asymmetric key API
      lib/scatterlist: Add sg_len helper
      crypto: rsa - update accoring to akcipher API changes
      crypto: qat - update accoring to akcipher API changes
      crypto: testmgr - update test mgr


 crypto/Makefile                                   |    9 +
 crypto/akcipher.c                                 |    4 
 crypto/rsa.c                                      |  191 ++++++++++++++---
 crypto/rsa_helper.c                               |   42 +++-
 crypto/rsakey.asn1                                |    5 
 crypto/rsaprivkey.asn1                            |   11 +
 crypto/rsapubkey.asn1                             |    4 
 crypto/testmgr.c                                  |   40 ++--
 crypto/testmgr.h                                  |   36 ++-
 drivers/crypto/qat/qat_common/Makefile            |   12 +
 drivers/crypto/qat/qat_common/adf_common_drv.h    |    2 
 drivers/crypto/qat/qat_common/adf_init.c          |    6 -
 drivers/crypto/qat/qat_common/qat_asym_algs.c     |  232 +++++++++++++++------
 drivers/crypto/qat/qat_common/qat_rsakey.asn1     |    5 
 drivers/crypto/qat/qat_common/qat_rsaprivkey.asn1 |   11 +
 drivers/crypto/qat/qat_common/qat_rsapubkey.asn1  |    4 
 include/crypto/akcipher.h                         |   99 ++++++---
 include/crypto/internal/akcipher.h                |    4 
 include/crypto/internal/rsa.h                     |    7 -
 include/linux/scatterlist.h                       |    1 
 lib/scatterlist.c                                 |   17 ++
 21 files changed, 552 insertions(+), 190 deletions(-)
 delete mode 100644 crypto/rsakey.asn1
 create mode 100644 crypto/rsaprivkey.asn1
 create mode 100644 crypto/rsapubkey.asn1
 delete mode 100644 drivers/crypto/qat/qat_common/qat_rsakey.asn1
 create mode 100644 drivers/crypto/qat/qat_common/qat_rsaprivkey.asn1
 create mode 100644 drivers/crypto/qat/qat_common/qat_rsapubkey.asn1

--
Signature

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

* [PATCH 1/8] crypto: akcipher - return status from crypto_unregister_alg
  2015-09-09 16:14 [PATCH 0/8] crypto: Updates to akcipher API Tadeusz Struk
@ 2015-09-09 16:15 ` Tadeusz Struk
  2015-09-18 11:29   ` Herbert Xu
  2015-09-09 16:15 ` [PATCH 2/8] crypto: rsa - check status returned from crypto_unregister_akcipher Tadeusz Struk
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 32+ messages in thread
From: Tadeusz Struk @ 2015-09-09 16:15 UTC (permalink / raw)
  To: herbert; +Cc: linux-crypto, qat-linux, tadeusz.struk

Return status from crypto_unregister_alg to the caller.

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
 crypto/akcipher.c                  |    4 ++--
 include/crypto/internal/akcipher.h |    4 +++-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/crypto/akcipher.c b/crypto/akcipher.c
index 528ae6a..9cd84f7 100644
--- a/crypto/akcipher.c
+++ b/crypto/akcipher.c
@@ -107,9 +107,9 @@ int crypto_register_akcipher(struct akcipher_alg *alg)
 }
 EXPORT_SYMBOL_GPL(crypto_register_akcipher);
 
-void crypto_unregister_akcipher(struct akcipher_alg *alg)
+int crypto_unregister_akcipher(struct akcipher_alg *alg)
 {
-	crypto_unregister_alg(&alg->base);
+	return crypto_unregister_alg(&alg->base);
 }
 EXPORT_SYMBOL_GPL(crypto_unregister_akcipher);
 
diff --git a/include/crypto/internal/akcipher.h b/include/crypto/internal/akcipher.h
index 9a2bda1..9ea7bc9 100644
--- a/include/crypto/internal/akcipher.h
+++ b/include/crypto/internal/akcipher.h
@@ -55,6 +55,8 @@ int crypto_register_akcipher(struct akcipher_alg *alg);
  * Function unregisters an implementation of a public key verify algorithm
  *
  * @alg:	algorithm definition
+ *
+ * Return: zero on success; error code in case of error
  */
-void crypto_unregister_akcipher(struct akcipher_alg *alg);
+int crypto_unregister_akcipher(struct akcipher_alg *alg);
 #endif

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

* [PATCH 2/8] crypto: rsa - check status returned from crypto_unregister_akcipher
  2015-09-09 16:14 [PATCH 0/8] crypto: Updates to akcipher API Tadeusz Struk
  2015-09-09 16:15 ` [PATCH 1/8] crypto: akcipher - return status from crypto_unregister_alg Tadeusz Struk
@ 2015-09-09 16:15 ` Tadeusz Struk
  2015-09-09 16:15 ` [PATCH 3/8] crypto: qat " Tadeusz Struk
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 32+ messages in thread
From: Tadeusz Struk @ 2015-09-09 16:15 UTC (permalink / raw)
  To: herbert; +Cc: linux-crypto, qat-linux, tadeusz.struk

Add status check returned from crypto_unregister_akcipher function.

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
 crypto/rsa.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto/rsa.c b/crypto/rsa.c
index 466003e..93feae2 100644
--- a/crypto/rsa.c
+++ b/crypto/rsa.c
@@ -329,7 +329,7 @@ static int rsa_init(void)
 
 static void rsa_exit(void)
 {
-	crypto_unregister_akcipher(&rsa);
+	WARN_ON(crypto_unregister_akcipher(&rsa));
 }
 
 module_init(rsa_init);

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

* [PATCH 3/8] crypto: qat - check status returned from crypto_unregister_akcipher
  2015-09-09 16:14 [PATCH 0/8] crypto: Updates to akcipher API Tadeusz Struk
  2015-09-09 16:15 ` [PATCH 1/8] crypto: akcipher - return status from crypto_unregister_alg Tadeusz Struk
  2015-09-09 16:15 ` [PATCH 2/8] crypto: rsa - check status returned from crypto_unregister_akcipher Tadeusz Struk
@ 2015-09-09 16:15 ` Tadeusz Struk
  2015-09-09 16:15 ` [PATCH 4/8] crypto: akcipher - Changes to asymmetric key API Tadeusz Struk
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 32+ messages in thread
From: Tadeusz Struk @ 2015-09-09 16:15 UTC (permalink / raw)
  To: herbert; +Cc: linux-crypto, qat-linux, tadeusz.struk

Add status check returned from crypto_unregister_akcipher.

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
 drivers/crypto/qat/qat_common/adf_common_drv.h |    2 +-
 drivers/crypto/qat/qat_common/adf_init.c       |    6 ++----
 drivers/crypto/qat/qat_common/qat_asym_algs.c  |    7 +++++--
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/crypto/qat/qat_common/adf_common_drv.h b/drivers/crypto/qat/qat_common/adf_common_drv.h
index 7836dff..6882c52 100644
--- a/drivers/crypto/qat/qat_common/adf_common_drv.h
+++ b/drivers/crypto/qat/qat_common/adf_common_drv.h
@@ -168,7 +168,7 @@ void qat_algs_exit(void);
 int qat_algs_register(void);
 int qat_algs_unregister(void);
 int qat_asym_algs_register(void);
-void qat_asym_algs_unregister(void);
+int qat_asym_algs_unregister(void);
 
 int qat_hal_init(struct adf_accel_dev *accel_dev);
 void qat_hal_deinit(struct icp_qat_fw_loader_handle *handle);
diff --git a/drivers/crypto/qat/qat_common/adf_init.c b/drivers/crypto/qat/qat_common/adf_init.c
index ac37a89..e9d52a8 100644
--- a/drivers/crypto/qat/qat_common/adf_init.c
+++ b/drivers/crypto/qat/qat_common/adf_init.c
@@ -272,13 +272,11 @@ int adf_dev_stop(struct adf_accel_dev *accel_dev)
 	clear_bit(ADF_STATUS_STARTING, &accel_dev->status);
 	clear_bit(ADF_STATUS_STARTED, &accel_dev->status);
 
-	if (!list_empty(&accel_dev->crypto_list) && qat_algs_unregister())
+	if (!list_empty(&accel_dev->crypto_list) &&
+	    (qat_algs_unregister() || qat_asym_algs_unregister()))
 		dev_err(&GET_DEV(accel_dev),
 			"Failed to unregister crypto algs\n");
 
-	if (!list_empty(&accel_dev->crypto_list))
-		qat_asym_algs_unregister();
-
 	list_for_each(list_itr, &service_table) {
 		service = list_entry(list_itr, struct service_hndl, list);
 		if (!test_bit(accel_dev->accel_id, &service->start_status))
diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c b/drivers/crypto/qat/qat_common/qat_asym_algs.c
index e87f510..7de765d 100644
--- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
+++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
@@ -643,10 +643,13 @@ int qat_asym_algs_register(void)
 	return ret;
 }
 
-void qat_asym_algs_unregister(void)
+int qat_asym_algs_unregister(void)
 {
+	int ret = 0;
+
 	mutex_lock(&algs_lock);
 	if (--active_devs == 0)
-		crypto_unregister_akcipher(&rsa);
+		ret = crypto_unregister_akcipher(&rsa);
 	mutex_unlock(&algs_lock);
+	return ret;
 }

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

* [PATCH 4/8] crypto: akcipher - Changes to asymmetric key API
  2015-09-09 16:14 [PATCH 0/8] crypto: Updates to akcipher API Tadeusz Struk
                   ` (2 preceding siblings ...)
  2015-09-09 16:15 ` [PATCH 3/8] crypto: qat " Tadeusz Struk
@ 2015-09-09 16:15 ` Tadeusz Struk
  2015-09-09 16:25   ` Stephan Mueller
  2015-09-18 11:35   ` Herbert Xu
  2015-09-09 16:15 ` [PATCH 5/8] lib/scatterlist: Add sg_len helper Tadeusz Struk
                   ` (3 subsequent siblings)
  7 siblings, 2 replies; 32+ messages in thread
From: Tadeusz Struk @ 2015-09-09 16:15 UTC (permalink / raw)
  To: herbert; +Cc: linux-crypto, qat-linux, tadeusz.struk

Setkey function has been split into set_priv_key and set_pub_key.
Akcipher requests takes sgl for src and dst instead of void *.
Users of the API need to be disabled so that the build works fine
after this patch.
They will be enabled in subsequent patches.

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
 crypto/Makefile                        |    5 --
 crypto/testmgr.c                       |    4 +
 drivers/crypto/qat/qat_common/Makefile |    2 -
 include/crypto/akcipher.h              |   99 ++++++++++++++++++++++----------
 4 files changed, 71 insertions(+), 39 deletions(-)

diff --git a/crypto/Makefile b/crypto/Makefile
index e2c5981..65e91da 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -34,11 +34,6 @@ obj-$(CONFIG_CRYPTO_AKCIPHER2) += 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/testmgr.c b/crypto/testmgr.c
index 35c2de1..2f2b66e 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -1835,6 +1835,7 @@ static int alg_test_drbg(const struct alg_test_desc *desc, const char *driver,
 
 }
 
+#if 0
 static int do_test_rsa(struct crypto_akcipher *tfm,
 		       struct akcipher_testvec *vecs)
 {
@@ -1975,6 +1976,7 @@ static int alg_test_akcipher(const struct alg_test_desc *desc,
 	crypto_free_akcipher(tfm);
 	return err;
 }
+#endif
 
 static int alg_test_null(const struct alg_test_desc *desc,
 			     const char *driver, u32 type, u32 mask)
@@ -3611,7 +3613,7 @@ static const struct alg_test_desc alg_test_descs[] = {
 		}
 	}, {
 		.alg = "rsa",
-		.test = alg_test_akcipher,
+		.test = alg_test_null,
 		.fips_allowed = 1,
 		.suite = {
 			.akcipher = {
diff --git a/drivers/crypto/qat/qat_common/Makefile b/drivers/crypto/qat/qat_common/Makefile
index df20a9d..ba5abdb 100644
--- a/drivers/crypto/qat/qat_common/Makefile
+++ b/drivers/crypto/qat/qat_common/Makefile
@@ -13,8 +13,6 @@ intel_qat-objs := adf_cfg.o \
 	adf_hw_arbiter.o \
 	qat_crypto.o \
 	qat_algs.o \
-	qat_rsakey-asn1.o \
-	qat_asym_algs.o \
 	qat_uclo.o \
 	qat_hal.o
 
diff --git a/include/crypto/akcipher.h b/include/crypto/akcipher.h
index 69d163e..7380e25 100644
--- a/include/crypto/akcipher.h
+++ b/include/crypto/akcipher.h
@@ -13,28 +13,25 @@
 #ifndef _CRYPTO_AKCIPHER_H
 #define _CRYPTO_AKCIPHER_H
 #include <linux/crypto.h>
+#include <linux/scatterlist.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
- *		After operation it will be updated with the acctual size of the
- *		result. In case of error, where the dst_len was insufficient,
+ * @src:	Source data
+ * @dst:	Destination data
+ * @out_len:	Size of the result. After operation it will be updated with
+ *		the acctual size of the data stored in the dst.
+ *		In case of error, where the dst sgl size was insufficient,
  *		it will be updated to the size required for the operation.
  * @__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;
+	struct scatterlist *src;
+	struct scatterlist *dst;
+	unsigned int out_len;
 	void *__ctx[] CRYPTO_MINALIGN_ATTR;
 };
 
@@ -67,8 +64,13 @@ struct crypto_akcipher {
  *		algorithm. In case of error, where the dst_len was insufficient,
  *		the req->dst_len will be updated to the size required for the
  *		operation
- * @setkey:	Function invokes the algorithm specific set key function, which
- *		knows how to decode and interpret the BER encoded key
+ * @set_pub_key: Function invokes the algorithm specific set public key
+ *		function, which knows how to decode and interpret
+ *		the BER encoded public key
+ * @set_priv_key: Function invokes the algorithm specific set private key
+ *		function, which knows how to decode and interpret
+ *		the BER encoded private key
+ * @get_len:	Function returns minimum dest buffer size for a given key.
  * @init:	Initialize the cryptographic transformation object.
  *		This function is used to initialize the cryptographic
  *		transformation object. This function is called only once at
@@ -89,8 +91,11 @@ struct akcipher_alg {
 	int (*verify)(struct akcipher_request *req);
 	int (*encrypt)(struct akcipher_request *req);
 	int (*decrypt)(struct akcipher_request *req);
-	int (*setkey)(struct crypto_akcipher *tfm, const void *key,
-		      unsigned int keylen);
+	int (*set_pub_key)(struct crypto_akcipher *tfm, const void *key,
+			   unsigned int keylen);
+	int (*set_priv_key)(struct crypto_akcipher *tfm, const void *key,
+			    unsigned int keylen);
+	int (*get_len)(struct crypto_akcipher *tfm);
 	int (*init)(struct crypto_akcipher *tfm);
 	void (*exit)(struct crypto_akcipher *tfm);
 
@@ -229,21 +234,31 @@ static inline void akcipher_request_set_callback(struct akcipher_request *req,
  * 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. It will be updated by the
- *		implementation to reflect the acctual size of the result
+ * @src:	ptr to input scatter list
+ * @dst:	ptr to output scatter list
  */
 static inline void akcipher_request_set_crypt(struct akcipher_request *req,
-					      void *src, void *dst,
-					      unsigned int src_len,
-					      unsigned int dst_len)
+					      struct scatterlist *src,
+					      struct scatterlist *dst)
 {
 	req->src = src;
 	req->dst = dst;
-	req->src_len = src_len;
-	req->dst_len = dst_len;
+}
+
+/**
+ * crypto_akcipher_get_len() -- Get minimum len for output buffer
+ *
+ * Function returns minimum dest buffer size for a given key
+ *
+ * @tfm:	AKCIPHER tfm handle allocated with crypto_alloc_akcipher()
+ *
+ * Return: minimum len for output buffer or error code in key hasn't been set
+ */
+static inline int crypto_akcipher_get_len(struct crypto_akcipher *tfm)
+{
+	struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
+
+	return alg->get_len(tfm);
 }
 
 /**
@@ -319,22 +334,44 @@ static inline int crypto_akcipher_verify(struct akcipher_request *req)
 }
 
 /**
- * crypto_akcipher_setkey() -- Invoke public key setkey operation
+ * crypto_akcipher_set_pub_key() -- Invoke set public key 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 public key
+ * @keylen:	length of the key
+ *
+ * Return: zero on success; error code in case of error
+ */
+static inline int crypto_akcipher_set_pub_key(struct crypto_akcipher *tfm,
+					      const void *key,
+					      unsigned int keylen)
+{
+	struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
+
+	return alg->set_pub_key(tfm, key, keylen);
+}
+
+/**
+ * crypto_akcipher_set_priv_key() -- Invoke set private key 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
+ * @key:	BER encoded private key
  * @keylen:	length of the key
  *
  * Return: zero on success; error code in case of error
  */
-static inline int crypto_akcipher_setkey(struct crypto_akcipher *tfm, void *key,
-					 unsigned int keylen)
+static inline int crypto_akcipher_set_priv_key(struct crypto_akcipher *tfm,
+					       const void *key,
+					       unsigned int keylen)
 {
 	struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
 
-	return alg->setkey(tfm, key, keylen);
+	return alg->set_priv_key(tfm, key, keylen);
 }
 #endif

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

* [PATCH 5/8] lib/scatterlist: Add sg_len helper
  2015-09-09 16:14 [PATCH 0/8] crypto: Updates to akcipher API Tadeusz Struk
                   ` (3 preceding siblings ...)
  2015-09-09 16:15 ` [PATCH 4/8] crypto: akcipher - Changes to asymmetric key API Tadeusz Struk
@ 2015-09-09 16:15 ` Tadeusz Struk
  2015-09-09 16:27   ` Stephan Mueller
  2015-09-09 16:15 ` [PATCH 6/8] crypto: rsa - update accoring to akcipher API changes Tadeusz Struk
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 32+ messages in thread
From: Tadeusz Struk @ 2015-09-09 16:15 UTC (permalink / raw)
  To: herbert; +Cc: linux-crypto, qat-linux, tadeusz.struk

Add sg_len function which returns the total number of bytes in sg.

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
 include/linux/scatterlist.h |    1 +
 lib/scatterlist.c           |   18 ++++++++++++++++++
 2 files changed, 19 insertions(+)

diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 9b1ef0c..7c82fc1 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -246,6 +246,7 @@ static inline void *sg_virt(struct scatterlist *sg)
 }
 
 int sg_nents(struct scatterlist *sg);
+int sg_len(struct scatterlist *sg);
 int sg_nents_for_len(struct scatterlist *sg, u64 len);
 struct scatterlist *sg_next(struct scatterlist *);
 struct scatterlist *sg_last(struct scatterlist *s, unsigned int);
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index d105a9f..71324bb 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -57,6 +57,24 @@ int sg_nents(struct scatterlist *sg)
 EXPORT_SYMBOL(sg_nents);
 
 /**
+  * sg_len - return total size of bytes in the scatterlist
+  * @sg:         The scatterlist
+  *
+  * Description:
+  * Allows to know how the total size of bytes in sg, taking into acount
+  * chaining as well
+  **/
+int sg_len(struct scatterlist *sg)
+{
+	int len;
+
+	for (len = 0; sg; sg = sg_next(sg))
+		len += sg->length;
+	return len;
+}
+EXPORT_SYMBOL(sg_len);
+
+/**
  * sg_nents_for_len - return total count of entries in scatterlist
  *                    needed to satisfy the supplied length
  * @sg:		The scatterlist

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

* [PATCH 6/8] crypto: rsa - update accoring to akcipher API changes
  2015-09-09 16:14 [PATCH 0/8] crypto: Updates to akcipher API Tadeusz Struk
                   ` (4 preceding siblings ...)
  2015-09-09 16:15 ` [PATCH 5/8] lib/scatterlist: Add sg_len helper Tadeusz Struk
@ 2015-09-09 16:15 ` Tadeusz Struk
  2015-09-09 16:35   ` Stephan Mueller
  2015-09-09 16:15 ` [PATCH 7/8] crypto: qat " Tadeusz Struk
  2015-09-09 16:15 ` [PATCH 8/8] crypto: testmgr - update test mgr according to " Tadeusz Struk
  7 siblings, 1 reply; 32+ messages in thread
From: Tadeusz Struk @ 2015-09-09 16:15 UTC (permalink / raw)
  To: herbert; +Cc: linux-crypto, qat-linux, tadeusz.struk

Rsa updates to reflect the API changes.

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
 crypto/Makefile               |   12 ++-
 crypto/rsa.c                  |  188 ++++++++++++++++++++++++++++++++++-------
 crypto/rsa_helper.c           |   42 ++++++++-
 crypto/rsakey.asn1            |    5 -
 crypto/rsaprivkey.asn1        |   11 ++
 crypto/rsapubkey.asn1         |    4 +
 include/crypto/internal/rsa.h |    7 +-
 7 files changed, 220 insertions(+), 49 deletions(-)
 delete mode 100644 crypto/rsakey.asn1
 create mode 100644 crypto/rsaprivkey.asn1
 create mode 100644 crypto/rsapubkey.asn1

diff --git a/crypto/Makefile b/crypto/Makefile
index 65e91da..d897e0b 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -31,8 +31,16 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 
-$(obj)/rsakey-asn1.o: $(obj)/rsakey-asn1.c $(obj)/rsakey-asn1.h
-clean-files += rsakey-asn1.c rsakey-asn1.h
+$(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
+$(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
+clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
+clean-files += rsaprivkey-asn1.c rsaprivkey-asn1.h
+
+rsa_generic-y := rsapubkey-asn1.o
+rsa_generic-y += rsaprivkey-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
 
diff --git a/crypto/rsa.c b/crypto/rsa.c
index 93feae2..f5b956c 100644
--- a/crypto/rsa.c
+++ b/crypto/rsa.c
@@ -13,6 +13,7 @@
 #include <crypto/internal/rsa.h>
 #include <crypto/internal/akcipher.h>
 #include <crypto/akcipher.h>
+#include <crypto/scatterwalk.h>
 
 /*
  * RSAEP function [RFC3447 sec 5.1.1]
@@ -80,34 +81,57 @@ static int rsa_enc(struct akcipher_request *req)
 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
 	const struct rsa_key *pkey = rsa_get_key(tfm);
 	MPI m, c = mpi_alloc(0);
+	int src_len = sg_len(req->src), dst_len = sg_len(req->dst);
 	int ret = 0;
 	int sign;
 
 	if (!c)
 		return -ENOMEM;
 
-	if (unlikely(!pkey->n || !pkey->e)) {
+	if (unlikely(!pkey->n || !pkey->e || !src_len)) {
 		ret = -EINVAL;
 		goto err_free_c;
 	}
 
-	if (req->dst_len < mpi_get_size(pkey->n)) {
-		req->dst_len = mpi_get_size(pkey->n);
+	if (dst_len < mpi_get_size(pkey->n)) {
+		req->out_len = mpi_get_size(pkey->n);
 		ret = -EOVERFLOW;
 		goto err_free_c;
 	}
 
-	m = mpi_read_raw_data(req->src, req->src_len);
-	if (!m) {
-		ret = -ENOMEM;
-		goto err_free_c;
+	ret = -ENOMEM;
+	if (sg_is_last(req->src)) {
+		m = mpi_read_raw_data(sg_virt(req->src), src_len);
+	} else {
+		void *ptr = kmalloc(src_len, GFP_KERNEL);
+
+		if (!ptr)
+			goto err_free_c;
+
+		scatterwalk_map_and_copy(ptr, req->src, 0, src_len, 0);
+		m = mpi_read_raw_data(ptr, src_len);
+		kfree(ptr);
 	}
+	if (!m)
+		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, &req->dst_len, &sign);
+	if (sg_is_last(req->dst)) {
+		ret = mpi_read_buffer(c, sg_virt(req->dst), dst_len,
+				      &req->out_len, &sign);
+	} else {
+		void *ptr = kmalloc(dst_len, GFP_KERNEL);
+
+		if (!ptr)
+			goto err_free_m;
+
+		ret = mpi_read_buffer(c, ptr, dst_len, &req->out_len, &sign);
+		scatterwalk_map_and_copy(ptr, req->dst, 0, dst_len, 1);
+		kfree(ptr);
+	}
 	if (ret)
 		goto err_free_m;
 
@@ -128,34 +152,57 @@ static int rsa_dec(struct akcipher_request *req)
 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
 	const struct rsa_key *pkey = rsa_get_key(tfm);
 	MPI c, m = mpi_alloc(0);
+	int src_len = sg_len(req->src), dst_len = sg_len(req->dst);
 	int ret = 0;
 	int sign;
 
 	if (!m)
 		return -ENOMEM;
 
-	if (unlikely(!pkey->n || !pkey->d)) {
+	if (unlikely(!pkey->n || !pkey->d || !src_len)) {
 		ret = -EINVAL;
 		goto err_free_m;
 	}
 
-	if (req->dst_len < mpi_get_size(pkey->n)) {
-		req->dst_len = mpi_get_size(pkey->n);
+	if (dst_len < mpi_get_size(pkey->n)) {
+		req->out_len = mpi_get_size(pkey->n);
 		ret = -EOVERFLOW;
 		goto err_free_m;
 	}
 
-	c = mpi_read_raw_data(req->src, req->src_len);
-	if (!c) {
-		ret = -ENOMEM;
-		goto err_free_m;
+	ret = -ENOMEM;
+	if (sg_is_last(req->src)) {
+		c = mpi_read_raw_data(sg_virt(req->src), src_len);
+	} else {
+		void *ptr = kmalloc(src_len, GFP_KERNEL);
+
+		if (!ptr)
+			goto err_free_m;
+
+		scatterwalk_map_and_copy(ptr, req->src, 0, src_len, 0);
+		c = mpi_read_raw_data(ptr, src_len);
+		kfree(ptr);
 	}
+	if (!c)
+		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, &req->dst_len, &sign);
+	if (sg_is_last(req->dst)) {
+		ret = mpi_read_buffer(m, sg_virt(req->dst), dst_len,
+				      &req->out_len, &sign);
+	} else {
+		void *ptr = kmalloc(dst_len, GFP_KERNEL);
+
+		if (!ptr)
+			goto err_free_c;
+
+		ret = mpi_read_buffer(m, ptr, dst_len, &req->out_len, &sign);
+		scatterwalk_map_and_copy(ptr, req->dst, 0, dst_len, 1);
+		kfree(ptr);
+	}
 	if (ret)
 		goto err_free_c;
 
@@ -176,34 +223,58 @@ static int rsa_sign(struct akcipher_request *req)
 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
 	const struct rsa_key *pkey = rsa_get_key(tfm);
 	MPI m, s = mpi_alloc(0);
+	int src_len = sg_len(req->src), dst_len = sg_len(req->dst);
 	int ret = 0;
 	int sign;
 
 	if (!s)
 		return -ENOMEM;
 
-	if (unlikely(!pkey->n || !pkey->d)) {
+	if (unlikely(!pkey->n || !pkey->d || !src_len)) {
 		ret = -EINVAL;
 		goto err_free_s;
 	}
 
-	if (req->dst_len < mpi_get_size(pkey->n)) {
-		req->dst_len = mpi_get_size(pkey->n);
+	if (dst_len < mpi_get_size(pkey->n)) {
+		req->out_len = mpi_get_size(pkey->n);
 		ret = -EOVERFLOW;
 		goto err_free_s;
 	}
 
-	m = mpi_read_raw_data(req->src, req->src_len);
-	if (!m) {
-		ret = -ENOMEM;
-		goto err_free_s;
+	ret = -ENOMEM;
+	if (sg_is_last(req->src)) {
+		m = mpi_read_raw_data(sg_virt(req->src), src_len);
+	} else {
+		void *ptr = kmalloc(src_len, GFP_KERNEL);
+
+		if (!ptr)
+			goto err_free_s;
+
+		scatterwalk_map_and_copy(ptr, req->src, 0, src_len, 0);
+		m = mpi_read_raw_data(ptr, src_len);
+		kfree(ptr);
+
 	}
+	if (!m)
+		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, &req->dst_len, &sign);
+	if (sg_is_last(req->dst)) {
+		ret = mpi_read_buffer(s, sg_virt(req->dst), dst_len,
+				      &req->out_len, &sign);
+	} else {
+		void *ptr = kmalloc(dst_len, GFP_KERNEL);
+
+		if (!ptr)
+			goto err_free_m;
+
+		ret = mpi_read_buffer(s, ptr, dst_len, &req->out_len, &sign);
+		scatterwalk_map_and_copy(ptr, req->dst, 0, dst_len, 1);
+		kfree(ptr);
+	}
 	if (ret)
 		goto err_free_m;
 
@@ -224,24 +295,37 @@ static int rsa_verify(struct akcipher_request *req)
 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
 	const struct rsa_key *pkey = rsa_get_key(tfm);
 	MPI s, m = mpi_alloc(0);
+	int src_len = sg_len(req->src), dst_len = sg_len(req->dst);
 	int ret = 0;
 	int sign;
 
 	if (!m)
 		return -ENOMEM;
 
-	if (unlikely(!pkey->n || !pkey->e)) {
+	if (unlikely(!pkey->n || !pkey->e || !src_len)) {
 		ret = -EINVAL;
 		goto err_free_m;
 	}
 
-	if (req->dst_len < mpi_get_size(pkey->n)) {
-		req->dst_len = mpi_get_size(pkey->n);
+	if (dst_len < mpi_get_size(pkey->n)) {
+		req->out_len = mpi_get_size(pkey->n);
 		ret = -EOVERFLOW;
 		goto err_free_m;
 	}
 
-	s = mpi_read_raw_data(req->src, req->src_len);
+	ret = -ENOMEM;
+	if (sg_is_last(req->src)) {
+		s = mpi_read_raw_data(sg_virt(req->src), src_len);
+	} else {
+		void *ptr = kmalloc(src_len, GFP_KERNEL);
+
+		if (!ptr)
+			goto err_free_m;
+
+		scatterwalk_map_and_copy(ptr, req->src, 0, src_len, 0);
+		s = mpi_read_raw_data(ptr, src_len);
+		kfree(ptr);
+	}
 	if (!s) {
 		ret = -ENOMEM;
 		goto err_free_m;
@@ -251,7 +335,19 @@ static int rsa_verify(struct akcipher_request *req)
 	if (ret)
 		goto err_free_s;
 
-	ret = mpi_read_buffer(m, req->dst, req->dst_len, &req->dst_len, &sign);
+	if (sg_is_last(req->dst)) {
+		ret = mpi_read_buffer(m, sg_virt(req->dst), dst_len,
+				      &req->out_len, &sign);
+	} else {
+		void *ptr = kmalloc(dst_len, GFP_KERNEL);
+
+		if (!ptr)
+			goto err_free_s;
+
+		ret = mpi_read_buffer(m, ptr, dst_len, &req->out_len, &sign);
+		scatterwalk_map_and_copy(ptr, req->dst, 0, dst_len, 1);
+		kfree(ptr);
+	}
 	if (ret)
 		goto err_free_s;
 
@@ -282,13 +378,30 @@ static int rsa_check_key_length(unsigned int len)
 	return -EINVAL;
 }
 
-static int rsa_setkey(struct crypto_akcipher *tfm, const void *key,
-		      unsigned int keylen)
+static int rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
+			   unsigned int keylen)
+{
+	struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
+	int ret;
+
+	ret = rsa_parse_pub_key(pkey, key, keylen);
+	if (ret)
+		return ret;
+
+	if (rsa_check_key_length(mpi_get_size(pkey->n) << 3)) {
+		rsa_free_key(pkey);
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
+static int rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,
+			    unsigned int keylen)
 {
 	struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
 	int ret;
 
-	ret = rsa_parse_key(pkey, key, keylen);
+	ret = rsa_parse_priv_key(pkey, key, keylen);
 	if (ret)
 		return ret;
 
@@ -299,6 +412,13 @@ static int rsa_setkey(struct crypto_akcipher *tfm, const void *key,
 	return ret;
 }
 
+static int rsa_get_len(struct crypto_akcipher *tfm)
+{
+	struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
+
+	return pkey->n ? mpi_get_size(pkey->n) : -EINVAL;
+}
+
 static void rsa_exit_tfm(struct crypto_akcipher *tfm)
 {
 	struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
@@ -311,7 +431,9 @@ static struct akcipher_alg rsa = {
 	.decrypt = rsa_dec,
 	.sign = rsa_sign,
 	.verify = rsa_verify,
-	.setkey = rsa_setkey,
+	.set_priv_key = rsa_set_priv_key,
+	.set_pub_key = rsa_set_pub_key,
+	.get_len = rsa_get_len,
 	.exit = rsa_exit_tfm,
 	.base = {
 		.cra_name = "rsa",
diff --git a/crypto/rsa_helper.c b/crypto/rsa_helper.c
index 8d96ce9..d226f48 100644
--- a/crypto/rsa_helper.c
+++ b/crypto/rsa_helper.c
@@ -15,7 +15,8 @@
 #include <linux/err.h>
 #include <linux/fips.h>
 #include <crypto/internal/rsa.h>
-#include "rsakey-asn1.h"
+#include "rsapubkey-asn1.h"
+#include "rsaprivkey-asn1.h"
 
 int rsa_get_n(void *context, size_t hdrlen, unsigned char tag,
 	      const void *value, size_t vlen)
@@ -94,8 +95,8 @@ void rsa_free_key(struct rsa_key *key)
 EXPORT_SYMBOL_GPL(rsa_free_key);
 
 /**
- * rsa_parse_key() - extracts an rsa key from BER encoded buffer
- *		     and stores it in the provided struct rsa_key
+ * rsa_parse_pub_key() - extracts an rsa public key from BER encoded buffer
+ *			 and stores it in the provided struct rsa_key
  *
  * @rsa_key:	struct rsa_key key representation
  * @key:	key in BER format
@@ -103,13 +104,13 @@ EXPORT_SYMBOL_GPL(rsa_free_key);
  *
  * Return:	0 on success or error code in case of error
  */
-int rsa_parse_key(struct rsa_key *rsa_key, const void *key,
-		  unsigned int key_len)
+int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
+		      unsigned int key_len)
 {
 	int ret;
 
 	free_mpis(rsa_key);
-	ret = asn1_ber_decoder(&rsakey_decoder, rsa_key, key, key_len);
+	ret = asn1_ber_decoder(&rsapubkey_decoder, rsa_key, key, key_len);
 	if (ret < 0)
 		goto error;
 
@@ -118,4 +119,31 @@ error:
 	free_mpis(rsa_key);
 	return ret;
 }
-EXPORT_SYMBOL_GPL(rsa_parse_key);
+EXPORT_SYMBOL_GPL(rsa_parse_pub_key);
+
+/**
+ * rsa_parse_pub_key() - extracts an rsa private key from BER encoded buffer
+ *			 and stores it in the provided struct rsa_key
+ *
+ * @rsa_key:	struct rsa_key key representation
+ * @key:	key in BER format
+ * @key_len:	length of key
+ *
+ * Return:	0 on success or error code in case of error
+ */
+int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,
+		       unsigned int key_len)
+{
+	int ret;
+
+	free_mpis(rsa_key);
+	ret = asn1_ber_decoder(&rsaprivkey_decoder, rsa_key, key, key_len);
+	if (ret < 0)
+		goto error;
+
+	return 0;
+error:
+	free_mpis(rsa_key);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(rsa_parse_priv_key);
diff --git a/crypto/rsakey.asn1 b/crypto/rsakey.asn1
deleted file mode 100644
index 3c7b5df..0000000
--- a/crypto/rsakey.asn1
+++ /dev/null
@@ -1,5 +0,0 @@
-RsaKey ::= SEQUENCE {
-	n INTEGER ({ rsa_get_n }),
-	e INTEGER ({ rsa_get_e }),
-	d INTEGER ({ rsa_get_d })
-}
diff --git a/crypto/rsaprivkey.asn1 b/crypto/rsaprivkey.asn1
new file mode 100644
index 0000000..731aea5
--- /dev/null
+++ b/crypto/rsaprivkey.asn1
@@ -0,0 +1,11 @@
+RsaPrivKey ::= SEQUENCE {
+	version		INTEGER,
+	n		INTEGER ({ rsa_get_n }),
+	e		INTEGER ({ rsa_get_e }),
+	d		INTEGER ({ rsa_get_d }),
+	prime1		INTEGER,
+	prime2		INTEGER,
+	exponent1	INTEGER,
+	exponent2	INTEGER,
+	coefficient	INTEGER
+}
diff --git a/crypto/rsapubkey.asn1 b/crypto/rsapubkey.asn1
new file mode 100644
index 0000000..725498e
--- /dev/null
+++ b/crypto/rsapubkey.asn1
@@ -0,0 +1,4 @@
+RsaPubKey ::= SEQUENCE {
+	n INTEGER ({ rsa_get_n }),
+	e INTEGER ({ rsa_get_e })
+}
diff --git a/include/crypto/internal/rsa.h b/include/crypto/internal/rsa.h
index a8c8636..f997e2d 100644
--- a/include/crypto/internal/rsa.h
+++ b/include/crypto/internal/rsa.h
@@ -20,8 +20,11 @@ struct rsa_key {
 	MPI d;
 };
 
-int rsa_parse_key(struct rsa_key *rsa_key, const void *key,
-		  unsigned int key_len);
+int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
+		      unsigned int key_len);
+
+int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,
+		       unsigned int key_len);
 
 void rsa_free_key(struct rsa_key *rsa_key);
 #endif

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

* [PATCH 7/8] crypto: qat - update accoring to akcipher API changes
  2015-09-09 16:14 [PATCH 0/8] crypto: Updates to akcipher API Tadeusz Struk
                   ` (5 preceding siblings ...)
  2015-09-09 16:15 ` [PATCH 6/8] crypto: rsa - update accoring to akcipher API changes Tadeusz Struk
@ 2015-09-09 16:15 ` Tadeusz Struk
  2015-09-09 16:15 ` [PATCH 8/8] crypto: testmgr - update test mgr according to " Tadeusz Struk
  7 siblings, 0 replies; 32+ messages in thread
From: Tadeusz Struk @ 2015-09-09 16:15 UTC (permalink / raw)
  To: herbert; +Cc: linux-crypto, qat-linux, tadeusz.struk

QAT updates to reflect akcipher API changes.

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
 drivers/crypto/qat/qat_common/Makefile            |   12 +
 drivers/crypto/qat/qat_common/qat_asym_algs.c     |  225 +++++++++++++++------
 drivers/crypto/qat/qat_common/qat_rsakey.asn1     |    5 
 drivers/crypto/qat/qat_common/qat_rsaprivkey.asn1 |   11 +
 drivers/crypto/qat/qat_common/qat_rsapubkey.asn1  |    4 
 5 files changed, 189 insertions(+), 68 deletions(-)
 delete mode 100644 drivers/crypto/qat/qat_common/qat_rsakey.asn1
 create mode 100644 drivers/crypto/qat/qat_common/qat_rsaprivkey.asn1
 create mode 100644 drivers/crypto/qat/qat_common/qat_rsapubkey.asn1

diff --git a/drivers/crypto/qat/qat_common/Makefile b/drivers/crypto/qat/qat_common/Makefile
index ba5abdb..9e9e196 100644
--- a/drivers/crypto/qat/qat_common/Makefile
+++ b/drivers/crypto/qat/qat_common/Makefile
@@ -1,5 +1,10 @@
-$(obj)/qat_rsakey-asn1.o: $(obj)/qat_rsakey-asn1.c $(obj)/qat_rsakey-asn1.h
-clean-files += qat_rsakey-asn1.c qat_rsakey-asn1.h
+$(obj)/qat_rsapubkey-asn1.o: $(obj)/qat_rsapubkey-asn1.c \
+			     $(obj)/qat_rsapubkey-asn1.h
+$(obj)/qat_rsaprivkey-asn1.o: $(obj)/qat_rsaprivkey-asn1.c \
+			      $(obj)/qat_rsaprivkey-asn1.h
+
+clean-files += qat_rsapubkey-asn1.c qat_rsapubkey-asn1.h
+clean-files += qat_rsaprivkey-asn1.c qat_rsapvivkey-asn1.h
 
 obj-$(CONFIG_CRYPTO_DEV_QAT) += intel_qat.o
 intel_qat-objs := adf_cfg.o \
@@ -13,6 +18,9 @@ intel_qat-objs := adf_cfg.o \
 	adf_hw_arbiter.o \
 	qat_crypto.o \
 	qat_algs.o \
+	qat_rsapubkey-asn1.o \
+	qat_rsaprivkey-asn1.o \
+	qat_asym_algs.o \
 	qat_uclo.o \
 	qat_hal.o
 
diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c b/drivers/crypto/qat/qat_common/qat_asym_algs.c
index 7de765d..d0c6e9c 100644
--- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
+++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
@@ -51,7 +51,9 @@
 #include <crypto/akcipher.h>
 #include <linux/dma-mapping.h>
 #include <linux/fips.h>
-#include "qat_rsakey-asn1.h"
+#include <crypto/scatterwalk.h>
+#include "qat_rsapubkey-asn1.h"
+#include "qat_rsaprivkey-asn1.h"
 #include "icp_qat_fw_pke.h"
 #include "adf_accel_devices.h"
 #include "adf_transport.h"
@@ -106,6 +108,7 @@ struct qat_rsa_request {
 	dma_addr_t phy_in;
 	dma_addr_t phy_out;
 	char *src_align;
+	char *dst_align;
 	struct icp_qat_fw_pke_request req;
 	struct qat_rsa_ctx *ctx;
 	int err;
@@ -118,7 +121,6 @@ static void qat_rsa_cb(struct icp_qat_fw_pke_resp *resp)
 	struct device *dev = &GET_DEV(req->ctx->inst->accel_dev);
 	int err = ICP_QAT_FW_PKE_RESP_PKE_STAT_GET(
 				resp->pke_resp_hdr.comn_resp_flags);
-	char *ptr = areq->dst;
 
 	err = (err == ICP_QAT_FW_COMN_STATUS_FLAG_OK) ? 0 : -EINVAL;
 
@@ -129,24 +131,44 @@ static void qat_rsa_cb(struct icp_qat_fw_pke_resp *resp)
 		dma_unmap_single(dev, req->in.enc.m, req->ctx->key_sz,
 				 DMA_TO_DEVICE);
 
-	dma_unmap_single(dev, req->out.enc.c, req->ctx->key_sz,
-			 DMA_FROM_DEVICE);
+	areq->out_len = req->ctx->key_sz;
+	if (req->dst_align) {
+		char *ptr = req->dst_align;
+
+		while (!(*ptr) && areq->out_len) {
+			areq->out_len--;
+			ptr++;
+		}
+
+		if (areq->out_len != req->ctx->key_sz)
+			memmove(req->dst_align, ptr, areq->out_len);
+
+		scatterwalk_map_and_copy(req->dst_align, areq->dst, 0,
+					 areq->out_len, 1);
+
+		dma_free_coherent(dev, req->ctx->key_sz, req->dst_align,
+				  req->out.enc.c);
+	} else {
+		char *ptr = sg_virt(areq->dst);
+
+		while (!(*ptr) && areq->out_len) {
+			areq->out_len--;
+			ptr++;
+		}
+
+		if (sg_virt(areq->dst) != ptr && areq->out_len)
+			memmove(sg_virt(areq->dst), ptr, areq->out_len);
+
+		dma_unmap_single(dev, req->out.enc.c, req->ctx->key_sz,
+				 DMA_FROM_DEVICE);
+	}
+
 	dma_unmap_single(dev, req->phy_in, sizeof(struct qat_rsa_input_params),
 			 DMA_TO_DEVICE);
 	dma_unmap_single(dev, req->phy_out,
 			 sizeof(struct qat_rsa_output_params),
 			 DMA_TO_DEVICE);
 
-	areq->dst_len = req->ctx->key_sz;
-	/* Need to set the corect length of the output */
-	while (!(*ptr) && areq->dst_len) {
-		areq->dst_len--;
-		ptr++;
-	}
-
-	if (areq->dst_len != req->ctx->key_sz)
-		memmove(areq->dst, ptr, areq->dst_len);
-
 	akcipher_request_complete(areq, err);
 }
 
@@ -224,13 +246,14 @@ static int qat_rsa_enc(struct akcipher_request *req)
 	struct qat_rsa_request *qat_req =
 			PTR_ALIGN(akcipher_request_ctx(req), 64);
 	struct icp_qat_fw_pke_request *msg = &qat_req->req;
+	int src_len = sg_len(req->src), dst_len = sg_len(req->dst);
 	int ret, ctr = 0;
 
 	if (unlikely(!ctx->n || !ctx->e))
 		return -EINVAL;
 
-	if (req->dst_len < ctx->key_sz) {
-		req->dst_len = ctx->key_sz;
+	if (dst_len < ctx->key_sz) {
+		req->out_len = ctx->key_sz;
 		return -EOVERFLOW;
 	}
 	memset(msg, '\0', sizeof(*msg));
@@ -255,9 +278,17 @@ static int qat_rsa_enc(struct akcipher_request *req)
 	 * same as modulo n so in case it is different we need to allocate a
 	 * new buf and copy src data.
 	 * In other case we just need to map the user provided buffer.
+	 * Also need to make sure that it is in contiguous buffer.
 	 */
-	if (req->src_len < ctx->key_sz) {
-		int shift = ctx->key_sz - req->src_len;
+	if (sg_is_last(req->src) && src_len == ctx->key_sz) {
+		qat_req->src_align = NULL;
+		qat_req->in.enc.m = dma_map_single(dev, sg_virt(req->src),
+						   src_len, DMA_TO_DEVICE);
+		if (unlikely(dma_mapping_error(dev, qat_req->in.enc.m)))
+			return ret;
+
+	} else {
+		int shift = ctx->key_sz - src_len;
 
 		qat_req->src_align = dma_zalloc_coherent(dev, ctx->key_sz,
 							 &qat_req->in.enc.m,
@@ -265,29 +296,38 @@ static int qat_rsa_enc(struct akcipher_request *req)
 		if (unlikely(!qat_req->src_align))
 			return ret;
 
-		memcpy(qat_req->src_align + shift, req->src, req->src_len);
+		scatterwalk_map_and_copy(qat_req->src_align + shift, req->src,
+					 0, src_len, 0);
+	}
+	if (sg_is_last(req->dst) && dst_len == ctx->key_sz) {
+		qat_req->dst_align = NULL;
+		qat_req->out.enc.c = dma_map_single(dev, sg_virt(req->dst),
+						     dst_len, DMA_FROM_DEVICE);
+
+		if (unlikely(dma_mapping_error(dev, qat_req->out.enc.c)))
+			goto unmap_src;
+
 	} else {
-		qat_req->src_align = NULL;
-		qat_req->in.enc.m = dma_map_single(dev, req->src, req->src_len,
-					   DMA_TO_DEVICE);
+		qat_req->dst_align = dma_zalloc_coherent(dev, ctx->key_sz,
+							 &qat_req->out.enc.c,
+							 GFP_KERNEL);
+		if (unlikely(!qat_req->dst_align))
+			goto unmap_src;
+
 	}
 	qat_req->in.in_tab[3] = 0;
-	qat_req->out.enc.c = dma_map_single(dev, req->dst, req->dst_len,
-					    DMA_FROM_DEVICE);
 	qat_req->out.out_tab[1] = 0;
 	qat_req->phy_in = dma_map_single(dev, &qat_req->in.enc.m,
 					 sizeof(struct qat_rsa_input_params),
 					 DMA_TO_DEVICE);
+	if (unlikely(dma_mapping_error(dev, qat_req->phy_in)))
+		goto unmap_dst;
+
 	qat_req->phy_out = dma_map_single(dev, &qat_req->out.enc.c,
 					  sizeof(struct qat_rsa_output_params),
-					    DMA_TO_DEVICE);
-
-	if (unlikely((!qat_req->src_align &&
-		      dma_mapping_error(dev, qat_req->in.enc.m)) ||
-		     dma_mapping_error(dev, qat_req->out.enc.c) ||
-		     dma_mapping_error(dev, qat_req->phy_in) ||
-		     dma_mapping_error(dev, qat_req->phy_out)))
-		goto unmap;
+					  DMA_TO_DEVICE);
+	if (unlikely(dma_mapping_error(dev, qat_req->phy_out)))
+		goto unmap_in_params;
 
 	msg->pke_mid.src_data_addr = qat_req->phy_in;
 	msg->pke_mid.dest_data_addr = qat_req->phy_out;
@@ -300,7 +340,7 @@ static int qat_rsa_enc(struct akcipher_request *req)
 
 	if (!ret)
 		return -EINPROGRESS;
-unmap:
+unmap_src:
 	if (qat_req->src_align)
 		dma_free_coherent(dev, ctx->key_sz, qat_req->src_align,
 				  qat_req->in.enc.m);
@@ -308,9 +348,15 @@ unmap:
 		if (!dma_mapping_error(dev, qat_req->in.enc.m))
 			dma_unmap_single(dev, qat_req->in.enc.m, ctx->key_sz,
 					 DMA_TO_DEVICE);
-	if (!dma_mapping_error(dev, qat_req->out.enc.c))
-		dma_unmap_single(dev, qat_req->out.enc.c, ctx->key_sz,
-				 DMA_FROM_DEVICE);
+unmap_dst:
+	if (qat_req->dst_align)
+		dma_free_coherent(dev, ctx->key_sz, qat_req->dst_align,
+				  qat_req->out.enc.c);
+	else
+		if (!dma_mapping_error(dev, qat_req->out.enc.c))
+			dma_unmap_single(dev, qat_req->out.enc.c, ctx->key_sz,
+					 DMA_FROM_DEVICE);
+unmap_in_params:
 	if (!dma_mapping_error(dev, qat_req->phy_in))
 		dma_unmap_single(dev, qat_req->phy_in,
 				 sizeof(struct qat_rsa_input_params),
@@ -331,13 +377,14 @@ static int qat_rsa_dec(struct akcipher_request *req)
 	struct qat_rsa_request *qat_req =
 			PTR_ALIGN(akcipher_request_ctx(req), 64);
 	struct icp_qat_fw_pke_request *msg = &qat_req->req;
+	int src_len = sg_len(req->src), dst_len = sg_len(req->dst);
 	int ret, ctr = 0;
 
 	if (unlikely(!ctx->n || !ctx->d))
 		return -EINVAL;
 
-	if (req->dst_len < ctx->key_sz) {
-		req->dst_len = ctx->key_sz;
+	if (dst_len < ctx->key_sz) {
+		req->out_len = ctx->key_sz;
 		return -EOVERFLOW;
 	}
 	memset(msg, '\0', sizeof(*msg));
@@ -362,9 +409,17 @@ static int qat_rsa_dec(struct akcipher_request *req)
 	 * same as modulo n so in case it is different we need to allocate a
 	 * new buf and copy src data.
 	 * In other case we just need to map the user provided buffer.
+	 * Also need to make sure that it is in contiguous buffer.
 	 */
-	if (req->src_len < ctx->key_sz) {
-		int shift = ctx->key_sz - req->src_len;
+	if (sg_is_last(req->src) && src_len == ctx->key_sz) {
+		qat_req->src_align = NULL;
+		qat_req->in.dec.c = dma_map_single(dev, sg_virt(req->src),
+						   dst_len, DMA_TO_DEVICE);
+		if (unlikely(dma_mapping_error(dev, qat_req->in.dec.c)))
+			return ret;
+
+	} else {
+		int shift = ctx->key_sz - src_len;
 
 		qat_req->src_align = dma_zalloc_coherent(dev, ctx->key_sz,
 							 &qat_req->in.dec.c,
@@ -372,29 +427,39 @@ static int qat_rsa_dec(struct akcipher_request *req)
 		if (unlikely(!qat_req->src_align))
 			return ret;
 
-		memcpy(qat_req->src_align + shift, req->src, req->src_len);
+		scatterwalk_map_and_copy(qat_req->src_align + shift, req->src,
+					 0, src_len, 0);
+	}
+	if (sg_is_last(req->dst) && dst_len == ctx->key_sz) {
+		qat_req->dst_align = NULL;
+		qat_req->out.dec.m = dma_map_single(dev, sg_virt(req->dst),
+						    dst_len, DMA_FROM_DEVICE);
+
+		if (unlikely(dma_mapping_error(dev, qat_req->out.dec.m)))
+			goto unmap_src;
+
 	} else {
-		qat_req->src_align = NULL;
-		qat_req->in.dec.c = dma_map_single(dev, req->src, req->src_len,
-						   DMA_TO_DEVICE);
+		qat_req->dst_align = dma_zalloc_coherent(dev, ctx->key_sz,
+							 &qat_req->out.dec.m,
+							 GFP_KERNEL);
+		if (unlikely(!qat_req->dst_align))
+			goto unmap_src;
+
 	}
+
 	qat_req->in.in_tab[3] = 0;
-	qat_req->out.dec.m = dma_map_single(dev, req->dst, req->dst_len,
-					    DMA_FROM_DEVICE);
 	qat_req->out.out_tab[1] = 0;
 	qat_req->phy_in = dma_map_single(dev, &qat_req->in.dec.c,
 					 sizeof(struct qat_rsa_input_params),
 					 DMA_TO_DEVICE);
+	if (unlikely(dma_mapping_error(dev, qat_req->phy_in)))
+		goto unmap_dst;
+
 	qat_req->phy_out = dma_map_single(dev, &qat_req->out.dec.m,
 					  sizeof(struct qat_rsa_output_params),
-					    DMA_TO_DEVICE);
-
-	if (unlikely((!qat_req->src_align &&
-		      dma_mapping_error(dev, qat_req->in.dec.c)) ||
-		     dma_mapping_error(dev, qat_req->out.dec.m) ||
-		     dma_mapping_error(dev, qat_req->phy_in) ||
-		     dma_mapping_error(dev, qat_req->phy_out)))
-		goto unmap;
+					  DMA_TO_DEVICE);
+	if (unlikely(dma_mapping_error(dev, qat_req->phy_out)))
+		goto unmap_in_params;
 
 	msg->pke_mid.src_data_addr = qat_req->phy_in;
 	msg->pke_mid.dest_data_addr = qat_req->phy_out;
@@ -407,7 +472,7 @@ static int qat_rsa_dec(struct akcipher_request *req)
 
 	if (!ret)
 		return -EINPROGRESS;
-unmap:
+unmap_src:
 	if (qat_req->src_align)
 		dma_free_coherent(dev, ctx->key_sz, qat_req->src_align,
 				  qat_req->in.dec.c);
@@ -415,9 +480,15 @@ unmap:
 		if (!dma_mapping_error(dev, qat_req->in.dec.c))
 			dma_unmap_single(dev, qat_req->in.dec.c, ctx->key_sz,
 					 DMA_TO_DEVICE);
-	if (!dma_mapping_error(dev, qat_req->out.dec.m))
-		dma_unmap_single(dev, qat_req->out.dec.m, ctx->key_sz,
-				 DMA_FROM_DEVICE);
+unmap_dst:
+	if (qat_req->dst_align)
+		dma_free_coherent(dev, ctx->key_sz, qat_req->dst_align,
+				  qat_req->out.dec.m);
+	else
+		if (!dma_mapping_error(dev, qat_req->out.dec.m))
+			dma_unmap_single(dev, qat_req->out.dec.m, ctx->key_sz,
+					 DMA_FROM_DEVICE);
+unmap_in_params:
 	if (!dma_mapping_error(dev, qat_req->phy_in))
 		dma_unmap_single(dev, qat_req->phy_in,
 				 sizeof(struct qat_rsa_input_params),
@@ -531,7 +602,7 @@ err:
 }
 
 static int qat_rsa_setkey(struct crypto_akcipher *tfm, const void *key,
-			  unsigned int keylen)
+			  unsigned int keylen, bool private)
 {
 	struct qat_rsa_ctx *ctx = akcipher_tfm_ctx(tfm);
 	struct device *dev = &GET_DEV(ctx->inst->accel_dev);
@@ -550,7 +621,13 @@ static int qat_rsa_setkey(struct crypto_akcipher *tfm, const void *key,
 	ctx->n = NULL;
 	ctx->e = NULL;
 	ctx->d = NULL;
-	ret = asn1_ber_decoder(&qat_rsakey_decoder, ctx, key, keylen);
+
+	if (private)
+		ret = asn1_ber_decoder(&qat_rsaprivkey_decoder, ctx, key,
+				       keylen);
+	else
+		ret = asn1_ber_decoder(&qat_rsapubkey_decoder, ctx, key,
+				       keylen);
 	if (ret < 0)
 		goto free;
 
@@ -559,6 +636,11 @@ static int qat_rsa_setkey(struct crypto_akcipher *tfm, const void *key,
 		ret = -EINVAL;
 		goto free;
 	}
+	if (private && !ctx->d) {
+		/* invalid private key provided */
+		ret = -EINVAL;
+		goto free;
+	}
 
 	return 0;
 free:
@@ -579,6 +661,25 @@ free:
 	return ret;
 }
 
+static int qat_rsa_setpubkey(struct crypto_akcipher *tfm, const void *key,
+			     unsigned int keylen)
+{
+	return qat_rsa_setkey(tfm, key, keylen, false);
+}
+
+static int qat_rsa_setprivkey(struct crypto_akcipher *tfm, const void *key,
+			      unsigned int keylen)
+{
+	return qat_rsa_setkey(tfm, key, keylen, true);
+}
+
+static int qat_rsa_get_len(struct crypto_akcipher *tfm)
+{
+	struct qat_rsa_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+	return (ctx->n) ? ctx->key_sz : -EINVAL;
+}
+
 static int qat_rsa_init_tfm(struct crypto_akcipher *tfm)
 {
 	struct qat_rsa_ctx *ctx = akcipher_tfm_ctx(tfm);
@@ -617,7 +718,9 @@ static struct akcipher_alg rsa = {
 	.decrypt = qat_rsa_dec,
 	.sign = qat_rsa_dec,
 	.verify = qat_rsa_enc,
-	.setkey = qat_rsa_setkey,
+	.set_pub_key = qat_rsa_setpubkey,
+	.set_priv_key = qat_rsa_setprivkey,
+	.get_len = qat_rsa_get_len,
 	.init = qat_rsa_init_tfm,
 	.exit = qat_rsa_exit_tfm,
 	.reqsize = sizeof(struct qat_rsa_request) + 64,
diff --git a/drivers/crypto/qat/qat_common/qat_rsakey.asn1 b/drivers/crypto/qat/qat_common/qat_rsakey.asn1
deleted file mode 100644
index 97b0e02..0000000
--- a/drivers/crypto/qat/qat_common/qat_rsakey.asn1
+++ /dev/null
@@ -1,5 +0,0 @@
-RsaKey ::= SEQUENCE {
-	n INTEGER ({ qat_rsa_get_n }),
-	e INTEGER ({ qat_rsa_get_e }),
-	d INTEGER ({ qat_rsa_get_d })
-}
diff --git a/drivers/crypto/qat/qat_common/qat_rsaprivkey.asn1 b/drivers/crypto/qat/qat_common/qat_rsaprivkey.asn1
new file mode 100644
index 0000000..f0066ad
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/qat_rsaprivkey.asn1
@@ -0,0 +1,11 @@
+RsaPrivKey ::= SEQUENCE {
+	version		INTEGER,
+	n		INTEGER ({ qat_rsa_get_n }),
+	e		INTEGER ({ qat_rsa_get_e }),
+	d		INTEGER ({ qat_rsa_get_d }),
+	prime1		INTEGER,
+	prime2		INTEGER,
+	exponent1	INTEGER,
+	exponent2	INTEGER,
+	coefficient	INTEGER
+}
diff --git a/drivers/crypto/qat/qat_common/qat_rsapubkey.asn1 b/drivers/crypto/qat/qat_common/qat_rsapubkey.asn1
new file mode 100644
index 0000000..bd667b3
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/qat_rsapubkey.asn1
@@ -0,0 +1,4 @@
+RsaPubKey ::= SEQUENCE {
+	n INTEGER ({ qat_rsa_get_n }),
+	e INTEGER ({ qat_rsa_get_e })
+}

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

* [PATCH 8/8] crypto: testmgr - update test mgr according to API changes
  2015-09-09 16:14 [PATCH 0/8] crypto: Updates to akcipher API Tadeusz Struk
                   ` (6 preceding siblings ...)
  2015-09-09 16:15 ` [PATCH 7/8] crypto: qat " Tadeusz Struk
@ 2015-09-09 16:15 ` Tadeusz Struk
  7 siblings, 0 replies; 32+ messages in thread
From: Tadeusz Struk @ 2015-09-09 16:15 UTC (permalink / raw)
  To: herbert; +Cc: linux-crypto, qat-linux, tadeusz.struk

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
 crypto/testmgr.c |   44 +++++++++++++++++++++-----------------------
 crypto/testmgr.h |   36 +++++++++++++++++++++++++++---------
 2 files changed, 48 insertions(+), 32 deletions(-)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 2f2b66e..f268707 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -1835,7 +1835,6 @@ static int alg_test_drbg(const struct alg_test_desc *desc, const char *driver,
 
 }
 
-#if 0
 static int do_test_rsa(struct crypto_akcipher *tfm,
 		       struct akcipher_testvec *vecs)
 {
@@ -1845,34 +1844,33 @@ static int do_test_rsa(struct crypto_akcipher *tfm,
 	struct tcrypt_result result;
 	unsigned int out_len_max, out_len = 0;
 	int err = -ENOMEM;
+	struct scatterlist src, dst, src_tab[2];
 
 	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;
 
-	akcipher_request_set_crypt(req, vecs->m, outbuf_enc, vecs->m_size,
-				   out_len);
-	/* expect this to fail, and update the required buf len */
-	crypto_akcipher_encrypt(req);
-	out_len = req->dst_len;
-	if (!out_len) {
-		err = -EINVAL;
+	if (vecs->public_key_vec)
+		err = crypto_akcipher_set_pub_key(tfm, vecs->key,
+						  vecs->key_len);
+	else
+		err = crypto_akcipher_set_priv_key(tfm, vecs->key,
+						   vecs->key_len);
+	if (err)
 		goto free_req;
-	}
 
-	out_len_max = out_len;
-	err = -ENOMEM;
+	out_len_max = crypto_akcipher_get_len(tfm);
 	outbuf_enc = kzalloc(out_len_max, GFP_KERNEL);
 	if (!outbuf_enc)
 		goto free_req;
 
-	akcipher_request_set_crypt(req, vecs->m, outbuf_enc, vecs->m_size,
-				   out_len);
+	sg_init_table(src_tab, 2);
+	sg_set_buf(&src_tab[0], vecs->m, 8);
+	sg_set_buf(&src_tab[1], vecs->m + 8, vecs->m_size - 8);
+	sg_init_one(&dst, outbuf_enc, out_len_max);
+	akcipher_request_set_crypt(req, src_tab, &dst);
 	akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
 				      tcrypt_complete, &result);
 
@@ -1882,13 +1880,13 @@ static int do_test_rsa(struct crypto_akcipher *tfm,
 		pr_err("alg: rsa: encrypt test failed. err %d\n", err);
 		goto free_all;
 	}
-	if (out_len != vecs->c_size) {
+	if (req->out_len != vecs->c_size) {
 		pr_err("alg: rsa: encrypt test failed. Invalid output len\n");
 		err = -EINVAL;
 		goto free_all;
 	}
 	/* verify that encrypted message is equal to expected */
-	if (memcmp(vecs->c, outbuf_enc, vecs->c_size)) {
+	if (memcmp(vecs->c, sg_virt(req->dst), vecs->c_size)) {
 		pr_err("alg: rsa: encrypt test failed. Invalid output\n");
 		err = -EINVAL;
 		goto free_all;
@@ -1903,9 +1901,10 @@ static int do_test_rsa(struct crypto_akcipher *tfm,
 		err = -ENOMEM;
 		goto free_all;
 	}
+	sg_init_one(&src, vecs->c, vecs->c_size);
+	sg_init_one(&dst, outbuf_dec, out_len_max);
 	init_completion(&result.completion);
-	akcipher_request_set_crypt(req, outbuf_enc, outbuf_dec, vecs->c_size,
-				   out_len);
+	akcipher_request_set_crypt(req, &src, &dst);
 
 	/* Run RSA decrypt - m = c^d mod n;*/
 	err = wait_async_op(&result, crypto_akcipher_decrypt(req));
@@ -1913,7 +1912,7 @@ static int do_test_rsa(struct crypto_akcipher *tfm,
 		pr_err("alg: rsa: decrypt test failed. err %d\n", err);
 		goto free_all;
 	}
-	out_len = req->dst_len;
+	out_len = req->out_len;
 	if (out_len != vecs->m_size) {
 		pr_err("alg: rsa: decrypt test failed. Invalid output len\n");
 		err = -EINVAL;
@@ -1976,7 +1975,6 @@ static int alg_test_akcipher(const struct alg_test_desc *desc,
 	crypto_free_akcipher(tfm);
 	return err;
 }
-#endif
 
 static int alg_test_null(const struct alg_test_desc *desc,
 			     const char *driver, u32 type, u32 mask)
@@ -3613,7 +3611,7 @@ static const struct alg_test_desc alg_test_descs[] = {
 		}
 	}, {
 		.alg = "rsa",
-		.test = alg_test_null,
+		.test = alg_test_akcipher,
 		.fips_allowed = 1,
 		.suite = {
 			.akcipher = {
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 64b8a80..e10582d 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -149,7 +149,8 @@ static struct akcipher_testvec rsa_tv_template[] = {
 	{
 #ifndef CONFIG_CRYPTO_FIPS
 	.key =
-	"\x30\x81\x88" /* sequence of 136 bytes */
+	"\x30\x81\x9A" /* sequence of 154 bytes */
+	"\x02\x01\x01" /* version - integer of 1 byte */
 	"\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"
@@ -161,19 +162,25 @@ static struct akcipher_testvec rsa_tv_template[] = {
 	"\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",
+	"\xDF\x8E\x8A\xE5\x9D\x73\x3D\x9F\x33\xB3\x01\x62\x4A\xFD\x1D\x51"
+	"\x02\x01\x00" /* prime1 - integer of 1 byte */
+	"\x02\x01\x00" /* prime2 - integer of 1 byte */
+	"\x02\x01\x00" /* exponent1 - integer of 1 byte */
+	"\x02\x01\x00" /* exponent2 - integer of 1 byte */
+	"\x02\x01\x00", /* coefficient - integer of 1 byte */
 	.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,
+	.key_len = 157,
 	.m_size = 8,
 	.c_size = 64,
 	}, {
 	.key =
-	"\x30\x82\x01\x0B" /* sequence of 267 bytes */
+	"\x30\x82\x01\x1D" /* sequence of 285 bytes */
+	"\x02\x01\x01" /* version - integer of 1 byte */
 	"\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"
@@ -194,8 +201,13 @@ static struct akcipher_testvec rsa_tv_template[] = {
 	"\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,
+	"\xC1"
+	"\x02\x01\x00" /* prime1 - integer of 1 byte */
+	"\x02\x01\x00" /* prime2 - integer of 1 byte */
+	"\x02\x01\x00" /* exponent1 - integer of 1 byte */
+	"\x02\x01\x00" /* exponent2 - integer of 1 byte */
+	"\x02\x01\x00", /* coefficient - integer of 1 byte */
+	.key_len = 289,
 	.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"
@@ -211,7 +223,8 @@ static struct akcipher_testvec rsa_tv_template[] = {
 	}, {
 #endif
 	.key =
-	"\x30\x82\x02\x0D" /* sequence of 525 bytes */
+	"\x30\x82\x02\x1F" /* sequence of 543 bytes */
+	"\x02\x01\x01" /* version - integer of 1 byte */
 	"\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"
@@ -246,8 +259,13 @@ static struct akcipher_testvec rsa_tv_template[] = {
 	"\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,
+	"\xA7\x1D\xD9\x1E\x06\xCD\xE8\xBA\x2C\x8C\x69\x32\xEA\xBE\x60\x71"
+	"\x02\x01\x00" /* prime1 - integer of 1 byte */
+	"\x02\x01\x00" /* prime2 - integer of 1 byte */
+	"\x02\x01\x00" /* exponent1 - integer of 1 byte */
+	"\x02\x01\x00" /* exponent2 - integer of 1 byte */
+	"\x02\x01\x00", /* coefficient - integer of 1 byte */
+	.key_len = 547,
 	.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"

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

* Re: [PATCH 4/8] crypto: akcipher - Changes to asymmetric key API
  2015-09-09 16:15 ` [PATCH 4/8] crypto: akcipher - Changes to asymmetric key API Tadeusz Struk
@ 2015-09-09 16:25   ` Stephan Mueller
  2015-09-09 16:29     ` Tadeusz Struk
  2015-09-18 11:35   ` Herbert Xu
  1 sibling, 1 reply; 32+ messages in thread
From: Stephan Mueller @ 2015-09-09 16:25 UTC (permalink / raw)
  To: Tadeusz Struk; +Cc: herbert, linux-crypto, qat-linux

Am Mittwoch, 9. September 2015, 09:15:20 schrieb Tadeusz Struk:

Hi Tadeusz,

>Setkey function has been split into set_priv_key and set_pub_key.
>Akcipher requests takes sgl for src and dst instead of void *.
>Users of the API need to be disabled so that the build works fine
>after this patch.
>They will be enabled in subsequent patches.
>
>Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
>---
> crypto/Makefile                        |    5 --
> crypto/testmgr.c                       |    4 +
> drivers/crypto/qat/qat_common/Makefile |    2 -
> include/crypto/akcipher.h              |   99
>++++++++++++++++++++++---------- 4 files changed, 71 insertions(+), 39
>deletions(-)
>
>diff --git a/crypto/Makefile b/crypto/Makefile
>index e2c5981..65e91da 100644
>--- a/crypto/Makefile
>+++ b/crypto/Makefile
>@@ -34,11 +34,6 @@ obj-$(CONFIG_CRYPTO_AKCIPHER2) += 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/testmgr.c b/crypto/testmgr.c
>index 35c2de1..2f2b66e 100644
>--- a/crypto/testmgr.c
>+++ b/crypto/testmgr.c
>@@ -1835,6 +1835,7 @@ static int alg_test_drbg(const struct alg_test_desc
>*desc, const char *driver,
>
> }
>
>+#if 0
> static int do_test_rsa(struct crypto_akcipher *tfm,
> 		       struct akcipher_testvec *vecs)
> {
>@@ -1975,6 +1976,7 @@ static int alg_test_akcipher(const struct alg_test_desc
>*desc, crypto_free_akcipher(tfm);
> 	return err;
> }
>+#endif

Just to check: is the ifdef 0 intentional?
>
> static int alg_test_null(const struct alg_test_desc *desc,
> 			     const char *driver, u32 type, u32 mask)
>@@ -3611,7 +3613,7 @@ static const struct alg_test_desc alg_test_descs[] = {
> 		}
> 	}, {
> 		.alg = "rsa",
>-		.test = alg_test_akcipher,
>+		.test = alg_test_null,
> 		.fips_allowed = 1,
> 		.suite = {
> 			.akcipher = {
>diff --git a/drivers/crypto/qat/qat_common/Makefile
>b/drivers/crypto/qat/qat_common/Makefile index df20a9d..ba5abdb 100644
>--- a/drivers/crypto/qat/qat_common/Makefile
>+++ b/drivers/crypto/qat/qat_common/Makefile
>@@ -13,8 +13,6 @@ intel_qat-objs := adf_cfg.o \
> 	adf_hw_arbiter.o \
> 	qat_crypto.o \
> 	qat_algs.o \
>-	qat_rsakey-asn1.o \
>-	qat_asym_algs.o \
> 	qat_uclo.o \
> 	qat_hal.o
>
>diff --git a/include/crypto/akcipher.h b/include/crypto/akcipher.h
>index 69d163e..7380e25 100644
>--- a/include/crypto/akcipher.h
>+++ b/include/crypto/akcipher.h
>@@ -13,28 +13,25 @@
> #ifndef _CRYPTO_AKCIPHER_H
> #define _CRYPTO_AKCIPHER_H
> #include <linux/crypto.h>
>+#include <linux/scatterlist.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
>- *		After operation it will be updated with the acctual size of 
the
>- *		result. In case of error, where the dst_len was insufficient,
>+ * @src:	Source data
>+ * @dst:	Destination data
>+ * @out_len:	Size of the result. After operation it will be updated with
>+ *		the acctual size of the data stored in the dst.
>+ *		In case of error, where the dst sgl size was insufficient,
>  *		it will be updated to the size required for the operation.
>  * @__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;
>+	struct scatterlist *src;
>+	struct scatterlist *dst;
>+	unsigned int out_len;
> 	void *__ctx[] CRYPTO_MINALIGN_ATTR;
> };
>
>@@ -67,8 +64,13 @@ struct crypto_akcipher {
>  *		algorithm. In case of error, where the dst_len was 
insufficient,
>  *		the req->dst_len will be updated to the size required for the
>  *		operation
>- * @setkey:	Function invokes the algorithm specific set key function, 
which
>- *		knows how to decode and interpret the BER encoded key
>+ * @set_pub_key: Function invokes the algorithm specific set public key
>+ *		function, which knows how to decode and interpret
>+ *		the BER encoded public key
>+ * @set_priv_key: Function invokes the algorithm specific set private key
>+ *		function, which knows how to decode and interpret
>+ *		the BER encoded private key
>+ * @get_len:	Function returns minimum dest buffer size for a given key.
>  * @init:	Initialize the cryptographic transformation object.
>  *		This function is used to initialize the cryptographic
>  *		transformation object. This function is called only once at
>@@ -89,8 +91,11 @@ struct akcipher_alg {
> 	int (*verify)(struct akcipher_request *req);
> 	int (*encrypt)(struct akcipher_request *req);
> 	int (*decrypt)(struct akcipher_request *req);
>-	int (*setkey)(struct crypto_akcipher *tfm, const void *key,
>-		      unsigned int keylen);
>+	int (*set_pub_key)(struct crypto_akcipher *tfm, const void *key,
>+			   unsigned int keylen);
>+	int (*set_priv_key)(struct crypto_akcipher *tfm, const void *key,
>+			    unsigned int keylen);
>+	int (*get_len)(struct crypto_akcipher *tfm);
> 	int (*init)(struct crypto_akcipher *tfm);
> 	void (*exit)(struct crypto_akcipher *tfm);
>
>@@ -229,21 +234,31 @@ static inline void akcipher_request_set_callback(struct
>akcipher_request *req, * 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. It will be updated by the
>- *		implementation to reflect the acctual size of the result
>+ * @src:	ptr to input scatter list
>+ * @dst:	ptr to output scatter list
>  */
> static inline void akcipher_request_set_crypt(struct akcipher_request *req,
>-					      void *src, void *dst,
>-					      unsigned int src_len,
>-					      unsigned int dst_len)
>+					      struct scatterlist *src,
>+					      struct scatterlist *dst)
> {
> 	req->src = src;
> 	req->dst = dst;
>-	req->src_len = src_len;
>-	req->dst_len = dst_len;
>+}
>+
>+/**
>+ * crypto_akcipher_get_len() -- Get minimum len for output buffer
>+ *
>+ * Function returns minimum dest buffer size for a given key
>+ *
>+ * @tfm:	AKCIPHER tfm handle allocated with crypto_alloc_akcipher()
>+ *
>+ * Return: minimum len for output buffer or error code in key hasn't been
>set + */
>+static inline int crypto_akcipher_get_len(struct crypto_akcipher *tfm)
>+{
>+	struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
>+
>+	return alg->get_len(tfm);
> }
>
> /**
>@@ -319,22 +334,44 @@ static inline int crypto_akcipher_verify(struct
>akcipher_request *req) }
>
> /**
>- * crypto_akcipher_setkey() -- Invoke public key setkey operation
>+ * crypto_akcipher_set_pub_key() -- Invoke set public key 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 public key

DER encoded?

>+ * @keylen:	length of the key
>+ *
>+ * Return: zero on success; error code in case of error
>+ */
>+static inline int crypto_akcipher_set_pub_key(struct crypto_akcipher *tfm,
>+					      const void *key,
>+					      unsigned int keylen)
>+{
>+	struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
>+
>+	return alg->set_pub_key(tfm, key, keylen);
>+}
>+
>+/**
>+ * crypto_akcipher_set_priv_key() -- Invoke set private key 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
>+ * @key:	BER encoded private key

DER encoded?

>  * @keylen:	length of the key
>  *
>  * Return: zero on success; error code in case of error
>  */
>-static inline int crypto_akcipher_setkey(struct crypto_akcipher *tfm, void
>*key, -					 unsigned int keylen)
>+static inline int crypto_akcipher_set_priv_key(struct crypto_akcipher *tfm,
>+					       const void *key,
>+					       unsigned int keylen)
> {
> 	struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
>
>-	return alg->setkey(tfm, key, keylen);
>+	return alg->set_priv_key(tfm, key, keylen);
> }
> #endif
>
>--
>To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html


Ciao
Stephan

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

* Re: [PATCH 5/8] lib/scatterlist: Add sg_len helper
  2015-09-09 16:15 ` [PATCH 5/8] lib/scatterlist: Add sg_len helper Tadeusz Struk
@ 2015-09-09 16:27   ` Stephan Mueller
  2015-09-09 16:31     ` Tadeusz Struk
  0 siblings, 1 reply; 32+ messages in thread
From: Stephan Mueller @ 2015-09-09 16:27 UTC (permalink / raw)
  To: Tadeusz Struk; +Cc: herbert, linux-crypto, qat-linux

Am Mittwoch, 9. September 2015, 09:15:26 schrieb Tadeusz Struk:

Hi Tadeusz,

>Add sg_len function which returns the total number of bytes in sg.
>
>Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
>---
> include/linux/scatterlist.h |    1 +
> lib/scatterlist.c           |   18 ++++++++++++++++++
> 2 files changed, 19 insertions(+)
>
>diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
>index 9b1ef0c..7c82fc1 100644
>--- a/include/linux/scatterlist.h
>+++ b/include/linux/scatterlist.h
>@@ -246,6 +246,7 @@ static inline void *sg_virt(struct scatterlist *sg)
> }
>
> int sg_nents(struct scatterlist *sg);
>+int sg_len(struct scatterlist *sg);
> int sg_nents_for_len(struct scatterlist *sg, u64 len);
> struct scatterlist *sg_next(struct scatterlist *);
> struct scatterlist *sg_last(struct scatterlist *s, unsigned int);
>diff --git a/lib/scatterlist.c b/lib/scatterlist.c
>index d105a9f..71324bb 100644
>--- a/lib/scatterlist.c
>+++ b/lib/scatterlist.c
>@@ -57,6 +57,24 @@ int sg_nents(struct scatterlist *sg)
> EXPORT_SYMBOL(sg_nents);
>
> /**
>+  * sg_len - return total size of bytes in the scatterlist
>+  * @sg:         The scatterlist
>+  *
>+  * Description:
>+  * Allows to know how the total size of bytes in sg, taking into acount
>+  * chaining as well
>+  **/
>+int sg_len(struct scatterlist *sg)

unsigned int?
>+{
>+	int len;
>+
>+	for (len = 0; sg; sg = sg_next(sg))
>+		len += sg->length;
>+	return len;
>+}
>+EXPORT_SYMBOL(sg_len);
>+
>+/**
>  * sg_nents_for_len - return total count of entries in scatterlist
>  *                    needed to satisfy the supplied length
>  * @sg:		The scatterlist
>
>--
>To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html


Ciao
Stephan

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

* Re: [PATCH 4/8] crypto: akcipher - Changes to asymmetric key API
  2015-09-09 16:25   ` Stephan Mueller
@ 2015-09-09 16:29     ` Tadeusz Struk
  2015-09-09 16:41       ` Stephan Mueller
  0 siblings, 1 reply; 32+ messages in thread
From: Tadeusz Struk @ 2015-09-09 16:29 UTC (permalink / raw)
  To: Stephan Mueller; +Cc: herbert, linux-crypto, qat-linux

Hi Stephan,
On 09/09/2015 09:25 AM, Stephan Mueller wrote:
>> >+#if 0
>> > static int do_test_rsa(struct crypto_akcipher *tfm,
>> > 		       struct akcipher_testvec *vecs)
>> > {
>> >@@ -1975,6 +1976,7 @@ static int alg_test_akcipher(const struct alg_test_desc
>> >*desc, crypto_free_akcipher(tfm);
>> > 	return err;
>> > }
>> >+#endif
> Just to check: is the ifdef 0 intentional?

Yes, it is otherwise it will break the build. It is enabled in subsequent patch.

>> + * @key:	BER encoded public key
> DER encoded?
> 

It is BER (Basic Encoding Rules), which is also valid DER (Distinguished Encoding Rules)

Regards
T

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

* Re: [PATCH 5/8] lib/scatterlist: Add sg_len helper
  2015-09-09 16:27   ` Stephan Mueller
@ 2015-09-09 16:31     ` Tadeusz Struk
  2015-09-09 16:39       ` Stephan Mueller
  2015-09-09 16:54       ` Stephan Mueller
  0 siblings, 2 replies; 32+ messages in thread
From: Tadeusz Struk @ 2015-09-09 16:31 UTC (permalink / raw)
  To: Stephan Mueller; +Cc: herbert, linux-crypto, qat-linux

On 09/09/2015 09:27 AM, Stephan Mueller wrote:
>> +int sg_len(struct scatterlist *sg)
> unsigned int?

No, because it can return -EINVAL if you call it before you set the key.

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

* Re: [PATCH 6/8] crypto: rsa - update accoring to akcipher API changes
  2015-09-09 16:15 ` [PATCH 6/8] crypto: rsa - update accoring to akcipher API changes Tadeusz Struk
@ 2015-09-09 16:35   ` Stephan Mueller
  2015-09-09 18:03     ` Tadeusz Struk
  0 siblings, 1 reply; 32+ messages in thread
From: Stephan Mueller @ 2015-09-09 16:35 UTC (permalink / raw)
  To: Tadeusz Struk; +Cc: herbert, linux-crypto, qat-linux

Am Mittwoch, 9. September 2015, 09:15:32 schrieb Tadeusz Struk:

Hi Tadeusz,

>Rsa updates to reflect the API changes.
>
>Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
>---
> crypto/Makefile               |   12 ++-
> crypto/rsa.c                  |  188
>++++++++++++++++++++++++++++++++++------- crypto/rsa_helper.c           |  
>42 ++++++++-
> crypto/rsakey.asn1            |    5 -
> crypto/rsaprivkey.asn1        |   11 ++
> crypto/rsapubkey.asn1         |    4 +
> include/crypto/internal/rsa.h |    7 +-
> 7 files changed, 220 insertions(+), 49 deletions(-)
> delete mode 100644 crypto/rsakey.asn1
> create mode 100644 crypto/rsaprivkey.asn1
> create mode 100644 crypto/rsapubkey.asn1
>
>diff --git a/crypto/Makefile b/crypto/Makefile
>index 65e91da..d897e0b 100644
>--- a/crypto/Makefile
>+++ b/crypto/Makefile
>@@ -31,8 +31,16 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
> obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
> obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
>
>-$(obj)/rsakey-asn1.o: $(obj)/rsakey-asn1.c $(obj)/rsakey-asn1.h
>-clean-files += rsakey-asn1.c rsakey-asn1.h
>+$(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
>+$(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
>+clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
>+clean-files += rsaprivkey-asn1.c rsaprivkey-asn1.h
>+
>+rsa_generic-y := rsapubkey-asn1.o
>+rsa_generic-y += rsaprivkey-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
>
>diff --git a/crypto/rsa.c b/crypto/rsa.c
>index 93feae2..f5b956c 100644
>--- a/crypto/rsa.c
>+++ b/crypto/rsa.c
>@@ -13,6 +13,7 @@
> #include <crypto/internal/rsa.h>
> #include <crypto/internal/akcipher.h>
> #include <crypto/akcipher.h>
>+#include <crypto/scatterwalk.h>
>
> /*
>  * RSAEP function [RFC3447 sec 5.1.1]
>@@ -80,34 +81,57 @@ static int rsa_enc(struct akcipher_request *req)
> 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
> 	const struct rsa_key *pkey = rsa_get_key(tfm);
> 	MPI m, c = mpi_alloc(0);
>+	int src_len = sg_len(req->src), dst_len = sg_len(req->dst);

unsigned int?

> 	int ret = 0;
> 	int sign;
>
> 	if (!c)
> 		return -ENOMEM;
>
>-	if (unlikely(!pkey->n || !pkey->e)) {
>+	if (unlikely(!pkey->n || !pkey->e || !src_len)) {
> 		ret = -EINVAL;
> 		goto err_free_c;
> 	}
>
>-	if (req->dst_len < mpi_get_size(pkey->n)) {
>-		req->dst_len = mpi_get_size(pkey->n);
>+	if (dst_len < mpi_get_size(pkey->n)) {
>+		req->out_len = mpi_get_size(pkey->n);
> 		ret = -EOVERFLOW;
> 		goto err_free_c;
> 	}
>
>-	m = mpi_read_raw_data(req->src, req->src_len);
>-	if (!m) {
>-		ret = -ENOMEM;
>-		goto err_free_c;
>+	ret = -ENOMEM;
>+	if (sg_is_last(req->src)) {
>+		m = mpi_read_raw_data(sg_virt(req->src), src_len);
>+	} else {
>+		void *ptr = kmalloc(src_len, GFP_KERNEL);
>+
>+		if (!ptr)
>+			goto err_free_c;
>+
>+		scatterwalk_map_and_copy(ptr, req->src, 0, src_len, 0);
>+		m = mpi_read_raw_data(ptr, src_len);
>+		kfree(ptr);
> 	}
>+	if (!m)
>+		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, &req->dst_len, 
&sign);
>+	if (sg_is_last(req->dst)) {
>+		ret = mpi_read_buffer(c, sg_virt(req->dst), dst_len,
>+				      &req->out_len, &sign);
>+	} else {
>+		void *ptr = kmalloc(dst_len, GFP_KERNEL);
>+
>+		if (!ptr)
>+			goto err_free_m;
>+
>+		ret = mpi_read_buffer(c, ptr, dst_len, &req->out_len, &sign);
>+		scatterwalk_map_and_copy(ptr, req->dst, 0, dst_len, 1);
>+		kfree(ptr);

Just a question: this code is present 4 times, can that be put into a separate 
inline?

>+	}
> 	if (ret)
> 		goto err_free_m;
>
>@@ -128,34 +152,57 @@ static int rsa_dec(struct akcipher_request *req)
> 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
> 	const struct rsa_key *pkey = rsa_get_key(tfm);
> 	MPI c, m = mpi_alloc(0);
>+	int src_len = sg_len(req->src), dst_len = sg_len(req->dst);

unsigned int?

> 	int ret = 0;
> 	int sign;
>
> 	if (!m)
> 		return -ENOMEM;
>
>-	if (unlikely(!pkey->n || !pkey->d)) {
>+	if (unlikely(!pkey->n || !pkey->d || !src_len)) {
> 		ret = -EINVAL;
> 		goto err_free_m;
> 	}
>
>-	if (req->dst_len < mpi_get_size(pkey->n)) {
>-		req->dst_len = mpi_get_size(pkey->n);
>+	if (dst_len < mpi_get_size(pkey->n)) {
>+		req->out_len = mpi_get_size(pkey->n);
> 		ret = -EOVERFLOW;
> 		goto err_free_m;
> 	}
>
>-	c = mpi_read_raw_data(req->src, req->src_len);
>-	if (!c) {
>-		ret = -ENOMEM;
>-		goto err_free_m;
>+	ret = -ENOMEM;
>+	if (sg_is_last(req->src)) {
>+		c = mpi_read_raw_data(sg_virt(req->src), src_len);
>+	} else {
>+		void *ptr = kmalloc(src_len, GFP_KERNEL);
>+
>+		if (!ptr)
>+			goto err_free_m;
>+
>+		scatterwalk_map_and_copy(ptr, req->src, 0, src_len, 0);
>+		c = mpi_read_raw_data(ptr, src_len);
>+		kfree(ptr);
> 	}
>+	if (!c)
>+		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, &req->dst_len, 
&sign);
>+	if (sg_is_last(req->dst)) {
>+		ret = mpi_read_buffer(m, sg_virt(req->dst), dst_len,
>+				      &req->out_len, &sign);
>+	} else {
>+		void *ptr = kmalloc(dst_len, GFP_KERNEL);
>+
>+		if (!ptr)
>+			goto err_free_c;
>+
>+		ret = mpi_read_buffer(m, ptr, dst_len, &req->out_len, &sign);
>+		scatterwalk_map_and_copy(ptr, req->dst, 0, dst_len, 1);
>+		kfree(ptr);
>+	}
> 	if (ret)
> 		goto err_free_c;
>
>@@ -176,34 +223,58 @@ static int rsa_sign(struct akcipher_request *req)
> 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
> 	const struct rsa_key *pkey = rsa_get_key(tfm);
> 	MPI m, s = mpi_alloc(0);
>+	int src_len = sg_len(req->src), dst_len = sg_len(req->dst);

unsigned int?

> 	int ret = 0;
> 	int sign;
>
> 	if (!s)
> 		return -ENOMEM;
>
>-	if (unlikely(!pkey->n || !pkey->d)) {
>+	if (unlikely(!pkey->n || !pkey->d || !src_len)) {
> 		ret = -EINVAL;
> 		goto err_free_s;
> 	}
>
>-	if (req->dst_len < mpi_get_size(pkey->n)) {
>-		req->dst_len = mpi_get_size(pkey->n);
>+	if (dst_len < mpi_get_size(pkey->n)) {
>+		req->out_len = mpi_get_size(pkey->n);
> 		ret = -EOVERFLOW;
> 		goto err_free_s;
> 	}
>
>-	m = mpi_read_raw_data(req->src, req->src_len);
>-	if (!m) {
>-		ret = -ENOMEM;
>-		goto err_free_s;
>+	ret = -ENOMEM;
>+	if (sg_is_last(req->src)) {
>+		m = mpi_read_raw_data(sg_virt(req->src), src_len);
>+	} else {
>+		void *ptr = kmalloc(src_len, GFP_KERNEL);
>+
>+		if (!ptr)
>+			goto err_free_s;
>+
>+		scatterwalk_map_and_copy(ptr, req->src, 0, src_len, 0);
>+		m = mpi_read_raw_data(ptr, src_len);
>+		kfree(ptr);
>+
> 	}
>+	if (!m)
>+		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, &req->dst_len, 
&sign);
>+	if (sg_is_last(req->dst)) {
>+		ret = mpi_read_buffer(s, sg_virt(req->dst), dst_len,
>+				      &req->out_len, &sign);
>+	} else {
>+		void *ptr = kmalloc(dst_len, GFP_KERNEL);
>+
>+		if (!ptr)
>+			goto err_free_m;
>+
>+		ret = mpi_read_buffer(s, ptr, dst_len, &req->out_len, &sign);
>+		scatterwalk_map_and_copy(ptr, req->dst, 0, dst_len, 1);
>+		kfree(ptr);
>+	}
> 	if (ret)
> 		goto err_free_m;
>
>@@ -224,24 +295,37 @@ static int rsa_verify(struct akcipher_request *req)
> 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
> 	const struct rsa_key *pkey = rsa_get_key(tfm);
> 	MPI s, m = mpi_alloc(0);
>+	int src_len = sg_len(req->src), dst_len = sg_len(req->dst);

unsigned int?

> 	int ret = 0;
> 	int sign;
>
> 	if (!m)
> 		return -ENOMEM;
>
>-	if (unlikely(!pkey->n || !pkey->e)) {
>+	if (unlikely(!pkey->n || !pkey->e || !src_len)) {
> 		ret = -EINVAL;
> 		goto err_free_m;
> 	}
>
>-	if (req->dst_len < mpi_get_size(pkey->n)) {
>-		req->dst_len = mpi_get_size(pkey->n);
>+	if (dst_len < mpi_get_size(pkey->n)) {
>+		req->out_len = mpi_get_size(pkey->n);
> 		ret = -EOVERFLOW;
> 		goto err_free_m;
> 	}
>
>-	s = mpi_read_raw_data(req->src, req->src_len);
>+	ret = -ENOMEM;
>+	if (sg_is_last(req->src)) {
>+		s = mpi_read_raw_data(sg_virt(req->src), src_len);
>+	} else {
>+		void *ptr = kmalloc(src_len, GFP_KERNEL);
>+
>+		if (!ptr)
>+			goto err_free_m;
>+
>+		scatterwalk_map_and_copy(ptr, req->src, 0, src_len, 0);
>+		s = mpi_read_raw_data(ptr, src_len);
>+		kfree(ptr);
>+	}
> 	if (!s) {
> 		ret = -ENOMEM;
> 		goto err_free_m;
>@@ -251,7 +335,19 @@ static int rsa_verify(struct akcipher_request *req)
> 	if (ret)
> 		goto err_free_s;
>
>-	ret = mpi_read_buffer(m, req->dst, req->dst_len, &req->dst_len, 
&sign);
>+	if (sg_is_last(req->dst)) {
>+		ret = mpi_read_buffer(m, sg_virt(req->dst), dst_len,
>+				      &req->out_len, &sign);
>+	} else {
>+		void *ptr = kmalloc(dst_len, GFP_KERNEL);
>+
>+		if (!ptr)
>+			goto err_free_s;
>+
>+		ret = mpi_read_buffer(m, ptr, dst_len, &req->out_len, &sign);
>+		scatterwalk_map_and_copy(ptr, req->dst, 0, dst_len, 1);
>+		kfree(ptr);
>+	}
> 	if (ret)
> 		goto err_free_s;
>
>@@ -282,13 +378,30 @@ static int rsa_check_key_length(unsigned int len)
> 	return -EINVAL;
> }
>
>-static int rsa_setkey(struct crypto_akcipher *tfm, const void *key,
>-		      unsigned int keylen)
>+static int rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
>+			   unsigned int keylen)
>+{
>+	struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
>+	int ret;
>+
>+	ret = rsa_parse_pub_key(pkey, key, keylen);
>+	if (ret)
>+		return ret;
>+
>+	if (rsa_check_key_length(mpi_get_size(pkey->n) << 3)) {
>+		rsa_free_key(pkey);
>+		ret = -EINVAL;
>+	}
>+	return ret;
>+}
>+
>+static int rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,
>+			    unsigned int keylen)
> {
> 	struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
> 	int ret;
>
>-	ret = rsa_parse_key(pkey, key, keylen);
>+	ret = rsa_parse_priv_key(pkey, key, keylen);
> 	if (ret)
> 		return ret;
>
>@@ -299,6 +412,13 @@ static int rsa_setkey(struct crypto_akcipher *tfm, const
>void *key, return ret;
> }
>
>+static int rsa_get_len(struct crypto_akcipher *tfm)
>+{
>+	struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
>+
>+	return pkey->n ? mpi_get_size(pkey->n) : -EINVAL;
>+}
>+
> static void rsa_exit_tfm(struct crypto_akcipher *tfm)
> {
> 	struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
>@@ -311,7 +431,9 @@ static struct akcipher_alg rsa = {
> 	.decrypt = rsa_dec,
> 	.sign = rsa_sign,
> 	.verify = rsa_verify,
>-	.setkey = rsa_setkey,
>+	.set_priv_key = rsa_set_priv_key,
>+	.set_pub_key = rsa_set_pub_key,
>+	.get_len = rsa_get_len,
> 	.exit = rsa_exit_tfm,
> 	.base = {
> 		.cra_name = "rsa",
>diff --git a/crypto/rsa_helper.c b/crypto/rsa_helper.c
>index 8d96ce9..d226f48 100644
>--- a/crypto/rsa_helper.c
>+++ b/crypto/rsa_helper.c
>@@ -15,7 +15,8 @@
> #include <linux/err.h>
> #include <linux/fips.h>
> #include <crypto/internal/rsa.h>
>-#include "rsakey-asn1.h"
>+#include "rsapubkey-asn1.h"
>+#include "rsaprivkey-asn1.h"
>
> int rsa_get_n(void *context, size_t hdrlen, unsigned char tag,
> 	      const void *value, size_t vlen)
>@@ -94,8 +95,8 @@ void rsa_free_key(struct rsa_key *key)
> EXPORT_SYMBOL_GPL(rsa_free_key);
>
> /**
>- * rsa_parse_key() - extracts an rsa key from BER encoded buffer
>- *		     and stores it in the provided struct rsa_key
>+ * rsa_parse_pub_key() - extracts an rsa public key from BER encoded buffer
>+ *			 and stores it in the provided struct rsa_key
>  *
>  * @rsa_key:	struct rsa_key key representation
>  * @key:	key in BER format
>@@ -103,13 +104,13 @@ EXPORT_SYMBOL_GPL(rsa_free_key);
>  *
>  * Return:	0 on success or error code in case of error
>  */
>-int rsa_parse_key(struct rsa_key *rsa_key, const void *key,
>-		  unsigned int key_len)
>+int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
>+		      unsigned int key_len)
> {
> 	int ret;
>
> 	free_mpis(rsa_key);
>-	ret = asn1_ber_decoder(&rsakey_decoder, rsa_key, key, key_len);
>+	ret = asn1_ber_decoder(&rsapubkey_decoder, rsa_key, key, key_len);
> 	if (ret < 0)
> 		goto error;
>
>@@ -118,4 +119,31 @@ error:
> 	free_mpis(rsa_key);
> 	return ret;
> }
>-EXPORT_SYMBOL_GPL(rsa_parse_key);
>+EXPORT_SYMBOL_GPL(rsa_parse_pub_key);
>+
>+/**
>+ * rsa_parse_pub_key() - extracts an rsa private key from BER encoded buffer
>+ *			 and stores it in the provided struct rsa_key

rsa_parse_*priv*_key

>+ *
>+ * @rsa_key:	struct rsa_key key representation
>+ * @key:	key in BER format
>+ * @key_len:	length of key
>+ *
>+ * Return:	0 on success or error code in case of error
>+ */
>+int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,
>+		       unsigned int key_len)
>+{
>+	int ret;
>+
>+	free_mpis(rsa_key);
>+	ret = asn1_ber_decoder(&rsaprivkey_decoder, rsa_key, key, key_len);
>+	if (ret < 0)
>+		goto error;
>+
>+	return 0;
>+error:
>+	free_mpis(rsa_key);
>+	return ret;
>+}
>+EXPORT_SYMBOL_GPL(rsa_parse_priv_key);
>diff --git a/crypto/rsakey.asn1 b/crypto/rsakey.asn1
>deleted file mode 100644
>index 3c7b5df..0000000
>--- a/crypto/rsakey.asn1
>+++ /dev/null
>@@ -1,5 +0,0 @@
>-RsaKey ::= SEQUENCE {
>-	n INTEGER ({ rsa_get_n }),
>-	e INTEGER ({ rsa_get_e }),
>-	d INTEGER ({ rsa_get_d })
>-}
>diff --git a/crypto/rsaprivkey.asn1 b/crypto/rsaprivkey.asn1
>new file mode 100644
>index 0000000..731aea5
>--- /dev/null
>+++ b/crypto/rsaprivkey.asn1
>@@ -0,0 +1,11 @@
>+RsaPrivKey ::= SEQUENCE {
>+	version		INTEGER,
>+	n		INTEGER ({ rsa_get_n }),
>+	e		INTEGER ({ rsa_get_e }),
>+	d		INTEGER ({ rsa_get_d }),
>+	prime1		INTEGER,
>+	prime2		INTEGER,
>+	exponent1	INTEGER,
>+	exponent2	INTEGER,
>+	coefficient	INTEGER
>+}
>diff --git a/crypto/rsapubkey.asn1 b/crypto/rsapubkey.asn1
>new file mode 100644
>index 0000000..725498e
>--- /dev/null
>+++ b/crypto/rsapubkey.asn1
>@@ -0,0 +1,4 @@
>+RsaPubKey ::= SEQUENCE {
>+	n INTEGER ({ rsa_get_n }),
>+	e INTEGER ({ rsa_get_e })
>+}
>diff --git a/include/crypto/internal/rsa.h b/include/crypto/internal/rsa.h
>index a8c8636..f997e2d 100644
>--- a/include/crypto/internal/rsa.h
>+++ b/include/crypto/internal/rsa.h
>@@ -20,8 +20,11 @@ struct rsa_key {
> 	MPI d;
> };
>
>-int rsa_parse_key(struct rsa_key *rsa_key, const void *key,
>-		  unsigned int key_len);
>+int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
>+		      unsigned int key_len);
>+
>+int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,
>+		       unsigned int key_len);
>
> void rsa_free_key(struct rsa_key *rsa_key);
> #endif
>
>--
>To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html


Ciao
Stephan

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

* Re: [PATCH 5/8] lib/scatterlist: Add sg_len helper
  2015-09-09 16:31     ` Tadeusz Struk
@ 2015-09-09 16:39       ` Stephan Mueller
  2015-09-09 16:46         ` Tadeusz Struk
  2015-09-09 16:54       ` Stephan Mueller
  1 sibling, 1 reply; 32+ messages in thread
From: Stephan Mueller @ 2015-09-09 16:39 UTC (permalink / raw)
  To: Tadeusz Struk; +Cc: herbert, linux-crypto, qat-linux

Am Mittwoch, 9. September 2015, 09:31:00 schrieb Tadeusz Struk:

Hi Tadeusz,

>On 09/09/2015 09:27 AM, Stephan Mueller wrote:
>>> +int sg_len(struct scatterlist *sg)
>> 
>> unsigned int?
>
>No, because it can return -EINVAL if you call it before you set the key.

I see.

But, shouldn't there be an overflow check? Maybe not here, but in the cases 
where the function is invoked. There is a kmalloc(src_len) without a check for 
negative values.


Ciao
Stephan

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

* Re: [PATCH 4/8] crypto: akcipher - Changes to asymmetric key API
  2015-09-09 16:29     ` Tadeusz Struk
@ 2015-09-09 16:41       ` Stephan Mueller
  2015-09-09 16:44         ` Tadeusz Struk
  2015-09-09 18:53         ` Andrzej Zaborowski
  0 siblings, 2 replies; 32+ messages in thread
From: Stephan Mueller @ 2015-09-09 16:41 UTC (permalink / raw)
  To: Tadeusz Struk; +Cc: herbert, linux-crypto, qat-linux

Am Mittwoch, 9. September 2015, 09:29:28 schrieb Tadeusz Struk:

Hi Tadeusz,

>>> + * @key:	BER encoded public key
>> 
>> DER encoded?
>
>It is BER (Basic Encoding Rules), which is also valid DER (Distinguished
>Encoding Rules)

I was just mentioning that since the ASN.1 structure now is equivalent to 
OpenSSL and what DER specifies. I just wanted to suggest to allow readers to 
establish a connection between OpenSSL DER encoded keys and the keys we use 
here.


Ciao
Stephan

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

* Re: [PATCH 4/8] crypto: akcipher - Changes to asymmetric key API
  2015-09-09 16:41       ` Stephan Mueller
@ 2015-09-09 16:44         ` Tadeusz Struk
  2015-09-09 18:53         ` Andrzej Zaborowski
  1 sibling, 0 replies; 32+ messages in thread
From: Tadeusz Struk @ 2015-09-09 16:44 UTC (permalink / raw)
  To: Stephan Mueller; +Cc: herbert, linux-crypto, qat-linux

On 09/09/2015 09:41 AM, Stephan Mueller wrote:
>> >It is BER (Basic Encoding Rules), which is also valid DER (Distinguished
>> >Encoding Rules)
> I was just mentioning that since the ASN.1 structure now is equivalent to 
> OpenSSL and what DER specifies. I just wanted to suggest to allow readers to 
> establish a connection between OpenSSL DER encoded keys and the keys we use 

Since DER is a valid BER it will work for both.

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

* Re: [PATCH 5/8] lib/scatterlist: Add sg_len helper
  2015-09-09 16:39       ` Stephan Mueller
@ 2015-09-09 16:46         ` Tadeusz Struk
  2015-09-09 16:49           ` Stephan Mueller
  0 siblings, 1 reply; 32+ messages in thread
From: Tadeusz Struk @ 2015-09-09 16:46 UTC (permalink / raw)
  To: Stephan Mueller; +Cc: herbert, linux-crypto, qat-linux

On 09/09/2015 09:39 AM, Stephan Mueller wrote:
>> No, because it can return -EINVAL if you call it before you set the key.
> I see.
> 
> But, shouldn't there be an overflow check? Maybe not here, but in the cases 
> where the function is invoked. There is a kmalloc(src_len) without a check for 
> negative values.

Right, but because testmgr.c calls setkey before this I skipped the check.

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

* Re: [PATCH 5/8] lib/scatterlist: Add sg_len helper
  2015-09-09 16:46         ` Tadeusz Struk
@ 2015-09-09 16:49           ` Stephan Mueller
  2015-09-09 16:51             ` Tadeusz Struk
  0 siblings, 1 reply; 32+ messages in thread
From: Stephan Mueller @ 2015-09-09 16:49 UTC (permalink / raw)
  To: Tadeusz Struk; +Cc: herbert, linux-crypto, qat-linux

Am Mittwoch, 9. September 2015, 09:46:36 schrieb Tadeusz Struk:

Hi Tadeusz,

>On 09/09/2015 09:39 AM, Stephan Mueller wrote:
>>> No, because it can return -EINVAL if you call it before you set the key.
>> 
>> I see.
>> 
>> But, shouldn't there be an overflow check? Maybe not here, but in the cases
>> where the function is invoked. There is a kmalloc(src_len) without a check
>> for negative values.
>
>Right, but because testmgr.c calls setkey before this I skipped the check.

But in the rsa.c enc/dec/verify/sign functions, there should be such check, I 
would guess.


Ciao
Stephan

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

* Re: [PATCH 5/8] lib/scatterlist: Add sg_len helper
  2015-09-09 16:49           ` Stephan Mueller
@ 2015-09-09 16:51             ` Tadeusz Struk
  2015-09-09 16:56               ` Stephan Mueller
  0 siblings, 1 reply; 32+ messages in thread
From: Tadeusz Struk @ 2015-09-09 16:51 UTC (permalink / raw)
  To: Stephan Mueller; +Cc: herbert, linux-crypto, qat-linux

On 09/09/2015 09:49 AM, Stephan Mueller wrote:
>>> >> But, shouldn't there be an overflow check? Maybe not here, but in the cases
>>> >> where the function is invoked. There is a kmalloc(src_len) without a check
>>> >> for negative values.
>> >
>> >Right, but because testmgr.c calls setkey before this I skipped the check.
> But in the rsa.c enc/dec/verify/sign functions, there should be such check, I 
> would guess.

There is see line 419:
return pkey->n ? mpi_get_size(pkey->n) : -EINVAL;

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

* Re: [PATCH 5/8] lib/scatterlist: Add sg_len helper
  2015-09-09 16:31     ` Tadeusz Struk
  2015-09-09 16:39       ` Stephan Mueller
@ 2015-09-09 16:54       ` Stephan Mueller
  1 sibling, 0 replies; 32+ messages in thread
From: Stephan Mueller @ 2015-09-09 16:54 UTC (permalink / raw)
  To: Tadeusz Struk; +Cc: herbert, linux-crypto, qat-linux

Am Mittwoch, 9. September 2015, 09:31:00 schrieb Tadeusz Struk:

Hi Tadeusz,

>On 09/09/2015 09:27 AM, Stephan Mueller wrote:
>>> +int sg_len(struct scatterlist *sg)
>> 
>> unsigned int?
>
>No, because it can return -EINVAL if you call it before you set the key.

Just re-reading the code: where would the -EINVAL be generated?

Ciao
Stephan

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

* Re: [PATCH 5/8] lib/scatterlist: Add sg_len helper
  2015-09-09 16:51             ` Tadeusz Struk
@ 2015-09-09 16:56               ` Stephan Mueller
  2015-09-09 17:02                 ` Tadeusz Struk
  0 siblings, 1 reply; 32+ messages in thread
From: Stephan Mueller @ 2015-09-09 16:56 UTC (permalink / raw)
  To: Tadeusz Struk; +Cc: herbert, linux-crypto, qat-linux

Am Mittwoch, 9. September 2015, 09:51:40 schrieb Tadeusz Struk:

Hi Tadeusz,

>On 09/09/2015 09:49 AM, Stephan Mueller wrote:
>>>> >> But, shouldn't there be an overflow check? Maybe not here, but in the
>>>> >> cases
>>>> >> where the function is invoked. There is a kmalloc(src_len) without a
>>>> >> check
>>>> >> for negative values.
>>> >
>>> >Right, but because testmgr.c calls setkey before this I skipped the
>>> >check.
>> 
>> But in the rsa.c enc/dec/verify/sign functions, there should be such check,
>> I would guess.
>
>There is see line 419:
>return pkey->n ? mpi_get_size(pkey->n) : -EINVAL;

I feel we are not talking about the same issue. I refer to your patch in 
rsa.c:

+       int src_len = sg_len(req->src), dst_len = sg_len(req->dst);

===> can be negative according to your statement

...

+               void *ptr = kmalloc(dst_len, GFP_KERNEL);

===> with a negative number, I guess we have a problem here.


Ciao
Stephan

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

* Re: [PATCH 5/8] lib/scatterlist: Add sg_len helper
  2015-09-09 16:56               ` Stephan Mueller
@ 2015-09-09 17:02                 ` Tadeusz Struk
  2015-09-09 17:05                   ` Stephan Mueller
  0 siblings, 1 reply; 32+ messages in thread
From: Tadeusz Struk @ 2015-09-09 17:02 UTC (permalink / raw)
  To: Stephan Mueller; +Cc: herbert, linux-crypto, qat-linux

On 09/09/2015 09:56 AM, Stephan Mueller wrote:
>>> But in the rsa.c enc/dec/verify/sign functions, there should be such check,
>>> >> I would guess.
>> >
>> >There is see line 419:
>> >return pkey->n ? mpi_get_size(pkey->n) : -EINVAL;
> I feel we are not talking about the same issue. I refer to your patch in 
> rsa.c:
> 
> +       int src_len = sg_len(req->src), dst_len = sg_len(req->dst);
> 
> ===> can be negative according to your statement
> 
> ...
> 
> +               void *ptr = kmalloc(dst_len, GFP_KERNEL);
> 
> ===> with a negative number, I guess we have a problem here.

Yes, sorry, you are right. sg_len() will only return positive numbers or zero.
rsa.c checks it in all four operations:
if (unlikely(!pkey->n || !pkey->d || !src_len)) 

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

* Re: [PATCH 5/8] lib/scatterlist: Add sg_len helper
  2015-09-09 17:02                 ` Tadeusz Struk
@ 2015-09-09 17:05                   ` Stephan Mueller
  2015-09-09 17:16                     ` Tadeusz Struk
  0 siblings, 1 reply; 32+ messages in thread
From: Stephan Mueller @ 2015-09-09 17:05 UTC (permalink / raw)
  To: Tadeusz Struk; +Cc: herbert, linux-crypto, qat-linux

Am Mittwoch, 9. September 2015, 10:02:17 schrieb Tadeusz Struk:

Hi Tadeusz,

>On 09/09/2015 09:56 AM, Stephan Mueller wrote:
>>>> But in the rsa.c enc/dec/verify/sign functions, there should be such
>>>> check,
>>>> 
>>>> >> I would guess.
>>> >
>>> >There is see line 419:
>>> >return pkey->n ? mpi_get_size(pkey->n) : -EINVAL;
>> 
>> I feel we are not talking about the same issue. I refer to your patch in
>> rsa.c:
>> 
>> +       int src_len = sg_len(req->src), dst_len = sg_len(req->dst);
>> 
>> ===> can be negative according to your statement
>> 
>> ...
>> 
>> +               void *ptr = kmalloc(dst_len, GFP_KERNEL);
>> 
>> ===> with a negative number, I guess we have a problem here.
>
>Yes, sorry, you are right. sg_len() will only return positive numbers or
>zero. rsa.c checks it in all four operations:
>if (unlikely(!pkey->n || !pkey->d || !src_len))

Great, I am not disputing the check for 0, I just want an unsigned int, 
because sg->length is unsigned int too. :-)


Ciao
Stephan

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

* Re: [PATCH 5/8] lib/scatterlist: Add sg_len helper
  2015-09-09 17:05                   ` Stephan Mueller
@ 2015-09-09 17:16                     ` Tadeusz Struk
  2015-09-09 17:37                       ` Stephan Mueller
  0 siblings, 1 reply; 32+ messages in thread
From: Tadeusz Struk @ 2015-09-09 17:16 UTC (permalink / raw)
  To: Stephan Mueller; +Cc: herbert, linux-crypto, qat-linux

On 09/09/2015 10:05 AM, Stephan Mueller wrote:
>> Yes, sorry, you are right. sg_len() will only return positive numbers or
>> >zero. rsa.c checks it in all four operations:
>> >if (unlikely(!pkey->n || !pkey->d || !src_len))
> Great, I am not disputing the check for 0, I just want an unsigned int, 
> because sg->length is unsigned int too. :-)

I see, maybe we can check for negative numbers in PF_ALG?

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

* Re: [PATCH 5/8] lib/scatterlist: Add sg_len helper
  2015-09-09 17:16                     ` Tadeusz Struk
@ 2015-09-09 17:37                       ` Stephan Mueller
  0 siblings, 0 replies; 32+ messages in thread
From: Stephan Mueller @ 2015-09-09 17:37 UTC (permalink / raw)
  To: Tadeusz Struk; +Cc: herbert, linux-crypto, qat-linux

Am Mittwoch, 9. September 2015, 10:16:16 schrieb Tadeusz Struk:

Hi Tadeusz,

>On 09/09/2015 10:05 AM, Stephan Mueller wrote:
>>> Yes, sorry, you are right. sg_len() will only return positive numbers or
>>> 
>>> >zero. rsa.c checks it in all four operations:
>>> >if (unlikely(!pkey->n || !pkey->d || !src_len))
>> 
>> Great, I am not disputing the check for 0, I just want an unsigned int,
>> because sg->length is unsigned int too. :-)
>
>I see, maybe we can check for negative numbers in PF_ALG?

My request for turning the implementation of sg_len and the callers of it to 
use unsigned int is simply to avoid overflows of the counter.

Note, I usually am very zealous about using the correct data types, especially 
with integers. I have seen way to many security related bugs by overflowing a 
signed integer.

Surely, PF_ALG will ensure that user space will only provide buffers up to a 
max number (PAGE_SIZE * ALG_MAX_PAGES is the maximum user space can provide at 
all considering my current user space approach). So, we have at most 65536 
bytes from user space in one request. This boundary is to allow at most 
ALG_MAX_PAGES individual SGL members (i.e. at most ALG_MAX_PAGES individual 
calls to splice) but also tries to squeeze the data coming with sendmsg into 
one page. But, surely we can discuss these limits once I post algif_akcipher.

Considering that, I do not feel that the code we discuss here should have a 
check for the maximum size of the SGL.


Ciao
Stephan

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

* Re: [PATCH 6/8] crypto: rsa - update accoring to akcipher API changes
  2015-09-09 16:35   ` Stephan Mueller
@ 2015-09-09 18:03     ` Tadeusz Struk
  0 siblings, 0 replies; 32+ messages in thread
From: Tadeusz Struk @ 2015-09-09 18:03 UTC (permalink / raw)
  To: Stephan Mueller; +Cc: herbert, linux-crypto, qat-linux

On 09/09/2015 09:35 AM, Stephan Mueller wrote:
>> +	if (sg_is_last(req->dst)) {
>> >+		ret = mpi_read_buffer(c, sg_virt(req->dst), dst_len,
>> >+				      &req->out_len, &sign);
>> >+	} else {
>> >+		void *ptr = kmalloc(dst_len, GFP_KERNEL);
>> >+
>> >+		if (!ptr)
>> >+			goto err_free_m;
>> >+
>> >+		ret = mpi_read_buffer(c, ptr, dst_len, &req->out_len, &sign);
>> >+		scatterwalk_map_and_copy(ptr, req->dst, 0, dst_len, 1);
>> >+		kfree(ptr);
> Just a question: this code is present 4 times, can that be put into a separate 
> inline?
> 

I have put it like this because it is easier to read.
All 4 functions use different variable names according to the spec.

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

* Re: [PATCH 4/8] crypto: akcipher - Changes to asymmetric key API
  2015-09-09 16:41       ` Stephan Mueller
  2015-09-09 16:44         ` Tadeusz Struk
@ 2015-09-09 18:53         ` Andrzej Zaborowski
  2015-09-09 19:13           ` Stephan Mueller
  1 sibling, 1 reply; 32+ messages in thread
From: Andrzej Zaborowski @ 2015-09-09 18:53 UTC (permalink / raw)
  To: Stephan Mueller; +Cc: Tadeusz Struk, herbert, linux-crypto, qat-linux

Hi,

On 9 September 2015 at 18:41, Stephan Mueller <smueller@chronox.de> wrote:
> Am Mittwoch, 9. September 2015, 09:29:28 schrieb Tadeusz Struk:
>>>> + * @key:   BER encoded public key
>>>
>>> DER encoded?
>>
>>It is BER (Basic Encoding Rules), which is also valid DER (Distinguished
>>Encoding Rules)
>
> I was just mentioning that since the ASN.1 structure now is equivalent to
> OpenSSL and what DER specifies. I just wanted to suggest to allow readers to
> establish a connection between OpenSSL DER encoded keys and the keys we use
> here.

Shouldn't the BER/DER requirement be only mentioned in rsa.c?  For
other asymmetric key ciphers there may, in theory, be a completely
different established key encoding and no point in using DER on top.

Also a question regarding .get_len: for RSA with padding the minimum
dest buffer length depends on the input.  What is that call supposed
to return in that case?

Best regards

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

* Re: [PATCH 4/8] crypto: akcipher - Changes to asymmetric key API
  2015-09-09 18:53         ` Andrzej Zaborowski
@ 2015-09-09 19:13           ` Stephan Mueller
  2015-09-09 19:35             ` Tadeusz Struk
  0 siblings, 1 reply; 32+ messages in thread
From: Stephan Mueller @ 2015-09-09 19:13 UTC (permalink / raw)
  To: Andrzej Zaborowski; +Cc: Tadeusz Struk, herbert, linux-crypto, qat-linux

Am Mittwoch, 9. September 2015, 20:53:23 schrieb Andrzej Zaborowski:

Hi Andrzej,
>
>Also a question regarding .get_len: for RSA with padding the minimum
>dest buffer length depends on the input.  What is that call supposed
>to return in that case?

I would guess that the destination buffer minimum size should be RSA size 
minus the minimum padding size. This way, the caller is always sure to get all 
data without error.

Ciao
Stephan

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

* Re: [PATCH 4/8] crypto: akcipher - Changes to asymmetric key API
  2015-09-09 19:13           ` Stephan Mueller
@ 2015-09-09 19:35             ` Tadeusz Struk
  0 siblings, 0 replies; 32+ messages in thread
From: Tadeusz Struk @ 2015-09-09 19:35 UTC (permalink / raw)
  To: Stephan Mueller, Andrzej Zaborowski; +Cc: herbert, linux-crypto, qat-linux

On 09/09/2015 12:13 PM, Stephan Mueller wrote:
>> >Also a question regarding .get_len: for RSA with padding the minimum
>> >dest buffer length depends on the input.  What is that call supposed
>> >to return in that case?
> I would guess that the destination buffer minimum size should be RSA size 
> minus the minimum padding size. This way, the caller is always sure to get all 
> data without error.

I think it should always be the size of modulo.

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

* Re: [PATCH 1/8] crypto: akcipher - return status from crypto_unregister_alg
  2015-09-09 16:15 ` [PATCH 1/8] crypto: akcipher - return status from crypto_unregister_alg Tadeusz Struk
@ 2015-09-18 11:29   ` Herbert Xu
  0 siblings, 0 replies; 32+ messages in thread
From: Herbert Xu @ 2015-09-18 11:29 UTC (permalink / raw)
  To: Tadeusz Struk; +Cc: linux-crypto, qat-linux

On Wed, Sep 09, 2015 at 09:15:01AM -0700, Tadeusz Struk wrote:
> Return status from crypto_unregister_alg to the caller.

Why? My plan is to turn crypto_unregister_alg into a void function.

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

* Re: [PATCH 4/8] crypto: akcipher - Changes to asymmetric key API
  2015-09-09 16:15 ` [PATCH 4/8] crypto: akcipher - Changes to asymmetric key API Tadeusz Struk
  2015-09-09 16:25   ` Stephan Mueller
@ 2015-09-18 11:35   ` Herbert Xu
  1 sibling, 0 replies; 32+ messages in thread
From: Herbert Xu @ 2015-09-18 11:35 UTC (permalink / raw)
  To: Tadeusz Struk; +Cc: linux-crypto, qat-linux

On Wed, Sep 09, 2015 at 09:15:20AM -0700, Tadeusz Struk wrote:
> Setkey function has been split into set_priv_key and set_pub_key.
> Akcipher requests takes sgl for src and dst instead of void *.
> Users of the API need to be disabled so that the build works fine
> after this patch.
> They will be enabled in subsequent patches.
> 
> Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>

Either do everything as a single patch (patches 4,6-8) or do it
properly by making incremental changes like what I did with AEAD
and RNG.

In this case I think a single patch is probably the best option.

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

end of thread, other threads:[~2015-09-18 11:35 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-09 16:14 [PATCH 0/8] crypto: Updates to akcipher API Tadeusz Struk
2015-09-09 16:15 ` [PATCH 1/8] crypto: akcipher - return status from crypto_unregister_alg Tadeusz Struk
2015-09-18 11:29   ` Herbert Xu
2015-09-09 16:15 ` [PATCH 2/8] crypto: rsa - check status returned from crypto_unregister_akcipher Tadeusz Struk
2015-09-09 16:15 ` [PATCH 3/8] crypto: qat " Tadeusz Struk
2015-09-09 16:15 ` [PATCH 4/8] crypto: akcipher - Changes to asymmetric key API Tadeusz Struk
2015-09-09 16:25   ` Stephan Mueller
2015-09-09 16:29     ` Tadeusz Struk
2015-09-09 16:41       ` Stephan Mueller
2015-09-09 16:44         ` Tadeusz Struk
2015-09-09 18:53         ` Andrzej Zaborowski
2015-09-09 19:13           ` Stephan Mueller
2015-09-09 19:35             ` Tadeusz Struk
2015-09-18 11:35   ` Herbert Xu
2015-09-09 16:15 ` [PATCH 5/8] lib/scatterlist: Add sg_len helper Tadeusz Struk
2015-09-09 16:27   ` Stephan Mueller
2015-09-09 16:31     ` Tadeusz Struk
2015-09-09 16:39       ` Stephan Mueller
2015-09-09 16:46         ` Tadeusz Struk
2015-09-09 16:49           ` Stephan Mueller
2015-09-09 16:51             ` Tadeusz Struk
2015-09-09 16:56               ` Stephan Mueller
2015-09-09 17:02                 ` Tadeusz Struk
2015-09-09 17:05                   ` Stephan Mueller
2015-09-09 17:16                     ` Tadeusz Struk
2015-09-09 17:37                       ` Stephan Mueller
2015-09-09 16:54       ` Stephan Mueller
2015-09-09 16:15 ` [PATCH 6/8] crypto: rsa - update accoring to akcipher API changes Tadeusz Struk
2015-09-09 16:35   ` Stephan Mueller
2015-09-09 18:03     ` Tadeusz Struk
2015-09-09 16:15 ` [PATCH 7/8] crypto: qat " Tadeusz Struk
2015-09-09 16:15 ` [PATCH 8/8] crypto: testmgr - update test mgr according to " Tadeusz Struk

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