[PATCH] PCI: Make pci_find_upstream_pcie_bridge() handle non PCIE VFs well

2013-01-08 Thread tadeusz . struk
pci_find_upstream_pcie_bridge() doesn't handle well non PCIE VFs
that are part of a PCIE PF device.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 drivers/pci/search.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index bf969ba..8ecdab2 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -23,6 +23,8 @@ EXPORT_SYMBOL_GPL(pci_bus_sem);
  * if the device isn't connected to a PCIe bridge (that is its parent is a
  * legacy PCI bridge and the bridge is directly connected to bus 0), return its
  * parent
+ * if the device is a VF that doesn't have PCIe cap,
+ * but the PF is a PCIE, return NULL
  */
 struct pci_dev *
 pci_find_upstream_pcie_bridge(struct pci_dev *pdev)
@@ -31,6 +33,10 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev)
 
if (pci_is_pcie(pdev))
return NULL;
+
+   if (pdev-is_virtfn  pci_is_pcie(pdev-physfn))
+   return NULL;
+
while (1) {
if (pci_is_root_bus(pdev-bus))
break;
-- 
1.7.7

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


Re: [PATCH] PCI: Make pci_find_upstream_pcie_bridge() handle non PCIE VFs well

2013-01-09 Thread Tadeusz Struk
On 01/08/2013 05:05 PM, Don Dutile wrote:

 (a) no such thing as a non-PCIe VF -- all VFs
 are PCIe-based.

The sriov spec says that a VF doesn't necessarily has to have PCIE cap:
3.5 PCI Express Capability:
   ...
   PFs and VFs are required to implement this capability ... subject to
   the exceptions and additional requirements described below

 (b) code says to return null if VF doesn't have PCIe cap,
 but the code checks if pdev is VF and if PF is PCIe,
 which it must be! ...

You are right, I should rather check if the VF is not a pcie.

 nack until a better /or matching explanation of what
 the real problem is, and what the solution is trying to do.

The problem is that I do have a device where VFs are not PCIE and I get this 
nasty warning.
For now I have a workaround, but it would be nice it Linux would support non 
PCIE VFs.

Thanks,
T

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


[PATCH] crypto: Fix DMA-API warning

2014-05-19 Thread Tadeusz Struk
With DMA-API debug enabled testmgr triggers a DMA-API: device driver maps 
memory from stack warning, when tested on a crypto HW accelerator.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/testmgr.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index dc3cf35..75c78e6 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -414,16 +414,18 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
void *input;
void *output;
void *assoc;
-   char iv[MAX_IVLEN];
+   char *iv;
char *xbuf[XBUFSIZE];
char *xoutbuf[XBUFSIZE];
char *axbuf[XBUFSIZE];
 
+   iv = kzalloc(MAX_IVLEN, GFP_KERNEL);
+   if (!iv)
+   return ret;
if (testmgr_alloc_buf(xbuf))
goto out_noxbuf;
if (testmgr_alloc_buf(axbuf))
goto out_noaxbuf;
-
if (diff_dst  testmgr_alloc_buf(xoutbuf))
goto out_nooutbuf;
 
@@ -767,6 +769,7 @@ out_nooutbuf:
 out_noaxbuf:
testmgr_free_buf(xbuf);
 out_noxbuf:
+   kfree(iv);
return ret;
 }
 
-- 
1.8.5.rc2.6.gc6f1b92.dirty

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


[RFC][PATCH 3/4] crypto: QAT dh895xcc accelerator support

2014-06-03 Thread Tadeusz Struk
Third patch adds dh895xcc hardware specific code.
It hooks to the common infrastructure and provides acceleration for crypto 
algorithms.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
Acked-by: John Griffin john.grif...@intel.com
Reviewed-by: Bruce W. Allan bruce.w.al...@intel.com
---
 drivers/crypto/qat/qat_dh895xcc/Makefile   |   8 +
 drivers/crypto/qat/qat_dh895xcc/adf_admin.c| 144 +++
 .../crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c | 214 ++
 .../crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.h |  86 
 drivers/crypto/qat/qat_dh895xcc/adf_drv.c  | 448 +
 drivers/crypto/qat/qat_dh895xcc/adf_drv.h  |  67 +++
 drivers/crypto/qat/qat_dh895xcc/adf_hw_arbiter.c   | 159 
 drivers/crypto/qat/qat_dh895xcc/adf_isr.c  | 266 
 drivers/crypto/qat/qat_dh895xcc/qat_admin.c| 107 +
 9 files changed, 1499 insertions(+)
 create mode 100644 drivers/crypto/qat/qat_dh895xcc/Makefile
 create mode 100644 drivers/crypto/qat/qat_dh895xcc/adf_admin.c
 create mode 100644 drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c
 create mode 100644 drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.h
 create mode 100644 drivers/crypto/qat/qat_dh895xcc/adf_drv.c
 create mode 100644 drivers/crypto/qat/qat_dh895xcc/adf_drv.h
 create mode 100644 drivers/crypto/qat/qat_dh895xcc/adf_hw_arbiter.c
 create mode 100644 drivers/crypto/qat/qat_dh895xcc/adf_isr.c
 create mode 100644 drivers/crypto/qat/qat_dh895xcc/qat_admin.c

diff --git a/drivers/crypto/qat/qat_dh895xcc/Makefile 
b/drivers/crypto/qat/qat_dh895xcc/Makefile
new file mode 100644
index 000..8e4924d
--- /dev/null
+++ b/drivers/crypto/qat/qat_dh895xcc/Makefile
@@ -0,0 +1,8 @@
+ccflags-y := -I$(CURDIR)/drivers/crypto/qat/qat_common
+obj-$(CONFIG_CRYPTO_DEV_QAT_DH895xCC) += qat_dh895xcc.o
+qat_dh895xcc-objs := adf_drv.o \
+   adf_isr.o \
+   adf_dh895xcc_hw_data.o \
+   adf_hw_arbiter.o \
+   qat_admin.o \
+   adf_admin.o
diff --git a/drivers/crypto/qat/qat_dh895xcc/adf_admin.c 
b/drivers/crypto/qat/qat_dh895xcc/adf_admin.c
new file mode 100644
index 000..978d6c5
--- /dev/null
+++ b/drivers/crypto/qat/qat_dh895xcc/adf_admin.c
@@ -0,0 +1,144 @@
+/*
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+  Copyright(c) 2014 Intel Corporation.
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  General Public License for more details.
+
+  Contact Information:
+  qat-li...@intel.com
+
+  BSD LICENSE
+  Copyright(c) 2014 Intel Corporation.
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+* Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in
+  the documentation and/or other materials provided with the
+  distribution.
+* Neither the name of Intel Corporation nor the names of its
+  contributors may be used to endorse or promote products derived
+  from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#include linux/types.h
+#include linux/mutex.h
+#include linux/slab.h
+#include linux/delay.h
+#include linux/pci.h
+#include linux/dma-mapping.h
+#include adf_accel_devices.h
+#include adf_drv.h
+#include adf_dh895xcc_hw_data.h
+
+#define ADF_ADMINMSG_LEN 32
+
+struct adf_admin_comms {
+   dma_addr_t phy_addr;
+   void *virt_addr;
+   void __iomem *mailbox_addr;
+   struct mutex lock;  /* protects adf_admin_comms

[RFC][PATCH 4/4] crypto: Updated makefiles to add QAT

2014-06-03 Thread Tadeusz Struk
Update to makefiles etc.
Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 Documentation/ioctl/ioctl-number.txt | 1 +
 MAINTAINERS  | 6 ++
 drivers/crypto/Kconfig   | 1 +
 drivers/crypto/Makefile  | 1 +
 firmware/Makefile| 1 +
 5 files changed, 10 insertions(+)

diff --git a/Documentation/ioctl/ioctl-number.txt 
b/Documentation/ioctl/ioctl-number.txt
index d7e43fa..7e240a7 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -197,6 +197,7 @@ Code  Seq#(hex) Include FileComments
mailto:gre...@linuxfoundation.org
 'a'all linux/atm*.h, linux/sonet.h ATM on linux
http://lrcwww.epfl.ch/
+'a'00-0F   drivers/crypto/qat/qat_common/adf_cfg_common.h  conflict! qat 
driver
 'b'00-FF   conflict! bit3 vme host bridge
mailto:nata...@nikhefk.nikhef.nl
 'c'all linux/cm4000_cs.h   conflict!
diff --git a/MAINTAINERS b/MAINTAINERS
index 3467445..5482679 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7060,6 +7060,12 @@ M:   Robert Jarzmik robert.jarz...@free.fr
 L: rtc-li...@googlegroups.com
 S: Maintained
 
+QAT DRIVER
+M:  Tadeusz Struk tadeusz.st...@intel.com
+L:  qat-li...@intel.com
+S:  Supported
+F:  drivers/crypto/qat/
+
 QIB DRIVER
 M: Mike Marciniszyn infinip...@intel.com
 L: linux-r...@vger.kernel.org
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index f066fa2..1f20814 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -418,4 +418,5 @@ config CRYPTO_DEV_MXS_DCP
  To compile this driver as a module, choose M here: the module
  will be called mxs-dcp.
 
+source drivers/crypto/qat/Kconfig
 endif # CRYPTO_HW
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 482f090..f996ed7 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -23,3 +23,4 @@ obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o
 obj-$(CONFIG_CRYPTO_DEV_SAHARA) += sahara.o
 obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
 obj-$(CONFIG_CRYPTO_DEV_UX500) += ux500/
+obj-$(CONFIG_CRYPTO_DEV_QAT) += qat/
diff --git a/firmware/Makefile b/firmware/Makefile
index cbb09ce..89ac80b 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -135,6 +135,7 @@ fw-shipped-$(CONFIG_USB_SERIAL_XIRCOM) += 
keyspan_pda/xircom_pgs.fw
 fw-shipped-$(CONFIG_USB_VICAM) += vicam/firmware.fw
 fw-shipped-$(CONFIG_VIDEO_CPIA2) += cpia2/stv0672_vp4.bin
 fw-shipped-$(CONFIG_YAM) += yam/1200.bin yam/9600.bin
+fw-shipped-$(CONFIG_CRYPTO_DEV_QAT_DH895xCC) += qat_895xcc.bin
 
 fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-)
 
-- 
1.8.5.rc2.6.gc6f1b92.dirty

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


[RFC][PATCH 0/4] crypto: Intel QAT driver

2014-06-03 Thread Tadeusz Struk
Hi,
This patchset adds support for Intel Quick Assist Technology and DH895xxC 
hardware accelerator.
First patch adds a common infractructure that will be used by all QAT devices.
Second patch adds a firmware loader module that is used to load the microcode 
to the acceleration engines and start them.
Third patch adds dh895xcc hardware specific code, which hooks to the common 
infrastructure and provides acceleration for
the following algorithms:
authenc(hmac(sha1),cbc(aes)), authenc(hmac(sha256),cbc(aes)), 
authenc(hmac(sha512),cbc(aes))
Forth patch updates makefiles etc.

More info on the hardware accelerator and the Quick Assist can be on:
https://01.org/packet-processing/intel%C2%AE-quickassist-technology-drivers-and-patches

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
Signed-off-by: Karen Xiang karen.xi...@intel.com
Signed-off-by: Pingchaox Yang pingchaox.y...@intel.com
Acked-by: John Griffin john.grif...@intel.com
Acked-by: Bo Cui bo@intel.com
Reviewed-by: Bruce W. Allan bruce.w.al...@intel.com
---
 drivers/crypto/Kconfig  |1 +
 drivers/crypto/Makefile |1 +
 drivers/crypto/qat/qat_common/Makefile  |   13 +
 drivers/crypto/qat/qat_common/adf_accel_devices.h   |  204 
+++
 drivers/crypto/qat/qat_common/adf_accel_engine.c|  168 
 drivers/crypto/qat/qat_common/adf_aer.c |  258 
+++
 drivers/crypto/qat/qat_common/adf_cfg.c |  359 
++
 drivers/crypto/qat/qat_common/adf_cfg.h |   87 +++
 drivers/crypto/qat/qat_common/adf_cfg_common.h  |  100 
 drivers/crypto/qat/qat_common/adf_cfg_strings.h |   83 ++
 drivers/crypto/qat/qat_common/adf_cfg_user.h|   94 +++
 drivers/crypto/qat/qat_common/adf_common_drv.h  |  192 
++
 drivers/crypto/qat/qat_common/adf_ctl_drv.c |  490 
+++
 drivers/crypto/qat/qat_common/adf_dev_mgr.c |  215 

 drivers/crypto/qat/qat_common/adf_init.c|  388 

 drivers/crypto/qat/qat_common/adf_transport.c   |  565 
+
 drivers/crypto/qat/qat_common/adf_transport.h   |   63 +
 drivers/crypto/qat/qat_common/adf_transport_access_macros.h |  160 
 drivers/crypto/qat/qat_common/adf_transport_debug.c |  301 
++
 drivers/crypto/qat/qat_common/adf_transport_internal.h  |  115 +
 drivers/crypto/qat/qat_common/icp_qat_fw.h  |  316 
+++
 drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h   |  131 ++
 drivers/crypto/qat/qat_common/icp_qat_fw_la.h   |  403 
+
 drivers/crypto/qat/qat_common/icp_qat_fw_loader_handle.h|   78 ++
 drivers/crypto/qat/qat_common/icp_qat_hal.h |  125 +
 drivers/crypto/qat/qat_common/icp_qat_hw.h  |  305 
++
 drivers/crypto/qat/qat_common/icp_qat_uclo.h|  377 
+++
 drivers/crypto/qat/qat_common/qat_algs.c| 1033 
++
 drivers/crypto/qat/qat_common/qat_crypto.c  |  284 
+
 drivers/crypto/qat/qat_common/qat_crypto.h  |   83 ++
 drivers/crypto/qat/qat_common/qat_hal.c | 1402 
+
 drivers/crypto/qat/qat_common/qat_uclo.c| 1191 
+
 drivers/crypto/qat/qat_dh895xcc/Makefile|8 +
 drivers/crypto/qat/qat_dh895xcc/adf_admin.c |  144 +++
 drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c  |  214 

 drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.h  |   86 +++
 drivers/crypto/qat/qat_dh895xcc/adf_drv.c   |  448 

 drivers/crypto/qat/qat_dh895xcc/adf_drv.h   |   67 +
 drivers/crypto/qat/qat_dh895xcc/adf_hw_arbiter.c|  159 
 drivers/crypto/qat/qat_dh895xcc/adf_isr.c   |  266 
+++
 drivers/crypto/qat/qat_dh895xcc/qat_admin.c |  107 
 firmware/Makefile   |1 +
 44 files changed, 11092 insertions(+)
 create mode 100644 drivers/crypto/qat/qat_common/Makefile
 create mode 100644 drivers/crypto/qat/qat_common/adf_accel_devices.h
 create mode 100644 drivers/crypto/qat/qat_common/adf_accel_engine.c

Re: [RFC][PATCH 4/4] crypto: Updated makefiles to add QAT

2014-06-03 Thread Tadeusz Struk
On 06/03/2014 12:16 PM, Randy Dunlap wrote:
 +source drivers/crypto/qat/Kconfig
 Missing that file ^^^


Hi,
Something went wrong. I need to resend v2.
Thanks Randy

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


[PATCH RFC 1/2] crypto: Simple crypto algorithm load balancer

2014-01-17 Thread Tadeusz Struk
Hi,
In case of multiple crypto devices implementing the same algorithms
the arbitration, which one to use is based on the cra_priority.
Currently the algorithm with the highest priority is always be used.
In case of two algorithms with the same priority the one added last is used.
There is no load balancing and on a busy system there can be a situation when
there more crypto accelerators, but only one is used for all crypto jobs
and the others sit idle.
This patch implements a simple load balancing based on the priority
of an algorithm and its usage refctr. The distribution for 10 algorithms
and 300 tfm_alloc allocations is as follows:

 === Algorithm load balancig test results for 300 allocatoins ===
 All different alg priorities:
 Algorithm 1 with cra_pri 1 allocated 3 times. That's ~0%
 Algorithm 2 with cra_pri 2 allocated 10 times. That's ~0%
 Algorithm 3 with cra_pri 3 allocated 38 times. That's ~0%
 Algorithm 4 with cra_pri 4 allocated 168 times. That's ~0%
 Algorithm 5 with cra_pri 5 allocated 781 times. That's ~0%
 Algorithm 6 with cra_pri 6 allocated 3757 times. That's ~0%
 Algorithm 7 with cra_pri 7 allocated 18483 times. That's ~0%
 Algorithm 8 with cra_pri 8 allocated 92540 times. That's ~3%
 Algorithm 9 with cra_pri 9 allocated 469918 times. That's ~15%
 Algorithm 10 with cra_pri 10 allocated 2414312 times. That's ~80%

 All the same alg priorities:
 Algorithm 1 with cra_pri 10 allocated 297521 times. That's ~9%
 Algorithm 2 with cra_pri 10 allocated 297521 times. That's ~9%
 Algorithm 3 with cra_pri 10 allocated 297521 times. That's ~9%
 Algorithm 4 with cra_pri 10 allocated 297522 times. That's ~9%
 Algorithm 5 with cra_pri 10 allocated 297522 times. That's ~9%
 Algorithm 6 with cra_pri 10 allocated 297522 times. That's ~9%
 Algorithm 7 with cra_pri 10 allocated 297522 times. That's ~9%
 Algorithm 8 with cra_pri 10 allocated 297522 times. That's ~9%
 Algorithm 9 with cra_pri 10 allocated 297522 times. That's ~9%
 Algorithm 10 with cra_pri 10 allocated 297522 times. That's ~9%

 A mix of alg priorities:
 Algorithm 1 with cra_pri 9 allocated 1938 times. That's ~0%
 Algorithm 2 with cra_pri 4 allocated 8 times. That's ~0%
 Algorithm 3 with cra_pri 1 allocated 2 times. That's ~0%
 Algorithm 4 with cra_pri 4 allocated 9 times. That's ~0%
 Algorithm 5 with cra_pri 5 allocated 62 times. That's ~0%
 Algorithm 6 with cra_pri 20 allocated 157052 times. That's ~5%
 Algorithm 7 with cra_pri 21 allocated 1410070 times. That's ~47%
 Algorithm 8 with cra_pri 10 allocated 10215 times. That's ~0%
 Algorithm 9 with cra_pri 21 allocated 1420284 times. That's ~47%
 Algorithm 10 with cra_pri 7 allocated 370 times. That's ~0%

 A mix of alg priorities with one very big:
 Algorithm 1 with cra_pri 9 allocated 6 times. That's ~0%
 Algorithm 2 with cra_pri 4 allocated 1 times. That's ~0%
 Algorithm 3 with cra_pri 1 allocated 1 times. That's ~0%
 Algorithm 4 with cra_pri 4 allocated 1 times. That's ~0%
 Algorithm 5 with cra_pri 500 allocated 2993808 times. That's ~99%
 Algorithm 6 with cra_pri 20 allocated 346 times. That's ~0%
 Algorithm 7 with cra_pri 21 allocated 2899 times. That's ~0%
 Algorithm 8 with cra_pri 10 allocated 23 times. That's ~0%
 Algorithm 9 with cra_pri 21 allocated 2922 times. That's ~0%
 Algorithm 10 with cra_pri 7 allocated 3 times. That's ~0%

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/api.c   |   25 ++---
 include/linux/crypto.h |3 ++-
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/crypto/api.c b/crypto/api.c
index a2b39c5..0c0f1c3 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -63,7 +63,7 @@ static struct crypto_alg *__crypto_alg_lookup(const char 
*name, u32 type,
int best = -2;
 
list_for_each_entry(q, crypto_alg_list, cra_list) {
-   int exact, fuzzy;
+   int exact, fuzzy, relative_priority;
 
if (crypto_is_moribund(q))
continue;
@@ -78,13 +78,15 @@ static struct crypto_alg *__crypto_alg_lookup(const char 
*name, u32 type,
 
exact = !strcmp(q-cra_driver_name, name);
fuzzy = !strcmp(q-cra_name, name);
-   if (!exact  !(fuzzy  q-cra_priority  best))
+   relative_priority = q-cra_priority -
+   atomic_read(q-cra_lbalance);
+   if (!exact  !(fuzzy  relative_priority  best))
continue;
 
if (unlikely(!crypto_mod_get(q)))
continue;
 
-   best = q-cra_priority;
+   best = relative_priority;
if (alg)
crypto_mod_put(alg);
alg = q;
@@ -92,6 +94,23 @@ static struct crypto_alg *__crypto_alg_lookup(const char 
*name, u32 type,
if (exact)
break;
}
+   if (!alg) {
+   list_for_each_entry(q, crypto_alg_list, cra_list

[PATCH RFC 2/2] crypto: Simple load balancer test module

2014-01-17 Thread Tadeusz Struk
Test module for the simple algorithm load balancer

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/Kconfig|6 ++
 crypto/Makefile   |1 +
 crypto/test_alg_loadbalance.c |  231 +
 3 files changed, 247 insertions(+)
 create mode 100644 crypto/test_alg_loadbalance.c

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 7bcb70d..85e1bc2 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -1404,6 +1404,12 @@ config CRYPTO_USER_API_SKCIPHER
 config CRYPTO_HASH_INFO
bool
 
+config CRYPTO_ALG_LOAD_BALANCE_TEST
+   tristate Crypto Algorithm load balancer test module
+   default n
+   help
+ This option enables the crypto algorithm load balancer test module.
+
 source drivers/crypto/Kconfig
 source crypto/asymmetric_keys/Kconfig
 
diff --git a/crypto/Makefile b/crypto/Makefile
index b29402a..5a49e2a 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -97,6 +97,7 @@ obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o
 obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o
 obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o
 obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o
+obj-$(CONFIG_CRYPTO_ALG_LOAD_BALANCE_TEST) += test_alg_loadbalance.o
 
 #
 # generic algorithms and the async_tx api
diff --git a/crypto/test_alg_loadbalance.c b/crypto/test_alg_loadbalance.c
new file mode 100644
index 000..2637247
--- /dev/null
+++ b/crypto/test_alg_loadbalance.c
@@ -0,0 +1,231 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#include linux/err.h
+#include linux/module.h
+#include linux/crypto.h
+#include linux/string.h
+#include crypto/algapi.h
+
+static int encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+   struct scatterlist *src, unsigned int nbytes)
+{
+   return 0;
+}
+static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
+{
+   return 0;
+}
+
+
+#define loops 300
+static struct crypto_ablkcipher *tfms[loops];
+
+static struct crypto_alg tmp = {
+   .cra_name   = test,
+   .cra_driver_name= test_driver,
+   .cra_priority   = 1,
+   .cra_flags  = CRYPTO_ALG_TYPE_ABLKCIPHER,
+   .cra_module = THIS_MODULE,
+   .cra_ctxsize= 0,
+   .cra_type   = crypto_blkcipher_type,
+   .cra_u = {
+   .blkcipher = {
+   .min_keysize= 64,
+   .max_keysize= 64,
+   .ivsize = 64,
+   .setkey = setkey,
+   .encrypt= encrypt,
+   .decrypt= encrypt,
+   },
+   },
+   };
+static struct crypto_alg algs[10] = {
+   { { 0 } },
+   { { 0 } },
+   { { 0 } },
+   { { 0 } },
+   { { 0 } },
+   { { 0 } },
+   { { 0 } },
+   { { 0 } },
+   { { 0 } },
+   { { 0 } },
+};
+
+static int __init cra_lbtest_init(void)
+{
+   int i;
+
+   for (i = 0; i  10; i++) {
+   algs[i] = tmp;
+   algs[i].cra_priority += i;
+   }
+
+   if (crypto_register_algs(algs, 10))
+   return -1;
+
+   for (i = 0; i  loops; i++) {
+   tfms[i] = crypto_alloc_ablkcipher(test, 0, 0);
+   if (IS_ERR(tfms[i]))
+   return PTR_ERR(tfms[i]);
+   }
+   pr_info(Algorithm load balancig test results for %d allocatoins\n,
+   loops);
+   pr_info(All different alg priorities:\n);
+   for (i = 0; i  10; i++) {
+   unsigned long times = atomic_read(algs[i].cra_refcnt);
+   unsigned long percent = (times * 100) / loops;
+
+   pr_info(Alg with cra_pri %d allocated %lu times. That's 
~%lu%%\n,
+   algs[i].cra_priority, times, percent);
+
+   }
+   for (i = 0; i  loops; i++)
+   crypto_free_ablkcipher(tfms[i]);
+
+   crypto_unregister_algs(algs, 10);
+
+   for (i = 0; i  10; i++) {
+   algs[i] = tmp;
+   algs[i].cra_priority = 10;
+   }
+   if (crypto_register_algs(algs, 10))
+   return -1;
+
+   for (i = 0; i  loops; i++) {
+   tfms[i] = crypto_alloc_ablkcipher(test, 0, 0);
+   if (IS_ERR(tfms[i]))
+   return PTR_ERR(tfms[i]);
+   }
+   pr_info(All same alg priorities:\n);
+   for (i = 0; i  10; i++) {
+   unsigned long times = atomic_read(algs[i].cra_refcnt

Re: [PATCH v4 6/7] sched: add function nr_running_cpu to expose number of tasks running on cpu

2014-07-12 Thread Tadeusz Struk
On 07/11/2014 01:33 PM, Tim Chen wrote:
 +unsigned long nr_running_cpu(int cpu)
 +{
 + if (cpumask_test_cpu(cpu, cpu_online_mask))
 + return cpu_rq(cpu)-nr_running;
 + else
 + return 0;
 +}
 +
EXPORT_SYMBOL?
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] firmware: Automatically pull missing FW files

2014-08-20 Thread Tadeusz Struk
Hi,
When a binary FW file is not present in the firmware dir then the build
will fail. This patch enables auto-download any missing FW file for both shipped
and external targets.
Generated against linux-next.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 firmware/Makefile |   25 +++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/firmware/Makefile b/firmware/Makefile
index 5747417..3ad12f6 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -178,10 +178,31 @@ wordsize_deps := $(wildcard include/config/64bit.h 
include/config/32bit.h \
include/config/superh32.h include/config/superh64.h \
include/config/x86_32.h include/config/x86_64.h)
 
-$(patsubst %,$(obj)/%.gen.S, $(fw-shipped-y)): %: $(wordsize_deps)
+FW_URL := 
git.kernel.org/cgit/linux/kernel/git/firmware/linux-firmware.git/plain
+
+.NOTPARALLEL: get_missing_external $(patsubst %,$(obj)/%.gen.S, 
$(fw-external-y))
+.NOTPARALLEL: get_missing_shipped $(patsubst %,$(obj)/%.gen.S, $(fw-shipped-y))
+
+get_missing_shipped:
+   @for file in $(fw-shipped-y) $(fw-shipped-m); do \
+   if [ ! -f $(obj)/$$file ]; then \
+   wget $(FW_URL)/$$file -o /dev/null -O $(obj)/$$file; \
+   fi; \
+   done;
+
+get_missing_external:
+   @for file in $(fw-external-y); do \
+   if [ ! -f $(obj)/$$file ]; then \
+   wget $(FW_URL)/$$file -o /dev/null -O $(obj)/$$file; \
+   fi; \
+   done;
+
+$(patsubst %,$(obj)/%.gen.S, $(fw-shipped-y)): %: $(wordsize_deps) \
+   get_missing_shipped
$(call cmd,fwbin,$(patsubst %.gen.S,%,$@))
+
 $(patsubst %,$(obj)/%.gen.S, $(fw-external-y)): %: $(wordsize_deps) \
-   include/config/extra/firmware/dir.h
+   include/config/extra/firmware/dir.h get_missing_external
$(call cmd,fwbin,$(fwabs)/$(patsubst $(obj)/%.gen.S,%,$@))
 
 # The .o files depend on the binaries directly; the .S files don't.

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


Re: [PATCH] firmware: Automatically pull missing FW files

2014-08-20 Thread Tadeusz Struk
Hi David,
On 08/20/2014 11:34 AM, David Woodhouse wrote:
 I'm not sure I understand. Precisely what fails?

I clone a subsystem, configure it to use
CONFIG_EXTRA_FIRMWARE=qat_895xcc.bin, type make  make install and get:

MK_FW   firmware/qat_895xxc.bin.gen.S
make[1]: *** No rule to make target `firmware/qat_895xxc.bin', needed by
`firmware/qat_895xxc.bin.gen.o'.  Stop.

I thought it might be useful if it would pull whatever FW it needs and
not just give up. It also might be useful if one wants to refresh the
FW binaries. In this case one can do rm firmware/*.[bin|ihex]  make 
make install

 
 I don't like this patch very much. We should be removing the legacy
 firmware/ directory entirely, not patching it up.
 
 Userspace is responsible for providing the firmware, and it should
 generally come from an entirely separate checkout of the linux-firmware
 repository.

Yes, if you use udev helper. When you want to compile in the blobs to
your kernel it is needed in build time, right?
In both cases you need the binary anyway so you can copy it manually
from linux-firmware or use this nice feature to do it for you.
If you want to remove firmware/ directory entirely then this makefile
will be gone as well so what's the problem?

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


Re: [PATCH] firmware: Automatically pull missing FW files

2014-08-20 Thread Tadeusz Struk
On 08/20/2014 01:39 PM, David Woodhouse wrote:
 On Wed, 2014-08-20 at 12:21 -0700, Tadeusz Struk wrote:
 Hi David,
 On 08/20/2014 11:34 AM, David Woodhouse wrote:
 I'm not sure I understand. Precisely what fails?

 I clone a subsystem, configure it to use
 CONFIG_EXTRA_FIRMWARE=qat_895xcc.bin, type make  make install and get:

 MK_FW   firmware/qat_895xxc.bin.gen.S
 make[1]: *** No rule to make target `firmware/qat_895xxc.bin', needed by
 `firmware/qat_895xxc.bin.gen.o'.  Stop.
 
 Can't you already just use CONFIG_EXTRA_FIRMWARE_DIR ? 


What for? The point is that you don't have the FW binary file and you
have to download it, which can happen automatically and this is what
this patch does. The director where it will be stored doesn't really
matter here.

 
 Yes, if you use udev helper. When you want to compile in the blobs to
 your kernel it is needed in build time, right?
 
 Yes. But seriously: don't do that. Let firmware get loaded from
 userspace the normal way. Don't build kernel images that you can't distribute
 because they include non-GPL parts.
 

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


Re: [PATCH] crypto, qat, use generic numa functions

2014-10-08 Thread Tadeusz Struk
Hi Prarit,
On 10/07/2014 05:12 PM, Prarit Bhargava wrote:
 The method in which the qat code determines the numa node for memory
 allocations is a bit clunky.  On 2 socket, single node systems it is
 possible that adf_get_dev_node_id() returns node 1, even though node 1
 doesn't exist.
 
 This code transitions the qat code to the generic numa functions.
 Changing adf_get_dev_node_id() to a simple call to dev_get_node() results
 in a change to the adf_accel_dev struct as well.

The problem with that is we don't want to use any valid numa node, but
the node we are connected to or we don't want to use the accelerator at
all. Otherwise, when the first valid numa node happens to be the remote
node the dma transactions we be slow and instead of accelerating we will
slow things down.
A patch that enforces this is on it's way.

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


Re: [PATCH v2 01/11] crypto: Documentation - crypto API high level spec

2014-11-05 Thread Tadeusz Struk
Hi,
On 11/02/2014 12:35 PM, Stephan Mueller wrote:
 + * type:
 + - blkcipher for symmetric block ciphers

blkcipher for synchronous block ciphers

 + - ablkcipher for asymmetric block ciphers

ablkcipher for asynchronous block ciphers

 + - cipher for single block ciphers that may be used with an
 +   additional template
 + - shash for symmetric message digest

shash for synchronous message digest

 + - ahash for asymmetric message digest

ahash for asynchronous message digest

T.

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


Re: [PATCH 0/3] crypto: algif - change algif_skcipher to be asynchronous

2015-02-02 Thread Tadeusz Struk
On 02/01/2015 10:31 AM, Stephan Mueller wrote:
 Hi Tadeusz,
 
  The way the algif_skcipher works currently is that on sendmsg/sendpage it
  builds an sgl for the input data and then on read/recvmsg it sends the job
  for encryption putting the user to sleep till the data is processed.
  This way it can only handle one job at a given time.
  To be able to fuly utilize the potential of existing crypto hardware
  accelerators it is required to submit multiple jobs in asynchronously.
  First patch enables asynchronous read and write on socket.
  Second patch enables af_alg sgl to be linked.
  Third patch implement asynch read for skcipher.
 Do you have a code fragment on how to test that patch? I would like to see 
 whether I can test that with my libkcapi.

Hi Stephan,
This is what I'm using.

#include unistd.h
#include fcntl.h
#include stdio.h
#include errno.h
#include string.h
#include sys/socket.h
#include sys/types.h
#include linux/types.h
#include linux/aio_abi.h
#include sys/syscall.h
#include sys/uio.h

#define SOL_ALG 279

#define SPLICE_F_GIFT   (0x08)  /* pages passed in are a gift */
struct sockaddr_alg {
__u16   salg_family;
__u8salg_type[14];
__u32   salg_feat;
__u32   salg_mask;
__u8salg_name[64];
};
struct af_alg_iv {
__u32   ivlen;
__u8iv[0];
};
/* Socket options */
#define ALG_SET_KEY 1
#define ALG_SET_IV  2
#define ALG_SET_OP  3
#define ALG_SET_AEAD_ASSOCLEN   4
#define ALG_SET_AEAD_AUTHSIZE   5

/* Operations */
#define ALG_OP_DECRYPT  0
#define ALG_OP_ENCRYPT  1

#define BUFFSIZE (4096)
//#define BUFFSIZE (4096)
#define PKGSIZE (4096)

#define INFLIGTHS 256
#define TO_SEND (1024 * 1024)
//#define OUT_OFFSET 2048;
//#define IN_OFFSET 4064;
#define OUT_OFFSET 0;
#define IN_OFFSET 0;

static char buf[BUFFSIZE] __attribute__((__aligned__(BUFFSIZE)));
static char *buf_out = buf;

static inline int io_setup(unsigned n, aio_context_t *ctx)
{
return syscall(__NR_io_setup, n, ctx);
}

static inline int io_destroy(aio_context_t ctx)
{
return syscall(__NR_io_destroy, ctx);
}

static inline int io_read(aio_context_t ctx, long n,  struct iocb **iocb)
{
return syscall(__NR_io_submit, ctx, n, iocb);
}

static inline int io_getevents(aio_context_t ctx, long min, long max,
struct io_event *events, struct timespec *timeout)
{
return syscall(__NR_io_getevents, ctx, min, max, events, timeout);
}

static inline int eventfd(int n)
{
return syscall(__NR_eventfd, n);
}

static int crypt_kernel(const char *key, char *oiv, int zcp)
{
int opfd;
int tfmfd;
int efd;
struct timespec timeout;
fd_set rfds;
struct timeval tv;
struct sockaddr_alg sa = {
.salg_family = AF_ALG,
.salg_type = skcipher,
.salg_name = cbc(aes)
};
struct msghdr msg = {};
struct cmsghdr *cmsg;
char cbuf[CMSG_SPACE(4) + CMSG_SPACE(20)] = {};
struct aes_iv {
__u32 len;
__u8 iv[16];
} *iv;
struct iovec iov;
int pipes[2];
aio_context_t aio_ctx;
struct iocb *cb;
struct iocb cbt[INFLIGTHS];
struct io_event events[INFLIGTHS];
unsigned int received = 0;
int i, r;

timeout.tv_sec = 0;
timeout.tv_nsec = 0;
pipe(pipes);
memset(cbt, 0, sizeof(cbt));
efd = eventfd(0);
tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
bind(tfmfd, (struct sockaddr *)sa, sizeof(sa));
setsockopt(tfmfd, SOL_ALG, ALG_SET_KEY, key, 16);
opfd = accept(tfmfd, NULL, 0);

msg.msg_control = cbuf;
msg.msg_controllen = sizeof(cbuf);

cmsg = CMSG_FIRSTHDR(msg);
cmsg-cmsg_level = SOL_ALG;
cmsg-cmsg_type = ALG_SET_OP;
cmsg-cmsg_len = CMSG_LEN(4);
*(__u32 *)CMSG_DATA(cmsg) = ALG_OP_ENCRYPT;

cmsg = CMSG_NXTHDR(msg, cmsg);
cmsg-cmsg_level = SOL_ALG;
cmsg-cmsg_type = ALG_SET_IV;
cmsg-cmsg_len = CMSG_LEN(20);
iv = (void *)CMSG_DATA(cmsg);
iv-len = 16;
memcpy(iv-iv, oiv, 16);

iov.iov_base = buf + IN_OFFSET;
iov.iov_len = PKGSIZE;
msg.msg_flags = MSG_MORE;

aio_ctx = 0;
r = io_setup(INFLIGTHS, aio_ctx);
if (r  0) {
perror(io_setup error);
return -1;
}

for (i = 0; i  TO_SEND; i++) {
if (zcp) {
msg.msg_iovlen = 0;
msg.msg_iov = NULL;

r = sendmsg(opfd, msg, 0);
if (r  0)
printf(sendmsg returned Error: %d\n, errno);

r = vmsplice(pipes[1], iov, 1, SPLICE_F_GIFT);
if 

Re: [PATCH] crypto: aesni: add setkey for driver-gcm-aes-aesni

2015-01-19 Thread Tadeusz Struk
On 01/18/2015 02:56 PM, Stephan Mueller wrote:
 The cipher registered as __driver-gcm-aes-aesni is never intended
 to be used directly by any caller. Instead it is a service mechanism to
 rfc4106-gcm-aesni.
 
 The kernel crypto API unconditionally calls the registered setkey
 function. In case a caller erroneously uses __driver-gcm-aes-aesni a
 call to crypto_aead_setkey will cause a NULL pointer dereference without
 this patch.

Acked-by: Tadeusz Struk tadeusz.st...@intel.com
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Intel GCM: __driver-gcm-aes-aesni setkey missing

2015-01-17 Thread Tadeusz Struk
Hi Stephan,
On 01/17/2015 10:23 AM, Stephan Mueller wrote:
 during testing of my algif_aead patch with the different GCM implementations 
 I 
 am able to trigger a kernel crash from user space using __driver-gcm-aes-
 aesni.
 
 As I hope that algif_aead is going to be included, unprivileged userspace 
 would then reliably crash the kernel -- with the current kernel code, 
 userspace has no interface to trigger the issue.

Yes, that's a problem.

 
 As I am not sure what the purpose of __driver-gcm-aes-aesni is (only a 
 backend 
 for RFC4106 GCM or a regular cipher), I did not yet create a patch. IMHO 
 there 
 are two solutions:
 
 - either create a valid setkey callback so that a key is set
 
 - or create a noop setkey that returns -EOPNOTSUPP which effectively disables 
 that cipher for regular consumption.

__driver-gcm-aes-aesni is only a helper for rfc4106-gcm-aesni and it
never supposed to be used on it's own. I think implementing a setkey
function that only returns an error would be a good solution for this.
Another question is what if someone will ignore the error or skip the
setsockopt(ALG_SET_KEY) altogether and still call the sendmsg() and
read() to trigger encrypt()?

 Note, if it is only a backend for the RFC4106 implementation, may I ask why 
 __driver-gcm-aes-aesni is implemented as a separate cipher that is registered 
 with the kernel crypto API?

This is because we need to have one instance of the helper tfm with its
context per each of the rfc4106-gcm-aesni tfm instance and that was one
convenient way to do this.

Tadeusz
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] crypto: aesni: add setkey for driver-gcm-aes-aesni

2015-01-22 Thread Tadeusz Struk
On 01/22/2015 01:20 PM, Stephan Mueller wrote:
 That would be correct. But if I understood Herbert correctly, he is 
 creating a patch that disables these service ciphers for general usage.

Yes, and this should also implicitly fix the problem with user space.
Thanks,
Tadeusz
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] crypto: aesni: add setkey for driver-gcm-aes-aesni

2015-01-22 Thread Tadeusz Struk
On 01/22/2015 02:23 PM, Herbert Xu wrote:
 Yes but we should also fix this so that it's a proper aead
 algorithm.
Ok, I'll do that.
Thanks,
Tadeusz
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] crypto: aesni: add setkey for driver-gcm-aes-aesni

2015-01-22 Thread Tadeusz Struk
On 01/20/2015 05:25 PM, Stephan Mueller wrote:
 Rather than adding a bogus setkey function, please fix this mess
 properly by moving the top-level setkey function into the __driver
 one where it should be.  Compare with how we handle it in the
 ablk_helper which is pretty much the same thing.
 
 Tadeusz, are you working on that update or shall I have a look?
 
Hi,
No, I thought that the agreement was that we don't want to allow user
space to use these helpers directly, right? Am I missing something?
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/3] net: socket: enable async read and write

2015-01-30 Thread Tadeusz Struk
On 01/29/2015 03:13 PM, Tadeusz Struk wrote:
 AIO read or write are not currently supported on sockets.
 This patch enables real socket async read/write.
 
 Please note - this patch is generated against cryptodev.
 
 Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
 ---
  include/net/sock.h |2 ++
  net/socket.c   |   48 ++--
  2 files changed, 40 insertions(+), 10 deletions(-)
 
 diff --git a/include/net/sock.h b/include/net/sock.h
 index 2210fec..2c7d160 100644
 --- a/include/net/sock.h
 +++ b/include/net/sock.h
 @@ -1397,6 +1397,8 @@ static inline struct kiocb *siocb_to_kiocb(struct 
 sock_iocb *si)
   return si-kiocb;
  }
  
 +void sock_aio_complete(struct kiocb *iocb, long res, long res2);
 +
  struct socket_alloc {
   struct socket socket;
   struct inode vfs_inode;
 diff --git a/net/socket.c b/net/socket.c
 index a2c33a4..368fa9f 100644
 --- a/net/socket.c
 +++ b/net/socket.c
 @@ -866,14 +866,25 @@ static ssize_t sock_splice_read(struct file *file, 
 loff_t *ppos,
   return sock-ops-splice_read(sock, ppos, pipe, len, flags);
  }
  
 +void sock_aio_complete(struct kiocb *iocb, long res, long res2)
 +{
 + struct sock_iocb *siocb = kiocb_to_siocb(iocb);
 +
 + kfree(siocb);
 + aio_complete(iocb, res, res2);
 +}
 +EXPORT_SYMBOL(sock_aio_complete);
 +
  static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb,
struct sock_iocb *siocb)
  {
 - if (!is_sync_kiocb(iocb))
 - BUG();
 + if (!siocb)
 + siocb = kmalloc(sizeof(*siocb), GFP_KERNEL);
  
 - siocb-kiocb = iocb;
 - iocb-private = siocb;
 + if (siocb) {
 + siocb-kiocb = iocb;
 + iocb-private = siocb;
 + }
   return siocb;
  }
  
 @@ -901,7 +912,8 @@ static ssize_t do_sock_read(struct msghdr *msg, struct 
 kiocb *iocb,
  static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
   unsigned long nr_segs, loff_t pos)
  {
 - struct sock_iocb siocb, *x;
 + struct sock_iocb siocb, *x = NULL;
 + int ret;
  
   if (pos != 0)
   return -ESPIPE;
 @@ -909,11 +921,18 @@ static ssize_t sock_aio_read(struct kiocb *iocb, const 
 struct iovec *iov,
   if (iocb-ki_nbytes == 0)   /* Match SYS5 behaviour */
   return 0;
  
 + if (is_sync_kiocb(iocb))
 + x = siocb;
  
 - x = alloc_sock_iocb(iocb, siocb);
 + x = alloc_sock_iocb(iocb, x);
   if (!x)
   return -ENOMEM;
 - return do_sock_read(x-async_msg, iocb, iocb-ki_filp, iov, nr_segs);
 + ret = do_sock_read(x-async_msg, iocb, iocb-ki_filp, iov, nr_segs);
 +
 + if (!is_sync_kiocb(iocb)  ret != -EIOCBQUEUED)
 + kfree(x);
 +
 + return ret;
  }
  
  static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb,
 @@ -942,16 +961,25 @@ static ssize_t do_sock_write(struct msghdr *msg, struct 
 kiocb *iocb,
  static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov,
 unsigned long nr_segs, loff_t pos)
  {
 - struct sock_iocb siocb, *x;
 + struct sock_iocb siocb, *x = NULL;
 + int ret;
  
   if (pos != 0)
   return -ESPIPE;
  
 - x = alloc_sock_iocb(iocb, siocb);
 + if (is_sync_kiocb(iocb))
 + x = siocb;
 +
 + x = alloc_sock_iocb(iocb, x);
   if (!x)
   return -ENOMEM;
  
 - return do_sock_write(x-async_msg, iocb, iocb-ki_filp, iov, nr_segs);
 + ret = do_sock_write(x-async_msg, iocb, iocb-ki_filp, iov, nr_segs);
 +
 + if (!is_sync_kiocb(iocb)  ret != -EIOCBQUEUED)
 + kfree(x);
 +
 + return ret;
  }
  
  /*

Hi Herbert,
Just noticed that the struct sock_iocb has just been removed on net-next
(see [1]). What we can do is to call aio_complete() directly from
algif_skcipher, assuming that it is ok to call asynchronous read or
write with the struct msghdr allocated on the stack.
Please let me know what you think.
Thanks,
Tadeusz

[1]
https://git.kernel.org/cgit/linux/kernel/git/davem/net-next.git/commit/?id=7cc05662682da4b0e0a4fdf3c3f190577803ae81



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


Re: linux-next: build warnings after merge of the crypto tree

2015-03-10 Thread Tadeusz Struk
On 03/09/2015 11:03 PM, Herbert Xu wrote:
 This is a bit of a bummer.  What happened is that net-next has
 killed the kiocb argument to sendmsg/recvmsg.  However, this
 change is obviously not part of the crypto tree and algif_aead
 only exists in the crypto tree.
 
 So Stephen could you fix this by hand until one of them is merged
 upstream (just kill the first argument in aead_sendmsg/aead_recvmsg)?

So does it mean that aio operations will not be supported on sockets?
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v12 1/2] crypto: AF_ALG: add AEAD support

2015-02-27 Thread Tadeusz Struk
On 02/27/2015 02:26 AM, Stephan Mueller wrote:
 This patch adds the AEAD support for AF_ALG.
   
   The implementation is based on algif_skcipher, but contains heavy
   modifications to streamline the interface for AEAD uses.
   
   To use AEAD, the user space consumer has to use the salg_type named
   aead.
  
  I just saw Al Viro's patch to use the iov_iter API in
  algif_skcipher.c. I looked at it but lacked documentation for using
  it properly. Now I have a template that I will incorporate into
  algif_aead.c
 
 Please resubmit once you have done this.
 I have done that, but as indicated with an email to Al, I cannot get his 
 patch for skcipher and hash to work. Similarly, my modification for the 
 AEAD does not work either. So, I do not see that Al's patch can be 
 merged as is.
 
 Therefore, I have not submitted my patch as Al mentioned he wanted to 
 look into his patchset.

Hi Stephan,
There was a problem with the iov_iter changes, but it has been fixed on netdev 
during merging window.
The algif_skcipher works fine for me on the latest (4.0.0-rc1+) cryptodev.

Regards,
Tadeusz
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/3] crypto: af_alg - Allow to link sgl

2015-01-29 Thread Tadeusz Struk
Allow to link af_alg sgls.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/af_alg.c |   16 
 include/crypto/if_alg.h |4 +++-
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index 76d739d..99608f2 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -374,7 +374,8 @@ int af_alg_make_sg(struct af_alg_sgl *sgl, void __user 
*addr, int len,
 
err = 0;
 
-   sg_init_table(sgl-sg, npages);
+   /* Add one extra for linking */
+   sg_init_table(sgl-sg, npages + 1);
 
for (i = 0; i  npages; i++) {
int plen = min_t(int, len, PAGE_SIZE - off);
@@ -385,20 +386,27 @@ int af_alg_make_sg(struct af_alg_sgl *sgl, void __user 
*addr, int len,
len -= plen;
err += plen;
}
+   sg_mark_end(sgl-sg + npages - 1);
+   sgl-npages = npages;
 
 out:
return err;
 }
 EXPORT_SYMBOL_GPL(af_alg_make_sg);
 
+void af_alg_link_sg(struct af_alg_sgl *sgl_prev, struct af_alg_sgl *sgl_new)
+{
+   sg_unmark_end(sgl_prev-sg + sgl_prev-npages - 1);
+   sg_chain(sgl_prev-sg, sgl_prev-npages + 1, sgl_new-sg);
+}
+EXPORT_SYMBOL(af_alg_link_sg);
+
 void af_alg_free_sg(struct af_alg_sgl *sgl)
 {
int i;
 
-   i = 0;
-   do {
+   for (i = 0; i  sgl-npages; i++)
put_page(sgl-pages[i]);
-   } while (!sg_is_last(sgl-sg + (i++)));
 }
 EXPORT_SYMBOL_GPL(af_alg_free_sg);
 
diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h
index 5c7b6c5..0908050 100644
--- a/include/crypto/if_alg.h
+++ b/include/crypto/if_alg.h
@@ -58,8 +58,9 @@ struct af_alg_type {
 };
 
 struct af_alg_sgl {
-   struct scatterlist sg[ALG_MAX_PAGES];
+   struct scatterlist sg[ALG_MAX_PAGES + 1];
struct page *pages[ALG_MAX_PAGES];
+   unsigned int npages;
 };
 
 int af_alg_register_type(const struct af_alg_type *type);
@@ -71,6 +72,7 @@ int af_alg_accept(struct sock *sk, struct socket *newsock);
 int af_alg_make_sg(struct af_alg_sgl *sgl, void __user *addr, int len,
   int write);
 void af_alg_free_sg(struct af_alg_sgl *sgl);
+void af_alg_link_sg(struct af_alg_sgl *sgl_prev, struct af_alg_sgl *sgl_new);
 
 int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con);
 

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


[PATCH 0/3] crypto: algif - change algif_skcipher to be asynchronous

2015-01-29 Thread Tadeusz Struk
The way the algif_skcipher works currently is that on sendmsg/sendpage it
builds an sgl for the input data and then on read/recvmsg it sends the job
for encryption putting the user to sleep till the data is processed.
This way it can only handle one job at a given time.
To be able to fuly utilize the potential of existing crypto hardware
accelerators it is required to submit multiple jobs in asynchronously.
First patch enables asynchronous read and write on socket.
Second patch enables af_alg sgl to be linked.
Third patch implement asynch read for skcipher.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
Tadeusz Struk (3):
  net: socket: enable async read and write
  crypto: af_alg - Allow to link sgl
  crypto: algif - change algif_skcipher to be asynchronous


 crypto/af_alg.c |   16 ++
 crypto/algif_skcipher.c |  315 ++-
 include/crypto/if_alg.h |4 -
 include/net/sock.h  |2 
 net/socket.c|   48 ++-
 5 files changed, 364 insertions(+), 21 deletions(-)
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/3] net: socket: enable async read and write

2015-01-29 Thread Tadeusz Struk
AIO read or write are not currently supported on sockets.
This patch enables real socket async read/write.

Please note - this patch is generated against cryptodev.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 include/net/sock.h |2 ++
 net/socket.c   |   48 ++--
 2 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/include/net/sock.h b/include/net/sock.h
index 2210fec..2c7d160 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1397,6 +1397,8 @@ static inline struct kiocb *siocb_to_kiocb(struct 
sock_iocb *si)
return si-kiocb;
 }
 
+void sock_aio_complete(struct kiocb *iocb, long res, long res2);
+
 struct socket_alloc {
struct socket socket;
struct inode vfs_inode;
diff --git a/net/socket.c b/net/socket.c
index a2c33a4..368fa9f 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -866,14 +866,25 @@ static ssize_t sock_splice_read(struct file *file, loff_t 
*ppos,
return sock-ops-splice_read(sock, ppos, pipe, len, flags);
 }
 
+void sock_aio_complete(struct kiocb *iocb, long res, long res2)
+{
+   struct sock_iocb *siocb = kiocb_to_siocb(iocb);
+
+   kfree(siocb);
+   aio_complete(iocb, res, res2);
+}
+EXPORT_SYMBOL(sock_aio_complete);
+
 static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb,
 struct sock_iocb *siocb)
 {
-   if (!is_sync_kiocb(iocb))
-   BUG();
+   if (!siocb)
+   siocb = kmalloc(sizeof(*siocb), GFP_KERNEL);
 
-   siocb-kiocb = iocb;
-   iocb-private = siocb;
+   if (siocb) {
+   siocb-kiocb = iocb;
+   iocb-private = siocb;
+   }
return siocb;
 }
 
@@ -901,7 +912,8 @@ static ssize_t do_sock_read(struct msghdr *msg, struct 
kiocb *iocb,
 static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos)
 {
-   struct sock_iocb siocb, *x;
+   struct sock_iocb siocb, *x = NULL;
+   int ret;
 
if (pos != 0)
return -ESPIPE;
@@ -909,11 +921,18 @@ static ssize_t sock_aio_read(struct kiocb *iocb, const 
struct iovec *iov,
if (iocb-ki_nbytes == 0)   /* Match SYS5 behaviour */
return 0;
 
+   if (is_sync_kiocb(iocb))
+   x = siocb;
 
-   x = alloc_sock_iocb(iocb, siocb);
+   x = alloc_sock_iocb(iocb, x);
if (!x)
return -ENOMEM;
-   return do_sock_read(x-async_msg, iocb, iocb-ki_filp, iov, nr_segs);
+   ret = do_sock_read(x-async_msg, iocb, iocb-ki_filp, iov, nr_segs);
+
+   if (!is_sync_kiocb(iocb)  ret != -EIOCBQUEUED)
+   kfree(x);
+
+   return ret;
 }
 
 static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb,
@@ -942,16 +961,25 @@ static ssize_t do_sock_write(struct msghdr *msg, struct 
kiocb *iocb,
 static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov,
  unsigned long nr_segs, loff_t pos)
 {
-   struct sock_iocb siocb, *x;
+   struct sock_iocb siocb, *x = NULL;
+   int ret;
 
if (pos != 0)
return -ESPIPE;
 
-   x = alloc_sock_iocb(iocb, siocb);
+   if (is_sync_kiocb(iocb))
+   x = siocb;
+
+   x = alloc_sock_iocb(iocb, x);
if (!x)
return -ENOMEM;
 
-   return do_sock_write(x-async_msg, iocb, iocb-ki_filp, iov, nr_segs);
+   ret = do_sock_write(x-async_msg, iocb, iocb-ki_filp, iov, nr_segs);
+
+   if (!is_sync_kiocb(iocb)  ret != -EIOCBQUEUED)
+   kfree(x);
+
+   return ret;
 }
 
 /*

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


[PATCH 3/3] crypto: algif - change algif_skcipher to be asynchronous

2015-01-29 Thread Tadeusz Struk
The way the algif_skcipher works currently is that on sendmsg/sendpage it
builds an sgl for the input data and then on read/recvmsg it sends the job
for encryption putting the user to sleep till the data is processed.
This way it can only handle one job at a given time.
This patch changes it to be asynchronous by adding AIO support.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/algif_skcipher.c |  315 ++-
 1 file changed, 309 insertions(+), 6 deletions(-)

diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index 38a6757..c953200 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -19,9 +19,11 @@
 #include linux/list.h
 #include linux/kernel.h
 #include linux/mm.h
+#include linux/mempool.h
 #include linux/module.h
 #include linux/net.h
 #include net/sock.h
+#include linux/aio.h
 
 struct skcipher_sg_list {
struct list_head list;
@@ -39,6 +41,9 @@ struct skcipher_ctx {
 
struct af_alg_completion completion;
 
+   struct kmem_cache *cache;
+   mempool_t *pool;
+   atomic_t inflight;
unsigned used;
 
unsigned int len;
@@ -49,9 +54,135 @@ struct skcipher_ctx {
struct ablkcipher_request req;
 };
 
+struct skcipher_async_rsgl {
+   struct af_alg_sgl sgl;
+   struct list_head list;
+};
+
+struct skcipher_async_req {
+   struct kiocb *iocb;
+   struct skcipher_async_rsgl first_sgl;
+   struct list_head list;
+   struct scatterlist *tsg;
+   char iv[];
+};
+
+#define GET_SREQ(areq, ctx) (struct skcipher_async_req *)((char *)areq + \
+   crypto_ablkcipher_reqsize(crypto_ablkcipher_reqtfm(ctx-req)))
+
+#define GET_REQ_SIZE(ctx) \
+   crypto_ablkcipher_reqsize(crypto_ablkcipher_reqtfm(ctx-req))
+
+#define GET_IV_SIZE(ctx) \
+   crypto_ablkcipher_ivsize(crypto_ablkcipher_reqtfm(ctx-req))
+
 #define MAX_SGL_ENTS ((4096 - sizeof(struct skcipher_sg_list)) / \
  sizeof(struct scatterlist) - 1)
 
+static void skcipher_free_async_sgls(struct skcipher_async_req *sreq)
+{
+   struct skcipher_async_rsgl *rsgl;
+   struct scatterlist *sgl;
+   struct scatterlist *sg;
+   int i, n;
+
+   list_for_each_entry(rsgl, sreq-list, list) {
+   af_alg_free_sg(rsgl-sgl);
+   if (rsgl != sreq-first_sgl)
+   kfree(rsgl);
+   }
+   sgl = sreq-tsg;
+   n = sg_nents(sgl);
+   for_each_sg(sgl, sg, n, i)
+   put_page(sg_page(sg));
+
+   kfree(sreq-tsg);
+}
+
+static void skcipher_async_cb(struct crypto_async_request *req, int err)
+{
+   struct sock *sk = req-data;
+   struct alg_sock *ask = alg_sk(sk);
+   struct skcipher_ctx *ctx = ask-private;
+   struct skcipher_async_req *sreq = GET_SREQ(req, ctx);
+   struct kiocb *iocb = sreq-iocb;
+
+   atomic_dec(ctx-inflight);
+   skcipher_free_async_sgls(sreq);
+   mempool_free(req, ctx-pool);
+   sock_aio_complete(iocb, err, err);
+}
+
+static void skcipher_mempool_free(void *_req, void *_sk)
+{
+   struct sock *sk = _sk;
+   struct alg_sock *ask = alg_sk(sk);
+   struct skcipher_ctx *ctx = ask-private;
+   struct kmem_cache *cache = ctx-cache;
+
+   kmem_cache_free(cache, _req);
+}
+
+static void *skcipher_mempool_alloc(gfp_t gfp_mask, void *_sk)
+{
+   struct sock *sk = _sk;
+   struct alg_sock *ask = alg_sk(sk);
+   struct skcipher_ctx *ctx = ask-private;
+   struct kmem_cache *cache = ctx-cache;
+   struct ablkcipher_request *req;
+
+   req = kmem_cache_alloc(cache, gfp_mask);
+   if (req) {
+   ablkcipher_request_set_tfm(req,
+  crypto_ablkcipher_reqtfm(ctx-req));
+   ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+   skcipher_async_cb, sk);
+   }
+   return req;
+}
+
+static void skcipher_cache_constructor(void *v)
+{
+   memset(v, 0, sizeof(struct skcipher_async_req));
+}
+
+static int skcipher_mempool_create(struct sock *sk)
+{
+   struct alg_sock *ask = alg_sk(sk);
+   struct skcipher_ctx *ctx = ask-private;
+   unsigned int len = sizeof(struct skcipher_async_req) +
+   GET_REQ_SIZE(ctx) + GET_IV_SIZE(ctx);
+   char buf[32];
+
+   snprintf(buf, sizeof(buf), skcipher_%p, ctx);
+   ctx-cache = kmem_cache_create(buf, len, 0, SLAB_HWCACHE_ALIGN |
+  SLAB_TEMPORARY,
+  skcipher_cache_constructor);
+   if (unlikely(!ctx-cache))
+   return -ENOMEM;
+
+   ctx-pool = mempool_create(128, skcipher_mempool_alloc,
+  skcipher_mempool_free, sk);
+
+   if (unlikely(!ctx-pool)) {
+   kmem_cache_destroy(ctx-cache);
+   return -ENOMEM;
+   }
+   return 0;
+}
+
+static void skcipher_mempool_destroy(struct

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

2015-05-04 Thread Tadeusz Struk
On 05/02/2015 05:07 PM, Herbert Xu wrote:
#define CRYPTO_ALG_TYPE_AHASH0x000a
+#define CRYPTO_ALG_TYPE_PKE   0x000b
 #define CRYPTO_ALG_TYPE_RNG   0x000c
   Will filling a hole cause a problem with something that got obsoleted?
  
  I hope not. I checked as far back as 2.6.18 and I don't see any clash.
  Herbert, what do you think?
 Indeed you can't use this hole as it'll make you a hash algorithm.

So in this case isn't RNG a hash algorithm as well?
Anyway will something like this be ok with you:

diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index ee14140..ac18cd3 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -41,7 +41,7 @@
 /*
  * Algorithm masks and types.
  */
-#define CRYPTO_ALG_TYPE_MASK   0x000f
+#define CRYPTO_ALG_TYPE_MASK   0xf00f
 #define CRYPTO_ALG_TYPE_CIPHER 0x0001
 #define CRYPTO_ALG_TYPE_COMPRESS   0x0002
 #define CRYPTO_ALG_TYPE_AEAD   0x0003
@@ -54,6 +54,7 @@
 #define CRYPTO_ALG_TYPE_AHASH  0x000a
 #define CRYPTO_ALG_TYPE_RNG0x000c
 #define CRYPTO_ALG_TYPE_PCOMPRESS  0x000f
+#define CRYPTO_ALG_TYPE_PKE0x1001
 
 #define CRYPTO_ALG_TYPE_HASH_MASK  0x000e
 #define CRYPTO_ALG_TYPE_AHASH_MASK 0x000c


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


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

2015-05-01 Thread Tadeusz Struk
Hi Stephan,
On 05/01/2015 12:24 AM, Stephan Mueller wrote:
 +struct public_key;
 +struct public_key_signature;
 Wouldn't it make sense to move the struct definitions here and have them 
 documented?

I'm not sure if they belong here. I think we can add some documentation
without moving them.

 +struct pke_alg {
 +   int (*sign)(struct pke_request *pkereq);
 +   int (*verify)(struct pke_request *pkereq);
 +   int (*encrypt)(struct pke_request *pkereq);
 +   int (*decrypt)(struct pke_request *pkereq);
 +
 +   u8 pub_mpis;/* Number of MPIs in public key */
 +   u8 sec_mpis;/* Number of MPIs in secret key */
 +   u8 sig_mpis;/* Number of MPIs in a signature */
 May I ask that for such new structs we add some documentation? Currently, I 
 am 
 unclear on what MPIs are. E.g. if somebody needs to add, say, Curve 25519, 
 what shall he add here?

Sure, I'll add some description.

 
 Up to here I am volunteering to add the documentation comments.
 
 But for the following functions, I am not sure how they are supposed to be 
 used correctly. Thus, can you add the documentation for them or at least give 
 me a hint so that I can add the documentation?

Same here, I'll add something. Thanks for volunteering.
You did a good job documenting the rest and your help will be appreciated.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC 0/2] crypto: Introduce Public Key Encryption API

2015-05-01 Thread Tadeusz Struk
On 05/01/2015 01:47 AM, Jean Delvare wrote:
 I have nothing to do with this, please drop me from Cc.

Sorry, your name was reported by scripts/get_maintainer.pl
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2015-04-30 Thread Tadeusz Struk
Add Public Key Encryption API.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/Kconfig |6 +
 crypto/Makefile|1 
 crypto/crypto_user.c   |   23 +
 crypto/pke.c   |  114 ++
 include/crypto/algapi.h|6 +
 include/linux/crypto.h |  191 
 include/linux/cryptouser.h |7 ++
 7 files changed, 347 insertions(+), 1 deletion(-)
 create mode 100644 crypto/pke.c

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 8aaf298..9a14b33 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -87,6 +87,12 @@ config CRYPTO_PCOMP2
tristate
select CRYPTO_ALGAPI2
 
+config CRYPTO_PKE
+   tristate Public Key Algorithms API
+   select CRYPTO_ALGAPI
+   help
+ Crypto API interface for public key algorithms.
+
 config CRYPTO_MANAGER
tristate Cryptographic algorithm manager
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 97b7d3a..e7dd283 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -27,6 +27,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
+obj-$(CONFIG_CRYPTO_PKE) += pke.o
 
 cryptomgr-y := algboss.o testmgr.o
 
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 41dfe76..83b4d0f 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -110,6 +110,23 @@ nla_put_failure:
return -EMSGSIZE;
 }
 
+static int crypto_report_pke(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_pke rpke;
+
+   strncpy(rpke.type, pke, sizeof(rpke.type));
+   strncpy(rpke.subtype, alg-cra_name, sizeof(rpke.subtype));
+   rpke.capabilities = alg-cra_pke.capabilities;
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_PKE,
+   sizeof(struct crypto_report_pke), rpke))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+
 static int crypto_report_one(struct crypto_alg *alg,
 struct crypto_user_alg *ualg, struct sk_buff *skb)
 {
@@ -154,6 +171,12 @@ static int crypto_report_one(struct crypto_alg *alg,
goto nla_put_failure;
 
break;
+
+   case CRYPTO_ALG_TYPE_PKE:
+   if (crypto_report_pke(skb, alg))
+   goto nla_put_failure;
+
+   break;
}
 
 out:
diff --git a/crypto/pke.c b/crypto/pke.c
new file mode 100644
index 000..c1350fa
--- /dev/null
+++ b/crypto/pke.c
@@ -0,0 +1,114 @@
+/*
+ * Public Key Encryption operations.
+ *
+ * Copyright (c) 2015, Intel Corporation
+ * Authors: Tadeusz Struk tadeusz.st...@intel.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include linux/errno.h
+#include linux/kernel.h
+#include linux/module.h
+#include linux/seq_file.h
+#include linux/slab.h
+#include linux/string.h
+#include linux/crypto.h
+#include linux/cryptouser.h
+#include net/netlink.h
+#include internal.h
+
+static unsigned int crypto_pke_ctxsize(struct crypto_alg *alg, u32 type,
+  u32 mask)
+{
+   unsigned int len = alg-cra_ctxsize;
+
+   return ALIGN(len, (unsigned long)alg-cra_alignmask + 1);
+}
+
+static int crypto_init_pke_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
+{
+   struct pke_tfm *crt = tfm-crt_pke;
+   struct pke_alg *alg = tfm-__crt_alg-cra_pke;
+
+   if (alg-pub_mpis  5 || alg-sec_mpis  5 || alg-sig_mpis  2)
+   return -EINVAL;
+
+   if ((alg-capabilities  PKEY_CAN_ENCRYPT)  !alg-encrypt)
+   return -EINVAL;
+
+   if ((alg-capabilities  PKEY_CAN_DECRYPT)  !alg-decrypt)
+   return -EINVAL;
+
+   if ((alg-capabilities  PKEY_CAN_SIGN)  !alg-sign)
+   return -EINVAL;
+
+   if ((alg-capabilities  PKEY_CAN_VERIFY)  !alg-verify)
+   return -EINVAL;
+
+   crt-sign = alg-sign;
+   crt-verify = alg-verify;
+   crt-encrypt = alg-encrypt;
+   crt-decrypt = alg-decrypt;
+   crt-base = __crypto_pke_cast(tfm);
+
+   return 0;
+}
+
+#ifdef CONFIG_NET
+static int crypto_pke_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_pke rep_pke;
+
+   strncpy(rep_pke.type, pke, sizeof(rep_pke.type));
+   strncpy(rep_pke.subtype, alg-cra_name, sizeof(rep_pke.subtype));
+   rep_pke.capabilities = alg-cra_pke.capabilities;
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_PKE,
+   sizeof(struct crypto_report_pke), rep_pke))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_pke_report(struct sk_buff *skb, struct

[PATCH RFC 2/2] crypto: RSA: KEYS: convert rsa and public key to new PKE API

2015-04-30 Thread Tadeusz Struk
Change the existing rsa and public key code to integrate it
with the new Public Key Encryption API.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 Documentation/crypto/asymmetric-keys.txt  |   10 +++-
 crypto/asymmetric_keys/Kconfig|1 
 crypto/asymmetric_keys/pkcs7_parser.c |4 +-
 crypto/asymmetric_keys/pkcs7_trust.c  |2 -
 crypto/asymmetric_keys/pkcs7_verify.c |5 +-
 crypto/asymmetric_keys/public_key.c   |   73 +
 crypto/asymmetric_keys/public_key.h   |   36 --
 crypto/asymmetric_keys/rsa.c  |   47 +++
 crypto/asymmetric_keys/x509_cert_parser.c |   14 --
 crypto/asymmetric_keys/x509_public_key.c  |   14 ++
 include/crypto/public_key.h   |   24 +++---
 kernel/module_signing.c   |9 +++-
 12 files changed, 124 insertions(+), 115 deletions(-)
 delete mode 100644 crypto/asymmetric_keys/public_key.h

diff --git a/Documentation/crypto/asymmetric-keys.txt 
b/Documentation/crypto/asymmetric-keys.txt
index b767590..47bb5fb 100644
--- a/Documentation/crypto/asymmetric-keys.txt
+++ b/Documentation/crypto/asymmetric-keys.txt
@@ -89,11 +89,9 @@ inclusion is required:
#include crypto/public_key.h
 
 This gives access to functions for dealing with asymmetric / public keys.
-Three enums are defined there for representing public-key cryptography
+Two enums are defined there for representing public-key cryptography
 algorithms:
 
-   enum pkey_algo
-
 digest algorithms used by those:
 
enum pkey_hash_algo
@@ -102,6 +100,11 @@ and key identifier representations:
 
enum pkey_id_type
 
+Additionally public key algorithm names are defined:
+#define PKEY_ALGO_DSA dsa
+#define PKEY_ALGO_RSA rsa
+These will be used to allocate public key tfm instances.
+
 Note that the key type representation types are required because key
 identifiers from different standards aren't necessarily compatible.  For
 instance, PGP generates key identifiers by hashing the key data plus some
@@ -131,6 +134,7 @@ transferred the relevant bits to the structure pointed to 
by sig.
 
struct public_key_signature {
u8 *digest;
+   char *pkey_algo;
u8 digest_size;
enum pkey_hash_algo pkey_hash_algo : 8;
u8 nr_mpi;
diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
index 4870f28..1ad10f1 100644
--- a/crypto/asymmetric_keys/Kconfig
+++ b/crypto/asymmetric_keys/Kconfig
@@ -23,6 +23,7 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
 config PUBLIC_KEY_ALGO_RSA
tristate RSA public-key algorithm
select MPILIB
+   select CRYPTO_PKE
help
  This option enables support for the RSA algorithm (PKCS#1, RFC3447).
 
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c 
b/crypto/asymmetric_keys/pkcs7_parser.c
index 3bd5a1e..d37a608 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -15,7 +15,7 @@
 #include linux/slab.h
 #include linux/err.h
 #include linux/oid_registry.h
-#include public_key.h
+#include crypto/public_key.h
 #include pkcs7_parser.h
 #include pkcs7-asn1.h
 
@@ -376,7 +376,7 @@ int pkcs7_sig_note_signature(void *context, size_t hdrlen,
struct pkcs7_parse_context *ctx = context;
MPI mpi;
 
-   BUG_ON(ctx-sinfo-sig.pkey_algo != PKEY_ALGO_RSA);
+   BUG_ON(strcmp(ctx-sinfo-sig.pkey_algo, PKEY_ALGO_RSA));
 
mpi = mpi_read_raw_data(value, vlen);
if (!mpi)
diff --git a/crypto/asymmetric_keys/pkcs7_trust.c 
b/crypto/asymmetric_keys/pkcs7_trust.c
index 1d29376..68ebae2 100644
--- a/crypto/asymmetric_keys/pkcs7_trust.c
+++ b/crypto/asymmetric_keys/pkcs7_trust.c
@@ -17,7 +17,7 @@
 #include linux/asn1.h
 #include linux/key.h
 #include keys/asymmetric-type.h
-#include public_key.h
+#include crypto/public_key.h
 #include pkcs7_parser.h
 
 /**
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c 
b/crypto/asymmetric_keys/pkcs7_verify.c
index cd45545..28f4a77 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -16,7 +16,7 @@
 #include linux/err.h
 #include linux/asn1.h
 #include crypto/hash.h
-#include public_key.h
+#include crypto/public_key.h
 #include pkcs7_parser.h
 
 /*
@@ -144,7 +144,8 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
pr_devel(Sig %u: Found cert serial match X.509[%u]\n,
 sinfo-index, certix);
 
-   if (x509-pub-pkey_algo != sinfo-sig.pkey_algo) {
+   if (strcmp(pke_alg_name(x509-pub-tfm),
+  sinfo-sig.pkey_algo)) {
pr_warn(Sig %u: X.509 algo and PKCS#7 sig algo don't 
match\n,
sinfo-index);
continue;
diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index 2f6e4fb..031112a 100644

[PATCH RFC 0/2] crypto: Introduce Public Key Encryption API

2015-04-30 Thread Tadeusz Struk
This patch set introduces a Public Key Encryption API.
What is proposed is a new crypto type called crypto_pke_type
plus new struct pke_alg and struct pke_tfm together with number
of helper functions to register pke type algorithms and allocate
tfm instances. This is to make it similar to how the existing crypto
API works for the ablkcipher, ahash, and aead types.
The operations the new interface will allow to provide are:

int (*sign)(struct pke_request *pkereq);
int (*verify)(struct pke_request *pkereq);
int (*encrypt)(struct pke_request *pkereq);
int (*decrypt)(struct pke_request *pkereq);

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

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

struct crypto_pke *tfm = crypto_alloc_pke(rsa, 0, 0);
struct pke_request *req = pke_request_alloc(tfm, GFP_KERNEL);
pke_request_set_crypt(req, pub_key, signature);
int ret = crypto_pke_verify(req);
pke_request_free(req);
crypto_free_pke(tfm);
return ret;

Additionally existing public_key and rsa code have been reworked to
use the new interface for verifying signed modules.
As part of the rework the enum pkey_algo has been removed as the algorithm
to allocate will be indicated by a string - for instance rsa or dsa,
similarly as it is with the symmetric algs e.g. aes.
It will also make it easier to extend in the future when new algorithms
will be added.
---
Tadeusz Struk (2):
  crypto: add PKE API
  crypto: RSA: KEYS: convert rsa and public key to new PKE API


 Documentation/crypto/asymmetric-keys.txt  |   10 +-
 crypto/Kconfig|6 +
 crypto/Makefile   |1 
 crypto/asymmetric_keys/Kconfig|1 
 crypto/asymmetric_keys/pkcs7_parser.c |4 -
 crypto/asymmetric_keys/pkcs7_trust.c  |2 
 crypto/asymmetric_keys/pkcs7_verify.c |5 -
 crypto/asymmetric_keys/public_key.c   |   73 +++
 crypto/asymmetric_keys/public_key.h   |   36 -
 crypto/asymmetric_keys/rsa.c  |   47 ++-
 crypto/asymmetric_keys/x509_cert_parser.c |   14 ++
 crypto/asymmetric_keys/x509_public_key.c  |   14 +-
 crypto/crypto_user.c  |   23 +++
 crypto/pke.c  |  114 +
 include/crypto/algapi.h   |6 +
 include/crypto/public_key.h   |   24 +---
 include/linux/crypto.h|  191 +
 include/linux/cryptouser.h|7 +
 kernel/module_signing.c   |9 +
 19 files changed, 471 insertions(+), 116 deletions(-)
 delete mode 100644 crypto/asymmetric_keys/public_key.h
 create mode 100644 crypto/pke.c

-- 

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


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

2015-04-30 Thread Tadeusz Struk
On 04/30/2015 03:43 PM, Herbert Xu wrote:
 Please remodel it after pcompress or the newly converted rng type.
 
 This union stuff has been obsolete since 2008 and it's time for
 it to die.

Ok, I didn't realize. Will send v2 shortly.
Thanks

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


Re: [PATCH RFC 2/2] crypto: RSA: KEYS: convert rsa and public key to new PKE API

2015-05-01 Thread Tadeusz Struk
On 05/01/2015 09:21 AM, David Howells wrote:
 +.verify = RSA_verify_signature,
  +  .capabilities = PKEY_CAN_VERIFY,
 Can we keep .verify_signature as the name of the first.  The second is
 redundant given the function pointers.

I'm thinking that .verify will be more generic. If in the future
we would like to implement something that verifies not a signature, but
for instance is a number is a prime, then we can register a prime alg
that implements verify and returns true if a number is a prime.   

 
 Given that X.509 certs can hang around for a very long time, having a tfm in
 the cert is probably a bad idea as it may pin resources such as crypto h/w.
 
  -  ctx-cert-pub-pkey_algo = PKEY_ALGO_RSA;
  -
 I think you need this rather than the above.  You should only get the tfm when
 you actually need it.
 

That's a good point.
Thank you David for all your comments. I'll rework my patches and send v2 soon.
I'll also try to integrate it with your sign-file as you suggested.
Thanks
T
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2015-05-01 Thread Tadeusz Struk
On 05/01/2015 09:04 AM, David Howells wrote:
 +config CRYPTO_PKE
 I would prefer CRYPTO_PKEY and pkey rather than pke generally and algo rather
 than alg where possible - this will have more consistency with what we have
 now.
 
 I understand, however, that in core crypto code, 'alg' is used.

I'm fine with pkey. Herbert do you have preference with regards 'algo' vs 'alg'?

  #define CRYPTO_ALG_TYPE_AHASH   0x000a
  +#define CRYPTO_ALG_TYPE_PKE   0x000b
   #define CRYPTO_ALG_TYPE_RNG   0x000c
 Will filling a hole cause a problem with something that got obsoleted?

I hope not. I checked as far back as 2.6.18 and I don't see any clash.
Herbert, what do you think?

 
 +struct pke_request {
  +  struct crypto_async_request base;
  +  const struct public_key *pk;
  +  const struct public_key_signature *pks;
  +};
 I recommend:
 
   pk - key or pkey
   pks - sig or signature

no problem

 
 +u8 pub_mpis;/* Number of MPIs in public key */
  +  u8 sec_mpis;/* Number of MPIs in secret key */
  +  u8 sig_mpis;/* Number of MPIs in a signature */
 Keep member names as:
 
   u8  n_pub_mpi;  /* Number of MPIs in public key */
   u8  n_sec_mpi;  /* Number of MPIs in secret key */
   u8  n_sig_mpi;  /* Number of MPIs in a signature */

same here.
thanks

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


[PATCH RFC v2 0/2] crypto: Introduce Public Key Encryption API

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

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

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

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

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

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

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

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


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

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


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

2015-05-06 Thread Tadeusz Struk
Add Public Key Encryption API.

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

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 8aaf298..daa9c07 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -87,6 +87,12 @@ config CRYPTO_PCOMP2
tristate
select CRYPTO_ALGAPI2
 
+config CRYPTO_PKEY
+   tristate Public Key Algorithms API
+   select CRYPTO_ALGAPI
+   help
+ Crypto API interface for public key algorithms.
+
 config CRYPTO_MANAGER
tristate Cryptographic algorithm manager
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 97b7d3a..1930f85 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -27,6 +27,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
+obj-$(CONFIG_CRYPTO_PKEY) += pkey.o
 
 cryptomgr-y := algboss.o testmgr.o
 
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 41dfe76..ccc7f1d 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -27,6 +27,7 @@
 #include net/net_namespace.h
 #include crypto/internal/aead.h
 #include crypto/internal/skcipher.h
+#include crypto/pkey.h
 
 #include internal.h
 
@@ -110,6 +111,23 @@ nla_put_failure:
return -EMSGSIZE;
 }
 
+static int crypto_report_pkey(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_pkey rpkey;
+
+   strncpy(rpkey.type, pke, sizeof(rpkey.type));
+   strncpy(rpkey.subtype, alg-cra_name, sizeof(rpkey.subtype));
+   rpkey.capabilities = __crypto_pkey_alg(alg)-capabilities;
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_PKEY,
+   sizeof(struct crypto_report_pkey), rpkey))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+
 static int crypto_report_one(struct crypto_alg *alg,
 struct crypto_user_alg *ualg, struct sk_buff *skb)
 {
@@ -154,6 +172,12 @@ static int crypto_report_one(struct crypto_alg *alg,
goto nla_put_failure;
 
break;
+
+   case CRYPTO_ALG_TYPE_PKEY:
+   if (crypto_report_pkey(skb, alg))
+   goto nla_put_failure;
+
+   break;
}
 
 out:
diff --git a/crypto/pkey.c b/crypto/pkey.c
new file mode 100644
index 000..ab8c0e9
--- /dev/null
+++ b/crypto/pkey.c
@@ -0,0 +1,125 @@
+/*
+ * Public Key Encryption
+ *
+ * Copyright (c) 2015, Intel Corporation
+ * Authors: Tadeusz Struk tadeusz.st...@intel.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include linux/errno.h
+#include linux/kernel.h
+#include linux/module.h
+#include linux/seq_file.h
+#include linux/slab.h
+#include linux/string.h
+#include linux/crypto.h
+#include crypto/algapi.h
+#include linux/cryptouser.h
+#include net/netlink.h
+#include crypto/pkey.h
+#include internal.h
+
+#ifdef CONFIG_NET
+static int crypto_pkey_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_pkey rep_pkey;
+
+   strncpy(rep_pkey.type, pkey, sizeof(rep_pkey.type));
+   strncpy(rep_pkey.subtype, alg-cra_name, sizeof(rep_pkey.subtype));
+   rep_pkey.capabilities = __crypto_pkey_alg(alg)-capabilities;
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_PKEY,
+   sizeof(struct crypto_report_pkey), rep_pkey))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_pkey_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+static void crypto_pkey_show(struct seq_file *m, struct crypto_alg *alg)
+   __attribute__ ((unused));
+static void crypto_pkey_show(struct seq_file *m, struct crypto_alg *alg)
+{
+   int cap = __crypto_pkey_alg(alg)-capabilities;
+
+   seq_puts(m, type : pke\n);
+   seq_printf(m, subtype  : %s\n, alg-cra_name);
+   seq_printf(m, can encrypt  : %s\n,
+  cap  PKEY_CAN_ENCRYPT ? yes : no);
+   seq_printf(m, can decrypt  : %s\n,
+  cap  PKEY_CAN_DECRYPT ? yes : no);
+   seq_printf(m, can sign : %s\n,
+  cap  PKEY_CAN_SIGN ? yes : no);
+   seq_printf(m, can verify   : %s\n,
+  cap  PKEY_CAN_VERIFY ? yes : no);
+}
+
+static int crypto_pkey_init(struct crypto_tfm

[PATCH RFC v2 2/2] crypto: RSA: KEYS: convert rsa and public key to new PKE API

2015-05-06 Thread Tadeusz Struk
Change the existing rsa and public key code to integrate it
with the new Public Key Encryption API.

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

diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
index 4870f28..1b7d7d6 100644
--- a/crypto/asymmetric_keys/Kconfig
+++ b/crypto/asymmetric_keys/Kconfig
@@ -23,6 +23,7 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
 config PUBLIC_KEY_ALGO_RSA
tristate RSA public-key algorithm
select MPILIB
+   select CRYPTO_PKEY
help
  This option enables support for the RSA algorithm (PKCS#1, RFC3447).
 
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c 
b/crypto/asymmetric_keys/pkcs7_parser.c
index 3bd5a1e..054f110 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -15,7 +15,7 @@
 #include linux/slab.h
 #include linux/err.h
 #include linux/oid_registry.h
-#include public_key.h
+#include crypto/public_key.h
 #include pkcs7_parser.h
 #include pkcs7-asn1.h
 
diff --git a/crypto/asymmetric_keys/pkcs7_trust.c 
b/crypto/asymmetric_keys/pkcs7_trust.c
index 1d29376..68ebae2 100644
--- a/crypto/asymmetric_keys/pkcs7_trust.c
+++ b/crypto/asymmetric_keys/pkcs7_trust.c
@@ -17,7 +17,7 @@
 #include linux/asn1.h
 #include linux/key.h
 #include keys/asymmetric-type.h
-#include public_key.h
+#include crypto/public_key.h
 #include pkcs7_parser.h
 
 /**
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c 
b/crypto/asymmetric_keys/pkcs7_verify.c
index cd45545..9f1035c 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -16,7 +16,8 @@
 #include linux/err.h
 #include linux/asn1.h
 #include crypto/hash.h
-#include public_key.h
+#include crypto/public_key.h
+#include crypto/pkey.h
 #include pkcs7_parser.h
 
 /*
diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index 2f6e4fb..d147ee0 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -18,30 +18,28 @@
 #include linux/slab.h
 #include linux/seq_file.h
 #include keys/asymmetric-subtype.h
-#include public_key.h
+#include crypto/public_key.h
+#include crypto/pkey.h
 
 MODULE_LICENSE(GPL);
 
 const char *const pkey_algo_name[PKEY_ALGO__LAST] = {
-   [PKEY_ALGO_DSA] = DSA,
-   [PKEY_ALGO_RSA] = RSA,
+   [PKEY_ALGO_DSA] = dsa,
+   [PKEY_ALGO_RSA] = rsa,
 };
 EXPORT_SYMBOL_GPL(pkey_algo_name);
 
-const struct public_key_algorithm *pkey_algo[PKEY_ALGO__LAST] = {
-#if defined(CONFIG_PUBLIC_KEY_ALGO_RSA) || \
-   defined(CONFIG_PUBLIC_KEY_ALGO_RSA_MODULE)
-   [PKEY_ALGO_RSA] = RSA_public_key_algorithm,
-#endif
-};
-EXPORT_SYMBOL_GPL(pkey_algo);
-
 const char *const pkey_id_type_name[PKEY_ID_TYPE__LAST] = {
[PKEY_ID_PGP]   = PGP,
[PKEY_ID_X509]  = X509,
 };
 EXPORT_SYMBOL_GPL(pkey_id_type_name);
 
+struct public_key_completion {
+   struct completion completion;
+   int err;
+};
+
 /*
  * Provide a part of a description of the key for /proc/keys.
  */
@@ -52,7 +50,8 @@ static void public_key_describe(const struct key 
*asymmetric_key,
 
if (key)
seq_printf(m, %s.%s,
-  pkey_id_type_name[key-id_type], key-algo-name);
+  pkey_id_type_name[key-id_type],
+  pkey_algo_name[key-pkey_algo]);
 }
 
 /*
@@ -71,40 +70,68 @@ void public_key_destroy(void *payload)
 }
 EXPORT_SYMBOL_GPL(public_key_destroy);
 
+static void public_key_verify_done(struct crypto_async_request *req, int err)
+{
+   struct public_key_completion *compl = req-data;
+
+   if (err == -EINPROGRESS)
+   return;
+
+   compl-err = err;
+   complete(compl-completion);
+}
+
 /*
  * Verify a signature using a public key.
  */
-int public_key_verify_signature(const struct public_key *pk,
+int public_key_verify_signature(const struct public_key *pkey,
const struct public_key_signature *sig)
 {
-   const struct public_key_algorithm *algo;
-
-   BUG_ON(!pk);
-   BUG_ON(!pk-mpi[0]);
-   BUG_ON(!pk-mpi[1]);
+   struct crypto_pkey *tfm;
+   struct pkey_request *req;
+   struct public_key_completion compl;
+   int ret

Re: [PATCH RFC 0/2] crypto: Introduce Public Key Encryption API

2015-05-04 Thread Tadeusz Struk
Hi Horia,
On 05/04/2015 06:16 AM, Horia Geantă wrote:
  int (*sign)(struct pke_request *pkereq);
 int (*verify)(struct pke_request *pkereq);
 int (*encrypt)(struct pke_request *pkereq);
 int (*decrypt)(struct pke_request *pkereq);
 Where would be the proper place for keygen operation?

This will need to be extended to support keygen.

 
 AFAICT algorithms currently map to primitives + encoding methods, which
 is not flexible. For e.g. current RSA implementation hardcodes the
 PKCS1-v1_5 encoding method, making it hard to add OAEP(+) etc.
 
 One solution would be to map algorithms to primitives only. Encoding
 methods need to be abstracted somehow, maybe using templates to wrap the
 algorithms.

So far there is only one rsa implementation in kernel and it is only used
by module signing code.
Later we can add templates or simply one can register oaep-rsa algorithm.

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


[PATCH RFC v3 2/3] crypto: RSA: KEYS: convert rsa and public key to new PKE API

2015-06-03 Thread Tadeusz Struk
Change the existing rsa and public key code to integrate it
with the new Public Key Encryption API.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/asymmetric_keys/Kconfig|1 
 crypto/asymmetric_keys/Makefile   |1 
 crypto/asymmetric_keys/pkcs7_parser.c |2 
 crypto/asymmetric_keys/pkcs7_trust.c  |2 
 crypto/asymmetric_keys/pkcs7_verify.c |2 
 crypto/asymmetric_keys/public_key.c   |   53 +--
 crypto/asymmetric_keys/public_key.h   |   36 --
 crypto/asymmetric_keys/rsa.c  |  467 -
 crypto/asymmetric_keys/rsa_pkcs1_v1_5.c   |  259 
 crypto/asymmetric_keys/x509_cert_parser.c |2 
 crypto/asymmetric_keys/x509_public_key.c  |4 
 include/crypto/public_key.h   |   11 -
 12 files changed, 540 insertions(+), 300 deletions(-)
 delete mode 100644 crypto/asymmetric_keys/public_key.h
 create mode 100644 crypto/asymmetric_keys/rsa_pkcs1_v1_5.c

diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
index 4870f28..4d27116 100644
--- a/crypto/asymmetric_keys/Kconfig
+++ b/crypto/asymmetric_keys/Kconfig
@@ -23,6 +23,7 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
 config PUBLIC_KEY_ALGO_RSA
tristate RSA public-key algorithm
select MPILIB
+   select CRYPTO_AKCIPHER
help
  This option enables support for the RSA algorithm (PKCS#1, RFC3447).
 
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index e47fcd9..a9cb1b8 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -8,6 +8,7 @@ asymmetric_keys-y := asymmetric_type.o signature.o
 
 obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
 obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa.o
+obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa_pkcs1_v1_5.o
 
 #
 # X.509 Certificate handling
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c 
b/crypto/asymmetric_keys/pkcs7_parser.c
index 3bd5a1e..054f110 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -15,7 +15,7 @@
 #include linux/slab.h
 #include linux/err.h
 #include linux/oid_registry.h
-#include public_key.h
+#include crypto/public_key.h
 #include pkcs7_parser.h
 #include pkcs7-asn1.h
 
diff --git a/crypto/asymmetric_keys/pkcs7_trust.c 
b/crypto/asymmetric_keys/pkcs7_trust.c
index 1d29376..68ebae2 100644
--- a/crypto/asymmetric_keys/pkcs7_trust.c
+++ b/crypto/asymmetric_keys/pkcs7_trust.c
@@ -17,7 +17,7 @@
 #include linux/asn1.h
 #include linux/key.h
 #include keys/asymmetric-type.h
-#include public_key.h
+#include crypto/public_key.h
 #include pkcs7_parser.h
 
 /**
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c 
b/crypto/asymmetric_keys/pkcs7_verify.c
index cd45545..c32a337 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -16,7 +16,7 @@
 #include linux/err.h
 #include linux/asn1.h
 #include crypto/hash.h
-#include public_key.h
+#include crypto/public_key.h
 #include pkcs7_parser.h
 
 /*
diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index 2f6e4fb..4685aed 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -18,30 +18,26 @@
 #include linux/slab.h
 #include linux/seq_file.h
 #include keys/asymmetric-subtype.h
-#include public_key.h
+#include crypto/public_key.h
+#include crypto/akcipher.h
 
 MODULE_LICENSE(GPL);
 
 const char *const pkey_algo_name[PKEY_ALGO__LAST] = {
-   [PKEY_ALGO_DSA] = DSA,
-   [PKEY_ALGO_RSA] = RSA,
+   [PKEY_ALGO_DSA] = dsa,
+   [PKEY_ALGO_RSA] = rsa,
 };
 EXPORT_SYMBOL_GPL(pkey_algo_name);
 
-const struct public_key_algorithm *pkey_algo[PKEY_ALGO__LAST] = {
-#if defined(CONFIG_PUBLIC_KEY_ALGO_RSA) || \
-   defined(CONFIG_PUBLIC_KEY_ALGO_RSA_MODULE)
-   [PKEY_ALGO_RSA] = RSA_public_key_algorithm,
-#endif
-};
-EXPORT_SYMBOL_GPL(pkey_algo);
-
 const char *const pkey_id_type_name[PKEY_ID_TYPE__LAST] = {
[PKEY_ID_PGP]   = PGP,
[PKEY_ID_X509]  = X509,
 };
 EXPORT_SYMBOL_GPL(pkey_id_type_name);
 
+int rsa_pkcs1_v1_5_verify_signature(const struct public_key *pkey,
+   const struct public_key_signature *sig);
+
 /*
  * Provide a part of a description of the key for /proc/keys.
  */
@@ -52,7 +48,8 @@ static void public_key_describe(const struct key 
*asymmetric_key,
 
if (key)
seq_printf(m, %s.%s,
-  pkey_id_type_name[key-id_type], key-algo-name);
+  pkey_id_type_name[key-id_type],
+  pkey_algo_name[key-pkey_algo]);
 }
 
 /*
@@ -74,37 +71,20 @@ EXPORT_SYMBOL_GPL(public_key_destroy);
 /*
  * Verify a signature using a public key.
  */
-int public_key_verify_signature(const struct public_key *pk,
+int public_key_verify_signature(const struct public_key *pkey

[PATCH RFC v3 0/3] crypto: Introduce Public Key Encryption API

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

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

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

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

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

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

Changes in v3:
 - changed input and output parameters type from sgl to void *
   and added separate src_len  dst_len - requested by Herbert Xu
 - separated rsa implementation into cryptographic primitives and
   left encryption scheme details outside of the algorithm implementation
 - added SW implementation for RSA encrypt, decrypt and sign operation
 - added RSA test vectors 
   
Changes in v2:
 - remodeled not to use obsolete cra_u and crt_u unions
 - changed type/funct names from pke_* to pkey_*
 - retained the enum pkey_algo type for it is external to the kernel
 - added documentation

---
Tadeusz Struk (3):
  crypto: add PKE API
  crypto: RSA: KEYS: convert rsa and public key to new PKE API
  crypto: add tests vectors for RSA


 crypto/Kconfig|6 
 crypto/Makefile   |1 
 crypto/akcipher.c |  100 ++
 crypto/asymmetric_keys/Kconfig|1 
 crypto/asymmetric_keys/Makefile   |1 
 crypto/asymmetric_keys/pkcs7_parser.c |2 
 crypto/asymmetric_keys/pkcs7_trust.c  |2 
 crypto/asymmetric_keys/pkcs7_verify.c |2 
 crypto/asymmetric_keys/public_key.c   |   53 +--
 crypto/asymmetric_keys/public_key.h   |   36 --
 crypto/asymmetric_keys/rsa.c  |  467 -
 crypto/asymmetric_keys/rsa_pkcs1_v1_5.c   |  259 
 crypto/asymmetric_keys/x509_cert_parser.c |2 
 crypto/asymmetric_keys/x509_public_key.c  |4 
 crypto/crypto_user.c  |   23 +
 crypto/testmgr.c  |  151 +
 crypto/testmgr.h  |   86 +
 include/crypto/akcipher.h |  385 
 include/crypto/public_key.h   |   11 -
 include/linux/crypto.h|1 
 include/linux/cryptouser.h|6 
 21 files changed, 1299 insertions(+), 300 deletions(-)
 create mode 100644 crypto/akcipher.c
 delete mode 100644 crypto/asymmetric_keys/public_key.h
 create mode 100644 crypto/asymmetric_keys/rsa_pkcs1_v1_5.c
 create mode 100644 include/crypto/akcipher.h
-- 

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


[PATCH RFC v3 1/3] crypto: add PKE API

2015-06-03 Thread Tadeusz Struk
Add Public Key Encryption API.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/Kconfig |6 +
 crypto/Makefile|1 
 crypto/akcipher.c  |  100 +++
 crypto/crypto_user.c   |   23 +++
 include/crypto/akcipher.h  |  385 
 include/linux/crypto.h |1 
 include/linux/cryptouser.h |6 +
 7 files changed, 522 insertions(+)
 create mode 100644 crypto/akcipher.c
 create mode 100644 include/crypto/akcipher.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 0ff4cd4..917f880 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -87,6 +87,12 @@ config CRYPTO_PCOMP2
tristate
select CRYPTO_ALGAPI2
 
+config CRYPTO_AKCIPHER
+   tristate Public Key Algorithms API
+   select CRYPTO_ALGAPI
+   help
+ Crypto API interface for public key algorithms.
+
 config CRYPTO_MANAGER
tristate Cryptographic algorithm manager
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 5db5b95..1ed2929 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -28,6 +28,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
+obj-$(CONFIG_CRYPTO_AKCIPHER) += akcipher.o
 
 cryptomgr-y := algboss.o testmgr.o
 
diff --git a/crypto/akcipher.c b/crypto/akcipher.c
new file mode 100644
index 000..92da8da8
--- /dev/null
+++ b/crypto/akcipher.c
@@ -0,0 +1,100 @@
+/*
+ * Public Key Encryption
+ *
+ * Copyright (c) 2015, Intel Corporation
+ * Authors: Tadeusz Struk tadeusz.st...@intel.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include linux/errno.h
+#include linux/kernel.h
+#include linux/module.h
+#include linux/seq_file.h
+#include linux/slab.h
+#include linux/string.h
+#include linux/crypto.h
+#include crypto/algapi.h
+#include linux/cryptouser.h
+#include net/netlink.h
+#include crypto/akcipher.h
+#include internal.h
+
+#ifdef CONFIG_NET
+static int crypto_akcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_akcipher rakcipher;
+
+   strncpy(rakcipher.type, akcipher, sizeof(rakcipher.type));
+   strncpy(rakcipher.subtype, alg-cra_name, sizeof(rakcipher.subtype));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_AKCIPHER,
+   sizeof(struct crypto_report_akcipher), rakcipher))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_akcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+static void crypto_akcipher_show(struct seq_file *m, struct crypto_alg *alg)
+   __attribute__ ((unused));
+
+static void crypto_akcipher_show(struct seq_file *m, struct crypto_alg *alg)
+{
+   seq_puts(m, type : akcipher\n);
+   seq_printf(m, subtype  : %s\n, alg-cra_name);
+}
+
+static int crypto_akcipher_init(struct crypto_tfm *tfm)
+{
+   return 0;
+}
+
+static const struct crypto_type crypto_akcipher_type = {
+   .extsize = crypto_alg_extsize,
+   .init_tfm = crypto_akcipher_init,
+#ifdef CONFIG_PROC_FS
+   .show = crypto_akcipher_show,
+#endif
+   .report = crypto_akcipher_report,
+   .maskclear = ~CRYPTO_ALG_TYPE_MASK,
+   .maskset = CRYPTO_ALG_TYPE_MASK,
+   .type = CRYPTO_ALG_TYPE_AKCIPHER,
+   .tfmsize = offsetof(struct crypto_akcipher, base),
+};
+
+struct crypto_akcipher *crypto_alloc_akcipher(const char *alg_name, u32 type,
+ u32 mask)
+{
+   return crypto_alloc_tfm(alg_name, crypto_akcipher_type, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_alloc_akcipher);
+
+int crypto_register_akcipher(struct akcipher_alg *alg)
+{
+   struct crypto_alg *base = alg-base;
+
+   base-cra_type = crypto_akcipher_type;
+   base-cra_flags = ~CRYPTO_ALG_TYPE_MASK;
+   base-cra_flags |= CRYPTO_ALG_TYPE_AKCIPHER;
+   return crypto_register_alg(base);
+}
+EXPORT_SYMBOL_GPL(crypto_register_akcipher);
+
+void crypto_unregister_akcipher(struct akcipher_alg *alg)
+{
+   crypto_unregister_alg(alg-base);
+}
+EXPORT_SYMBOL_GPL(crypto_unregister_akcipher);
+MODULE_LICENSE(GPL);
+MODULE_DESCRIPTION(Generic public key cihper type);
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 41dfe76..508e71d 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -27,6 +27,7 @@
 #include net/net_namespace.h
 #include crypto/internal/aead.h
 #include crypto/internal/skcipher.h
+#include crypto/akcipher.h
 
 #include internal.h
 
@@ -110,6 +111,22 @@ nla_put_failure:
return -EMSGSIZE;
 }
 
+static int crypto_report_akcipher(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct

[PATCH RFC v3 3/3] crypto: add tests vectors for RSA

2015-06-03 Thread Tadeusz Struk
New test vectors for RSA algorithm.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/testmgr.c |  151 ++
 crypto/testmgr.h |   86 +++
 2 files changed, 237 insertions(+)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 717d6f2..54a5412 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -30,6 +30,8 @@
 #include linux/string.h
 #include crypto/rng.h
 #include crypto/drbg.h
+#include crypto/public_key.h
+#include crypto/akcipher.h
 
 #include internal.h
 
@@ -116,6 +118,11 @@ struct drbg_test_suite {
unsigned int count;
 };
 
+struct akcipher_test_suite {
+   struct akcipher_testvec *vecs;
+   unsigned int count;
+};
+
 struct alg_test_desc {
const char *alg;
int (*test)(const struct alg_test_desc *desc, const char *driver,
@@ -130,6 +137,7 @@ struct alg_test_desc {
struct hash_test_suite hash;
struct cprng_test_suite cprng;
struct drbg_test_suite drbg;
+   struct akcipher_test_suite akcipher;
} suite;
 };
 
@@ -1825,6 +1833,139 @@ static int alg_test_drbg(const struct alg_test_desc 
*desc, const char *driver,
 
 }
 
+static int do_test_rsa(struct crypto_akcipher *tfm,
+  struct akcipher_testvec *vecs)
+{
+   struct akcipher_request *req;
+   struct public_key pkey;
+   void *outbuf_enc = NULL;
+   void *outbuf_dec = NULL;
+   struct tcrypt_result result;
+   unsigned int out_len = vecs-c_size;
+   int err = -ENOMEM;
+
+   req = akcipher_request_alloc(tfm, GFP_KERNEL);
+   if (!req)
+   return err;
+
+   pkey.rsa.n = mpi_read_raw_data(vecs-pub_key_n, vecs-pub_key_n_size);
+   if (!pkey.rsa.n)
+   goto free_req;
+
+   pkey.rsa.e = mpi_read_raw_data(vecs-pub_key_e, vecs-pub_key_e_size);
+   if (!pkey.rsa.e)
+   goto free_n;
+
+   pkey.rsa.d = mpi_read_raw_data(vecs-sec_key_d, vecs-sec_key_d_size);
+   if (!pkey.rsa.d)
+   goto free_e;
+
+   outbuf_enc = kzalloc(vecs-c_size, GFP_KERNEL);
+   if (!outbuf_enc)
+   goto free_d;
+
+   /* Run RSA encrypt - c = m^e mod n;*/
+   init_completion(result.completion);
+   crypto_akcipher_setkey(tfm, pkey);
+   akcipher_request_set_crypt(req, vecs-m, outbuf_enc, vecs-m_size,
+  out_len, out_len);
+   akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ tcrypt_complete, result);
+   err = wait_async_op(result, crypto_akcipher_encrypt(req));
+   if (err) {
+   pr_err(alg: rsa: encrypt test failed. err %d\n, err);
+   goto free_all;
+   }
+
+   if (out_len != vecs-c_size) {
+   err = -EINVAL;
+   goto free_all;
+   }
+
+   outbuf_dec = kzalloc(out_len, GFP_KERNEL);
+   if (!outbuf_dec) {
+   err = -ENOMEM;
+   goto free_all;
+   }
+
+   init_completion(result.completion);
+   akcipher_request_set_crypt(req, outbuf_enc, outbuf_dec, vecs-c_size,
+  out_len, out_len);
+   /* Run RSA decrypt - m = c^d mod n;*/
+   err = wait_async_op(result, crypto_akcipher_decrypt(req));
+   if (err) {
+   pr_err(alg: rsa: decrypt test failed. err %d\n, err);
+   goto free_all;
+   }
+
+   if (out_len != vecs-m_size) {
+   err = -EINVAL;
+   goto free_all;
+   }
+
+   /* verify that decrypted message is equal to the original msg */
+   if (memcmp(vecs-m, outbuf_dec, vecs-m_size)) {
+   pr_err(alg: rsa: encrypt test failed. Invalid output\n);
+   err = -EINVAL;
+   }
+free_all:
+   kfree(outbuf_dec);
+   kfree(outbuf_enc);
+free_d:
+   mpi_free(pkey.rsa.d);
+free_e:
+   mpi_free(pkey.rsa.e);
+free_n:
+   mpi_free(pkey.rsa.n);
+free_req:
+   akcipher_request_free(req);
+   return err;
+}
+
+static int test_rsa(struct crypto_akcipher *tfm, struct akcipher_testvec *vecs,
+   unsigned int tcount)
+{
+   int ret, i;
+
+   for (i = 0; i  tcount; i++) {
+   ret = do_test_rsa(tfm, vecs++);
+   if (ret) {
+   pr_err(alg: rsa: test failed on vector %d\n, i + 1);
+   return ret;
+   }
+   }
+   return 0;
+}
+
+static int test_akcipher(struct crypto_akcipher *tfm, const char *alg,
+struct akcipher_testvec *vecs, unsigned int tcount)
+{
+   if (strncmp(alg, rsa, 3) == 0)
+   return test_rsa(tfm, vecs, tcount);
+
+   return 0;
+}
+
+static int alg_test_akcipher(const struct alg_test_desc *desc,
+const char *driver, u32 type, u32 mask)
+{
+   struct crypto_akcipher *tfm;
+   int err = 0;
+
+   tfm

Re: [PATCH RFC v3 1/3] crypto: add PKE API

2015-06-04 Thread Tadeusz Struk
Hi Herbert,
On 06/03/2015 11:49 PM, Herbert Xu wrote:
 Because the caller is going to be allocating memory for the output,
 we need to provide a way for them to know how much memory to
 allocate.
 
 This presumably will depend on the key size.
 
 So something like
 
   int (*maxsize)(struct crypto_akcipher *tfm);
 
 is needed.
 
 You should also provide setkey here.  You can't just save a pointer
 to the key.  The transform must hold the key physically as the
 original may go away.  It should also ensure that the key is
 actually valid for the transform.
 
 base already has ctx so you should get rid of ctx and move base
 to the end of the struct.

right, will do that.
Thanks for quick response.




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


Re: [PATCH RFC v3 2/3] crypto: RSA: KEYS: convert rsa and public key to new PKE API

2015-06-04 Thread Tadeusz Struk
On 06/03/2015 11:53 PM, Herbert Xu wrote:
 I'd like to see this split into multiple patches.  First of all
 the new crypto_akcipher implementation should coexist with the
 existing code.  That way the exiting users can be converted over
 one-by-one.
 
 Also you should implement the crypto_akcipher completely before
 converting anybody over, that means doing encoding/wrapping in
 addition to the crypto.
 
 That way we don't have to have craziness like converting in and
 out of MPI multiple times.

That's cool. It will make it easier for me. I wanted to convert
one to show that the interface is working.

 
 Lastly you should consider adding an MPI helper that writes to
 an existing buffer instead of allocating a new one and copying
 it over.

I'll think about something.

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


Re: [PATCH RFC v3 2/3] crypto: RSA: KEYS: convert rsa and public key to new PKE API

2015-06-05 Thread Tadeusz Struk
On 06/05/2015 01:50 AM, Paul Bolle wrote:
 This builds two modules if PUBLIC_KEY_ALGO_RSA = 'm': rsa.ko and
 rsa_pkcs1_v1_5.ko. Is that what you want?

No, this not what I wanted.

 
 public_key.c uses this, so it can end up in public_key.ko. But it's not
 exported. So a _quick and dirty_ build test generated:
 WARNING: rsa_pkcs1_v1_5_verify_signature 
 [[...]/crypto/asymmetric_keys/public_key.ko] undefined!
 
 Also no MODULE_LICENSE() macro, so loading rsa_pkcs1_v1_5.ko should
 trigger a warning and taint the kernel.

Thank you Paul for taking the time to review the patches and for your feedback.
I'll have to change this again based on Herbert's feedback so this 
rsa_pkcs1_v1_5.c file
will go away anyway.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC v3 3/3] crypto: add tests vectors for RSA

2015-06-04 Thread Tadeusz Struk
Hi Stephan
On 06/03/2015 05:15 PM, Stephan Mueller wrote:
 May I ask that the outbuf_enc is memcmp()ed with an expected value? This 
 check 
 is required for FIPS 140-2 compliance. Without that memcmp, FIPS 140-2 
 validations will not be successful.

Sure, I will do that. I wasn't aware that this was required.

 
 Sorry for bringing that one up just now: 512 and 1024 bit test vectors will 
 not be helpful for several use cases, including FIPS. I can offer to give you 
 2k or 3k vectors.

I have one 2K vector from openSSL fips so I'll use it instead of the 512 one.

 Besides, wouldn't one vector be sufficient?

I think there is no harm to have these 3 vectors to make sure an implementation
is well tested.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: crypto: rsa - select on undefined AKCIPHER

2015-06-18 Thread Tadeusz Struk
On 06/18/2015 01:26 AM, Andreas Ruprecht wrote:
 Hi Tadeusz,
 
 your commit cfc2bb32b313 (crypto: rsa - add a new rsa generic
 implementation) was merged into linux-next today (i.e., next-20150618).
 It changes the crypto/Kconfig file and adds the CRYPTO_RSA config option:
 
 +config CRYPTO_RSA
 + tristate RSA algorithm
 + select AKCIPHER
 [...]
 
 The symbol AKCIPHER, however, is not defined in Kconfig. Did you maybe
 mean CRYPTO_AKCIPHER, which you added in commit 3c339ab83fc0 (crypto:
 akcipher - add PKE API)?
 
 I detected the issue by running undertaker-checkpatch from the
 Undertaker tool suite (https://undertaker.cs.fau.de) as part of an
 automated, daily analysis of the most recent linux-next tree.
 There is also a tool in the Linux tree itself that can detect such
 issues (scripts/checkkconfigsymbols.py).
Hi Andreas,
Yes it should have been CRYPTO_AKCIPHER.
Thanks for reporting this.

--- 8 ---
This patch fixes invalid config selection for AKCIPHER

Reported-by: Andreas Ruprecht andreas.rupre...@fau.de
Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 6c79ef0..b4cfc57 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -102,7 +102,7 @@ config CRYPTO_AKCIPHER
 
 config CRYPTO_RSA
tristate RSA algorithm
-   select AKCIPHER
+   select CRYPTO_AKCIPHER
select MPILIB
select ASN1
help

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


Re: [PATCH v13 1/2] crypto: AF_ALG: add AEAD support

2015-06-11 Thread Tadeusz Struk
Hi Stephan,
On 02/28/2015 11:50 AM, Stephan Mueller wrote:
 + err = af_alg_wait_for_completion(ctx-enc ?
 +  crypto_aead_encrypt(ctx-aead_req) :
 +  crypto_aead_decrypt(ctx-aead_req),
 +  ctx-completion);
 +
 + if (err) {
 + /* EBADMSG implies a valid cipher operation took place */
 + if (err == -EBADMSG)
 + aead_put_sgl(sk);
 + goto unlock;

Shouldn't we free the TX sgl regardless of the error was?
Or do we expect that the user will try to read again and it will be Ok the 
second time?
Hope you still remember :)

 + }
 +
 + aead_put_sgl(sk);
 +
 + err = 0;
 +
 +unlock:
 + for (i = 0; i  cnt; i++)
 + af_alg_free_sg(ctx-rsgl[i]);
 +
 + aead_wmem_wakeup(sk);
 + release_sock(sk);
 +
 + return err ? err : outlen;
 +}

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


[PATCH RFC v7 3/3] crypto: add tests vectors for RSA

2015-06-16 Thread Tadeusz Struk
New test vectors for RSA algorithm.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/Kconfig   |1 
 crypto/testmgr.c |  158 ++
 crypto/testmgr.h |  187 ++
 3 files changed, 346 insertions(+)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 52467cf..9471ac8 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -122,6 +122,7 @@ config CRYPTO_MANAGER2
select CRYPTO_HASH2
select CRYPTO_BLKCIPHER2
select CRYPTO_PCOMP2
+   select CRYPTO_AKCIPHER2
 
 config CRYPTO_USER
tristate Userspace cryptographic algorithm configuration
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index ccd19cf..975e1ea 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -30,6 +30,7 @@
 #include linux/string.h
 #include crypto/rng.h
 #include crypto/drbg.h
+#include crypto/akcipher.h
 
 #include internal.h
 
@@ -116,6 +117,11 @@ struct drbg_test_suite {
unsigned int count;
 };
 
+struct akcipher_test_suite {
+   struct akcipher_testvec *vecs;
+   unsigned int count;
+};
+
 struct alg_test_desc {
const char *alg;
int (*test)(const struct alg_test_desc *desc, const char *driver,
@@ -130,6 +136,7 @@ struct alg_test_desc {
struct hash_test_suite hash;
struct cprng_test_suite cprng;
struct drbg_test_suite drbg;
+   struct akcipher_test_suite akcipher;
} suite;
 };
 
@@ -1825,6 +1832,147 @@ static int alg_test_drbg(const struct alg_test_desc 
*desc, const char *driver,
 
 }
 
+static int do_test_rsa(struct crypto_akcipher *tfm,
+  struct akcipher_testvec *vecs)
+{
+   struct akcipher_request *req;
+   void *outbuf_enc = NULL;
+   void *outbuf_dec = NULL;
+   struct tcrypt_result result;
+   unsigned int out_len_max, out_len = 0;
+   int err = -ENOMEM;
+
+   req = akcipher_request_alloc(tfm, GFP_KERNEL);
+   if (!req)
+   return err;
+
+   init_completion(result.completion);
+   err = crypto_akcipher_setkey(tfm, vecs-key, vecs-key_len);
+   if (err)
+   goto free_req;
+
+   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;
+   goto free_req;
+   }
+
+   out_len_max = out_len;
+   err = -ENOMEM;
+   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);
+   akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ tcrypt_complete, result);
+
+   /* Run RSA encrypt - c = m^e mod n;*/
+   err = wait_async_op(result, crypto_akcipher_encrypt(req));
+   if (err) {
+   pr_err(alg: rsa: encrypt test failed. err %d\n, err);
+   goto free_all;
+   }
+   if (out_len != vecs-c_size) {
+   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)) {
+   pr_err(alg: rsa: encrypt test failed. Invalid output\n);
+   err = -EINVAL;
+   goto free_all;
+   }
+   /* Don't invoke decrypt for vectors with public key */
+   if (vecs-public_key_vec) {
+   err = 0;
+   goto free_all;
+   }
+   outbuf_dec = kzalloc(out_len_max, GFP_KERNEL);
+   if (!outbuf_dec) {
+   err = -ENOMEM;
+   goto free_all;
+   }
+   init_completion(result.completion);
+   akcipher_request_set_crypt(req, outbuf_enc, outbuf_dec, vecs-c_size,
+  out_len);
+
+   /* Run RSA decrypt - m = c^d mod n;*/
+   err = wait_async_op(result, crypto_akcipher_decrypt(req));
+   if (err) {
+   pr_err(alg: rsa: decrypt test failed. err %d\n, err);
+   goto free_all;
+   }
+   out_len = req-dst_len;
+   if (out_len != vecs-m_size) {
+   pr_err(alg: rsa: decrypt test failed. Invalid output len\n);
+   err = -EINVAL;
+   goto free_all;
+   }
+   /* verify that decrypted message is equal to the original msg */
+   if (memcmp(vecs-m, outbuf_dec, vecs-m_size)) {
+   pr_err(alg: rsa: decrypt test failed. Invalid output\n);
+   err = -EINVAL;
+   }
+free_all:
+   kfree(outbuf_dec);
+   kfree(outbuf_enc);
+free_req:
+   akcipher_request_free(req);
+   return err

[PATCH RFC v7 0/3] crypto: Introduce Public Key Encryption API

2015-06-16 Thread Tadeusz Struk
This patch set introduces a Public Key Encryption API.
What is proposed is a new crypto type called crypto_akcipher_type,
plus new struct akcipher_alg and struct crypto_akcipher, together with number
of helper functions to register akcipher type algorithms and allocate
tfm instances. This is to make it similar to how the existing crypto
API works for the ablkcipher, ahash, and aead types.
The operations the new interface will allow to provide are:

int (*sign)(struct akcipher_request *req);
int (*verify)(struct akcipher_request *req);
int (*encrypt)(struct akcipher_request *req);
int (*decrypt)(struct akcipher_request *req);

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

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

struct crypto_akcipher *tfm = crypto_alloc_akcipher(rsa, 0, 0);
struct akcipher_request *req = akcipher_request_alloc(tfm, GFP_KERNEL);
akcipher_request_set_crypt(req, pub_key, signature);
int ret = crypto_akcipher_verify(src, dst, src_len, dst_len, res_len);
akcipher_request_free(req);
crypto_free_akcipher(tfm);
return ret;

Changes in v7:
 - change req-dst_len to be int instead of int *
 - remove result_len from comments - it's not longer there
 - use crypto_akcipher_reqtfm helper instead of __crypto_akcipher_tfm
 - fix memleak in rsa.c
 - change error code to -EOVERFLOW if dst buf is not big enough
 - drop redundant cra_ctxsize inits
 - add type-safe init/exit functions
 - cleanup headers in rsa_helpers
 - remove checks for NULL before mpi_free

Changes in v6:
 - in FIPS mode only allow key sizes 2K  3K
 - remove result_len and use dst_len as in/out param
 - remove subtype from akcipher reports
 - store rsa_key in tfm ctx and change ras_parse_key to take struct rsa_key
   instead of tfm. 
 - export rsa_free_key, which free memory allocated by ras_parse_key.
 - split akcipher.h into public and internal with public key specific helpers
 - remove maxsize() and set the required size in enc/dec/sign/verify instead
 - add public key vector
 - split AKCIPHER into AKCIPHER and AKCIPHER2 in Kconfig
 - remove MPI patch from the series - already applied

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

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

Changes in v3:
 - changed input and output parameters type from sgl to void *
   and added separate src_len  dst_len - requested by Herbert Xu
 - separated rsa implementation into cryptographic primitives and
   left encryption scheme details outside of the algorithm implementation
 - added SW implementation for RSA encrypt, decrypt and sign operation
 - added RSA test vectors 
   
Changes in v2:
 - remodeled not to use obsolete cra_u and crt_u unions
 - changed type/funct names from pke_* to pkey_*
 - retained the enum pkey_algo type for it is external to the kernel
 - added documentation

---
Tadeusz Struk (3):
  crypto: add PKE API
  crypto: rsa: add a new rsa generic implementation
  crypto: add tests vectors for RSA


 crypto/Kconfig |   19 ++
 crypto/Makefile|9

[PATCH RFC v7 2/3] crypto: rsa: add a new rsa generic implementation

2015-06-16 Thread Tadeusz Struk
Add a new rsa generic SW implementation.
This implements only cryptographic primitives.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/Kconfig|7 +
 crypto/Makefile   |8 +
 crypto/rsa.c  |  315 +
 crypto/rsa_helper.c   |  121 
 crypto/rsakey.asn1|5 +
 include/crypto/internal/rsa.h |   27 
 6 files changed, 483 insertions(+)
 create mode 100644 crypto/rsa.c
 create mode 100644 crypto/rsa_helper.c
 create mode 100644 crypto/rsakey.asn1
 create mode 100644 include/crypto/internal/rsa.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 264dadb..52467cf 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -102,6 +102,13 @@ config CRYPTO_AKCIPHER
help
  Crypto API interface for public key algorithms.
 
+config CRYPTO_RSA
+   tristate RSA algorithm
+   select AKCIPHER
+   select MPILIB
+   help
+ Generic implementation of the RSA public key algorithm.
+
 config CRYPTO_MANAGER
tristate Cryptographic algorithm manager
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 1ed382d..0077476 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -30,6 +30,14 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
 obj-$(CONFIG_CRYPTO_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/rsa.c b/crypto/rsa.c
new file mode 100644
index 000..752af06
--- /dev/null
+++ b/crypto/rsa.c
@@ -0,0 +1,315 @@
+/* RSA asymmetric public-key algorithm [RFC3447]
+ *
+ * Copyright (c) 2015, Intel Corporation
+ * Authors: Tadeusz Struk tadeusz.st...@intel.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include linux/module.h
+#include crypto/internal/rsa.h
+#include crypto/internal/akcipher.h
+#include crypto/akcipher.h
+
+/*
+ * RSAEP function [RFC3447 sec 5.1.1]
+ * c = m^e mod n;
+ */
+static int _rsa_enc(const struct rsa_key *key, MPI c, MPI m)
+{
+   /* (1) Validate 0 = m  n */
+   if (mpi_cmp_ui(m, 0)  0 || mpi_cmp(m, key-n) = 0)
+   return -EINVAL;
+
+   /* (2) c = m^e mod n */
+   return mpi_powm(c, m, key-e, key-n);
+}
+
+/*
+ * RSADP function [RFC3447 sec 5.1.2]
+ * m = c^d mod n;
+ */
+static int _rsa_dec(const struct rsa_key *key, MPI m, MPI c)
+{
+   /* (1) Validate 0 = c  n */
+   if (mpi_cmp_ui(c, 0)  0 || mpi_cmp(c, key-n) = 0)
+   return -EINVAL;
+
+   /* (2) m = c^d mod n */
+   return mpi_powm(m, c, key-d, key-n);
+}
+
+/*
+ * RSASP1 function [RFC3447 sec 5.2.1]
+ * s = m^d mod n
+ */
+static int _rsa_sign(const struct rsa_key *key, MPI s, MPI m)
+{
+   /* (1) Validate 0 = m  n */
+   if (mpi_cmp_ui(m, 0)  0 || mpi_cmp(m, key-n) = 0)
+   return -EINVAL;
+
+   /* (2) s = m^d mod n */
+   return mpi_powm(s, m, key-d, key-n);
+}
+
+/*
+ * RSAVP1 function [RFC3447 sec 5.2.2]
+ * m = s^e mod n;
+ */
+static int _rsa_verify(const struct rsa_key *key, MPI m, MPI s)
+{
+   /* (1) Validate 0 = s  n */
+   if (mpi_cmp_ui(s, 0)  0 || mpi_cmp(s, key-n) = 0)
+   return -EINVAL;
+
+   /* (2) m = s^e mod n */
+   return mpi_powm(m, s, key-e, key-n);
+}
+
+static inline struct rsa_key *rsa_get_key(struct crypto_akcipher *tfm)
+{
+   return akcipher_tfm_ctx(tfm);
+}
+
+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 ret = 0;
+   int sign;
+
+   if (!c)
+   return -ENOMEM;
+
+   if (unlikely(!pkey-n || !pkey-e)) {
+   ret = -EINVAL;
+   goto err_free_c;
+   }
+
+   if (req-dst_len  mpi_get_size(pkey-n)) {
+   req-dst_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 = _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 (ret)
+   goto err_free_m;
+
+   if (sign  0) {
+   ret = -EBADMSG;
+   goto err_free_m;
+   }
+
+err_free_m

[PATCH RFC v7 1/3] crypto: add PKE API

2015-06-16 Thread Tadeusz Struk
Add Public Key Encryption API.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/Kconfig |   11 +
 crypto/Makefile|1 
 crypto/akcipher.c  |  117 
 crypto/crypto_user.c   |   22 ++
 include/crypto/akcipher.h  |  340 
 include/crypto/internal/akcipher.h |   60 ++
 include/linux/crypto.h |1 
 include/linux/cryptouser.h |5 +
 8 files changed, 557 insertions(+)
 create mode 100644 crypto/akcipher.c
 create mode 100644 include/crypto/akcipher.h
 create mode 100644 include/crypto/internal/akcipher.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index f6fc054..264dadb 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -91,6 +91,17 @@ config CRYPTO_PCOMP2
tristate
select CRYPTO_ALGAPI2
 
+config CRYPTO_AKCIPHER2
+   tristate
+   select CRYPTO_ALGAPI2
+
+config CRYPTO_AKCIPHER
+   tristate Public Key Algorithms API
+   select CRYPTO_AKCIPHER2
+   select CRYPTO_ALGAPI
+   help
+ Crypto API interface for public key algorithms.
+
 config CRYPTO_MANAGER
tristate Cryptographic algorithm manager
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index c842035..1ed382d 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -28,6 +28,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
+obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 
 cryptomgr-y := algboss.o testmgr.o
 
diff --git a/crypto/akcipher.c b/crypto/akcipher.c
new file mode 100644
index 000..d798641
--- /dev/null
+++ b/crypto/akcipher.c
@@ -0,0 +1,117 @@
+/*
+ * Public Key Encryption
+ *
+ * Copyright (c) 2015, Intel Corporation
+ * Authors: Tadeusz Struk tadeusz.st...@intel.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include linux/errno.h
+#include linux/kernel.h
+#include linux/module.h
+#include linux/seq_file.h
+#include linux/slab.h
+#include linux/string.h
+#include linux/crypto.h
+#include crypto/algapi.h
+#include linux/cryptouser.h
+#include net/netlink.h
+#include crypto/akcipher.h
+#include crypto/public_key.h
+#include internal.h
+
+#ifdef CONFIG_NET
+static int crypto_akcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_akcipher rakcipher;
+
+   strncpy(rakcipher.type, akcipher, sizeof(rakcipher.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_AKCIPHER,
+   sizeof(struct crypto_report_akcipher), rakcipher))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_akcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+static void crypto_akcipher_show(struct seq_file *m, struct crypto_alg *alg)
+   __attribute__ ((unused));
+
+static void crypto_akcipher_show(struct seq_file *m, struct crypto_alg *alg)
+{
+   seq_puts(m, type : akcipher\n);
+}
+
+static void crypto_akcipher_exit_tfm(struct crypto_tfm *tfm)
+{
+   struct crypto_akcipher *akcipher = __crypto_akcipher_tfm(tfm);
+   struct akcipher_alg *alg = crypto_akcipher_alg(akcipher);
+
+   alg-exit(akcipher);
+}
+
+static int crypto_akcipher_init_tfm(struct crypto_tfm *tfm)
+{
+   struct crypto_akcipher *akcipher = __crypto_akcipher_tfm(tfm);
+   struct akcipher_alg *alg = crypto_akcipher_alg(akcipher);
+
+   if (alg-exit)
+   akcipher-base.exit = crypto_akcipher_exit_tfm;
+
+   if (alg-init)
+   return alg-init(akcipher);
+
+   return 0;
+}
+
+static const struct crypto_type crypto_akcipher_type = {
+   .extsize = crypto_alg_extsize,
+   .init_tfm = crypto_akcipher_init_tfm,
+#ifdef CONFIG_PROC_FS
+   .show = crypto_akcipher_show,
+#endif
+   .report = crypto_akcipher_report,
+   .maskclear = ~CRYPTO_ALG_TYPE_MASK,
+   .maskset = CRYPTO_ALG_TYPE_MASK,
+   .type = CRYPTO_ALG_TYPE_AKCIPHER,
+   .tfmsize = offsetof(struct crypto_akcipher, base),
+};
+
+struct crypto_akcipher *crypto_alloc_akcipher(const char *alg_name, u32 type,
+ u32 mask)
+{
+   return crypto_alloc_tfm(alg_name, crypto_akcipher_type, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_alloc_akcipher);
+
+int crypto_register_akcipher(struct akcipher_alg *alg)
+{
+   struct crypto_alg *base = alg-base;
+
+   base-cra_type = crypto_akcipher_type;
+   base-cra_flags = ~CRYPTO_ALG_TYPE_MASK;
+   base-cra_flags |= CRYPTO_ALG_TYPE_AKCIPHER;
+   return crypto_register_alg(base);
+}
+EXPORT_SYMBOL_GPL(crypto_register_akcipher);
+
+void

Re: [PATCH RFC v4 2/4] crypto: add PKE API

2015-06-12 Thread Tadeusz Struk
On 06/11/2015 07:59 PM, Herbert Xu wrote:
 +int crypto_akcipher_setkey(struct crypto_akcipher *tfm,
  + const struct public_key *pkey)
  +{
  +  if (tfm-pkey)
  +  akcipher_free_key(tfm-pkey);
  +
  +  return akcipher_clone_key(tfm, pkey);
  +}
 No please do not expose the struct public_key crap to the new
 API.  The key should be completely opaque to entities outside
 of the algorithm.  So make it raw and read out the MPIs from
 it.
 
 The contents of the function must go into the algorithm setkey
 function, not the crypto API.  So RSA would read out however
 many MPIs it needs and verify it, and so on.

Should I make it MPI[] rather than void *
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC v4 1/4] MPILIB: add mpi_read_buf(), mpi_copy() and mpi_get_size() helpers

2015-06-12 Thread Tadeusz Struk
On 06/12/2015 09:21 AM, Stephan Mueller wrote:
 +void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign)
 +{
 +   uint8_t *buf, *p;
 +   int n, ret;
 +
 +   if (!nbytes)
 +   return NULL;
 +
 +   n = mpi_get_size(a);
 Shouldn't n be unsigned int?

You are right, thanks.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC v7 2/3] crypto: rsa: add a new rsa generic implementation

2015-06-16 Thread Tadeusz Struk
Hi David,
On 06/16/2015 03:10 PM, David Howells wrote:
 +static int _rsa_sign(const struct rsa_key *key, MPI s, MPI m)
  +{
  +  /* (1) Validate 0 = m  n */
  +  if (mpi_cmp_ui(m, 0)  0 || mpi_cmp(m, key-n) = 0)
  +  return -EINVAL;
 Why -EINVAL not -EBADMSG?

I thought that -EBADMSG was mainly used for authenticated ciphers in case when 
verification of auth data fails.
Since this are input params I thought that -EINVAL would be more appropriate.
I can change it to -EBADMSG, no problem.
Herbert, what do you think?
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC v7 2/3] crypto: rsa: add a new rsa generic implementation

2015-06-16 Thread Tadeusz Struk
On 06/16/2015 07:36 PM, Herbert Xu wrote:
 The existing crypto/asymmetric_key errno scheme doesn't really
 mesh in with the rest of crypto.  So you'll just have to pick one
 scheme and stick with it.
 
 I don't really mind either way as long as the error codes are
 unique and meaningful.

So I would use -EINVAL since these are input parameters. Do you agree David?
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC v7 0/3] crypto: Introduce Public Key Encryption API

2015-06-17 Thread Tadeusz Struk
On 06/17/2015 02:14 AM, Herbert Xu wrote:
 This patch set introduces a Public Key Encryption API.
  What is proposed is a new crypto type called crypto_akcipher_type,
  plus new struct akcipher_alg and struct crypto_akcipher, together with 
  number
  of helper functions to register akcipher type algorithms and allocate
  tfm instances. This is to make it similar to how the existing crypto
  API works for the ablkcipher, ahash, and aead types.
  The operations the new interface will allow to provide are:
  
 int (*sign)(struct akcipher_request *req);
 int (*verify)(struct akcipher_request *req);
 int (*encrypt)(struct akcipher_request *req);
 int (*decrypt)(struct akcipher_request *req);
 All applied with two minor changes.  First of all I made AKCIPHER
 invisible to the user like the other type config options.  I also
 added a missing select on ASN1 that broke my build.

Thank you very much for all your help with this Herbert

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


Re: [PATCH RFC v5 2/4] crypto: add PKE API

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

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

  + *
  + * @reqsize:  Request context size required by algorithm 
  implementation
  + * @base: Common crypto API algorithm data structure
  + */
  +struct akcipher_alg {
  +  int (*sign)(struct akcipher_request *req);
  +  int (*verify)(struct akcipher_request *req);
  +  int (*encrypt)(struct akcipher_request *req);
  +  int (*decrypt)(struct akcipher_request *req);
  +  int (*maxsize)(struct crypto_akcipher *tfm);
 Hmm, we could actually get rid of maxsize by just having each
 function check the dst_len and if it is insufficient write the
 required length in it and then return an error.

Can do it that way too.
Thanks for your feedback. I will send v6 soon.
Thanks
T
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC v5 2/4] crypto: add PKE API

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

Ok I'll do it that way.

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

Oh yes, it is definitely optional.
Thanks
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC v5 4/4] crypto: add tests vectors for RSA

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

This causes a recursive dependency error

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

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


Re: [PATCH RFC v5 2/4] crypto: add PKE API

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

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



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


Re: [PATCH RFC v5 2/4] crypto: add PKE API

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

I've just tested it and it works fine for both private and public keys.
I'll add one vector to test only public key case.
Thanks
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC v5 2/4] crypto: add PKE API

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

I thought that the ctx needs to be available for implementations to store 
private data.
This way we can allocate and store any type of key in the alg_parse_key() 
helper and still have the cxt
available for implementations to use for their stuff (e.g. HW context).
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC v5 2/4] crypto: add PKE API

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

Actually I think it is useful. Without it the user will need to allocate
a buffer, and invoke an operation only to find out that the buffer need to be
bigger.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC v5 3/4] crypto: rsa: add a new rsa generic implementation

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

Ok I'll update it to only accept 2K  3K. Thanks
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RFC v5 3/4] crypto: rsa: add a new rsa generic implementation

2015-06-15 Thread Tadeusz Struk
Add a new rsa generic SW implementation.
This implements only cryptographic primitives.

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

diff --git a/crypto/Kconfig b/crypto/Kconfig
index ed413d9..a09404b 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -97,6 +97,13 @@ config CRYPTO_AKCIPHER
help
  Crypto API interface for public key algorithms.
 
+config CRYPTO_RSA
+   tristate RSA algorithm
+   select AKCIPHER
+   select MPILIB
+   help
+ Generic implementation of the RSA public key algorithm.
+
 config CRYPTO_MANAGER
tristate Cryptographic algorithm manager
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 6f2940a..c6217ea 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -30,6 +30,14 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
 obj-$(CONFIG_CRYPTO_AKCIPHER) += akcipher.o
 
+$(obj)/rsakey-asn1.o: $(obj)/rsakey-asn1.c $(obj)/rsakey-asn1.h
+clean-files += rsakey-asn1.c rsakey-asn1.h
+
+rsa_generic-y := rsakey-asn1.o
+rsa_generic-y += rsa.o
+rsa_generic-y += rsa_helper.o
+obj-$(CONFIG_CRYPTO_RSA) += rsa_generic.o
+
 cryptomgr-y := algboss.o testmgr.o
 
 obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o
diff --git a/crypto/rsa.c b/crypto/rsa.c
new file mode 100644
index 000..176f565
--- /dev/null
+++ b/crypto/rsa.c
@@ -0,0 +1,295 @@
+/* RSA asymmetric public-key algorithm [RFC3447]
+ *
+ * Copyright (c) 2015, Intel Corporation
+ * Authors: Tadeusz Struk tadeusz.st...@intel.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include linux/module.h
+#include crypto/internal/rsa.h
+#include crypto/akcipher.h
+
+/*
+ * RSAEP function [RFC3447 sec 5.1.1]
+ * c = m^e mod n;
+ */
+static int _rsa_enc(const struct rsa_key *key, MPI c, MPI m)
+{
+   /* (1) Validate 0 = m  n */
+   if (mpi_cmp_ui(m, 0)  0 || mpi_cmp(m, key-n) = 0)
+   return -EINVAL;
+
+   /* (2) c = m^e mod n */
+   return mpi_powm(c, m, key-e, key-n);
+}
+
+/*
+ * RSADP function [RFC3447 sec 5.1.2]
+ * m = c^d mod n;
+ */
+static int _rsa_dec(const struct rsa_key *key, MPI m, MPI c)
+{
+   /* (1) Validate 0 = c  n */
+   if (mpi_cmp_ui(c, 0)  0 || mpi_cmp(c, key-n) = 0)
+   return -EINVAL;
+
+   /* (2) m = c^d mod n */
+   return mpi_powm(m, c, key-d, key-n);
+}
+
+/*
+ * RSASP1 function [RFC3447 sec 5.2.1]
+ * s = m^d mod n
+ */
+static int _rsa_sign(const struct rsa_key *key, MPI s, MPI m)
+{
+   /* (1) Validate 0 = m  n */
+   if (mpi_cmp_ui(m, 0)  0 || mpi_cmp(m, key-n) = 0)
+   return -EINVAL;
+
+   /* (2) s = m^d mod n */
+   return mpi_powm(s, m, key-d, key-n);
+}
+
+/*
+ * RSAVP1 function [RFC3447 sec 5.2.2]
+ * m = s^e mod n;
+ */
+static int _rsa_verify(const struct rsa_key *key, MPI m, MPI s)
+{
+   /* (1) Validate 0 = s  n */
+   if (mpi_cmp_ui(s, 0)  0 || mpi_cmp(s, key-n) = 0)
+   return -EINVAL;
+
+   /* (2) m = s^e mod n */
+   return mpi_powm(m, s, key-e, key-n);
+}
+
+static int rsa_enc(struct akcipher_request *req)
+{
+   struct crypto_akcipher *tfm = akcipher_request_get_tfm(req);
+   const struct rsa_key *pkey = rsa_get_key(tfm);
+   MPI m, c = mpi_alloc(0);
+   unsigned int len;
+   int ret = 0;
+   int sign;
+
+   if (!c)
+   return -ENOMEM;
+
+   if (!pkey-n || !pkey-e || req-dst_len  mpi_get_size(pkey-n))
+   return -EINVAL;
+
+   m = mpi_read_raw_data(req-src, req-src_len);
+   if (!m) {
+   ret = -ENOMEM;
+   goto err_free_c;
+   }
+
+   ret = _rsa_enc(pkey, c, m);
+   if (ret)
+   goto err_free_m;
+
+   ret = mpi_read_buffer(c, req-dst, req-dst_len, len, sign);
+   if (ret)
+   goto err_free_m;
+
+   if (sign  0) {
+   ret = -EBADMSG;
+   goto err_free_m;
+   }
+
+   if (req-result_len)
+   *req-result_len = len;
+
+err_free_m:
+   mpi_free(m);
+err_free_c:
+   mpi_free(c);
+   return ret;
+}
+
+static int rsa_dec(struct akcipher_request *req)
+{
+   struct crypto_akcipher *tfm = akcipher_request_get_tfm(req);
+   const struct rsa_key *pkey = rsa_get_key(tfm

[PATCH RFC v5 2/4] crypto: add PKE API

2015-06-15 Thread Tadeusz Struk
Add Public Key Encryption API.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/Kconfig |6 +
 crypto/Makefile|1 
 crypto/akcipher.c  |  102 +++
 crypto/crypto_user.c   |   23 +++
 include/crypto/akcipher.h  |  404 
 include/linux/crypto.h |1 
 include/linux/cryptouser.h |6 +
 7 files changed, 543 insertions(+)
 create mode 100644 crypto/akcipher.c
 create mode 100644 include/crypto/akcipher.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index f6fc054..ed413d9 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -91,6 +91,12 @@ config CRYPTO_PCOMP2
tristate
select CRYPTO_ALGAPI2
 
+config CRYPTO_AKCIPHER
+   tristate Public Key Algorithms API
+   select CRYPTO_ALGAPI
+   help
+ Crypto API interface for public key algorithms.
+
 config CRYPTO_MANAGER
tristate Cryptographic algorithm manager
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index c842035..6f2940a 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -28,6 +28,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
+obj-$(CONFIG_CRYPTO_AKCIPHER) += akcipher.o
 
 cryptomgr-y := algboss.o testmgr.o
 
diff --git a/crypto/akcipher.c b/crypto/akcipher.c
new file mode 100644
index 000..be65374
--- /dev/null
+++ b/crypto/akcipher.c
@@ -0,0 +1,102 @@
+/*
+ * Public Key Encryption
+ *
+ * Copyright (c) 2015, Intel Corporation
+ * Authors: Tadeusz Struk tadeusz.st...@intel.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include linux/errno.h
+#include linux/kernel.h
+#include linux/module.h
+#include linux/seq_file.h
+#include linux/slab.h
+#include linux/string.h
+#include linux/crypto.h
+#include crypto/algapi.h
+#include linux/cryptouser.h
+#include net/netlink.h
+#include crypto/akcipher.h
+#include crypto/public_key.h
+#include internal.h
+
+#ifdef CONFIG_NET
+static int crypto_akcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_akcipher rakcipher;
+
+   strncpy(rakcipher.type, akcipher, sizeof(rakcipher.type));
+   strncpy(rakcipher.subtype, alg-cra_name, sizeof(rakcipher.subtype));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_AKCIPHER,
+   sizeof(struct crypto_report_akcipher), rakcipher))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_akcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+static void crypto_akcipher_show(struct seq_file *m, struct crypto_alg *alg)
+   __attribute__ ((unused));
+
+static void crypto_akcipher_show(struct seq_file *m, struct crypto_alg *alg)
+{
+   seq_puts(m, type : akcipher\n);
+   seq_printf(m, subtype  : %s\n, alg-cra_name);
+}
+
+static int crypto_akcipher_init_tfm(struct crypto_tfm *tfm)
+{
+   return 0;
+}
+
+static const struct crypto_type crypto_akcipher_type = {
+   .extsize = crypto_alg_extsize,
+   .init_tfm = crypto_akcipher_init_tfm,
+#ifdef CONFIG_PROC_FS
+   .show = crypto_akcipher_show,
+#endif
+   .report = crypto_akcipher_report,
+   .maskclear = ~CRYPTO_ALG_TYPE_MASK,
+   .maskset = CRYPTO_ALG_TYPE_MASK,
+   .type = CRYPTO_ALG_TYPE_AKCIPHER,
+   .tfmsize = offsetof(struct crypto_akcipher, base),
+};
+
+struct crypto_akcipher *crypto_alloc_akcipher(const char *alg_name, u32 type,
+ u32 mask)
+{
+   return crypto_alloc_tfm(alg_name, crypto_akcipher_type, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_alloc_akcipher);
+
+int crypto_register_akcipher(struct akcipher_alg *alg)
+{
+   struct crypto_alg *base = alg-base;
+
+   base-cra_type = crypto_akcipher_type;
+   base-cra_flags = ~CRYPTO_ALG_TYPE_MASK;
+   base-cra_flags |= CRYPTO_ALG_TYPE_AKCIPHER;
+   return crypto_register_alg(base);
+}
+EXPORT_SYMBOL_GPL(crypto_register_akcipher);
+
+void crypto_unregister_akcipher(struct akcipher_alg *alg)
+{
+   crypto_unregister_alg(alg-base);
+}
+EXPORT_SYMBOL_GPL(crypto_unregister_akcipher);
+
+MODULE_LICENSE(GPL);
+MODULE_DESCRIPTION(Generic public key cihper type);
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 41dfe76..508e71d 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -27,6 +27,7 @@
 #include net/net_namespace.h
 #include crypto/internal/aead.h
 #include crypto/internal/skcipher.h
+#include crypto/akcipher.h
 
 #include internal.h
 
@@ -110,6 +111,22 @@ nla_put_failure:
return -EMSGSIZE;
 }
 
+static int crypto_report_akcipher(struct sk_buff *skb, struct

[PATCH RFC v5 4/4] crypto: add tests vectors for RSA

2015-06-15 Thread Tadeusz Struk
New test vectors for RSA algorithm.

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

diff --git a/crypto/Kconfig b/crypto/Kconfig
index a09404b..90c1f77 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -107,6 +107,7 @@ config CRYPTO_RSA
 config CRYPTO_MANAGER
tristate Cryptographic algorithm manager
select CRYPTO_MANAGER2
+   select CRYPTO_AKCIPHER
help
  Create default cryptographic template instantiations such as
  cbc(aes).
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index ccd19cf..ff41714 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -30,6 +30,7 @@
 #include linux/string.h
 #include crypto/rng.h
 #include crypto/drbg.h
+#include crypto/akcipher.h
 
 #include internal.h
 
@@ -116,6 +117,11 @@ struct drbg_test_suite {
unsigned int count;
 };
 
+struct akcipher_test_suite {
+   struct akcipher_testvec *vecs;
+   unsigned int count;
+};
+
 struct alg_test_desc {
const char *alg;
int (*test)(const struct alg_test_desc *desc, const char *driver,
@@ -130,6 +136,7 @@ struct alg_test_desc {
struct hash_test_suite hash;
struct cprng_test_suite cprng;
struct drbg_test_suite drbg;
+   struct akcipher_test_suite akcipher;
} suite;
 };
 
@@ -1825,6 +1832,138 @@ static int alg_test_drbg(const struct alg_test_desc 
*desc, const char *driver,
 
 }
 
+static int do_test_rsa(struct crypto_akcipher *tfm,
+  struct akcipher_testvec *vecs)
+{
+   struct akcipher_request *req;
+   void *outbuf_enc = NULL;
+   void *outbuf_dec = NULL;
+   struct tcrypt_result result;
+   unsigned int max_out_len, out_len;
+   int err = -ENOMEM;
+
+   req = akcipher_request_alloc(tfm, GFP_KERNEL);
+   if (!req)
+   return err;
+
+   init_completion(result.completion);
+   err = crypto_akcipher_setkey(tfm, vecs-key, vecs-key_len);
+   if (err)
+   goto free_req;
+
+   err = -EINVAL;
+   max_out_len = crypto_akcipher_maxsize(tfm);
+   if (!(max_out_len  0))
+   goto free_req;
+
+   err = -ENOMEM;
+   outbuf_enc = kzalloc(max_out_len, GFP_KERNEL);
+   if (!outbuf_enc)
+   goto free_req;
+
+   akcipher_request_set_crypt(req, vecs-m, outbuf_enc, vecs-m_size,
+  max_out_len, out_len);
+   akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ tcrypt_complete, result);
+
+   /* Run RSA encrypt - c = m^e mod n;*/
+   err = wait_async_op(result, crypto_akcipher_encrypt(req));
+   if (err) {
+   pr_err(alg: rsa: encrypt test failed. err %d\n, err);
+   goto free_all;
+   }
+
+   if (out_len != vecs-c_size) {
+   err = -EINVAL;
+   goto free_all;
+   }
+   /* verify that encrypted message is equal to expected */
+   if (memcmp(vecs-c, outbuf_enc, vecs-c_size)) {
+   pr_err(alg: rsa: encrypt test failed. Invalid output\n);
+   err = -EINVAL;
+   goto free_all;
+   }
+
+   outbuf_dec = kzalloc(max_out_len, GFP_KERNEL);
+   if (!outbuf_dec) {
+   err = -ENOMEM;
+   goto free_all;
+   }
+
+   init_completion(result.completion);
+   akcipher_request_set_crypt(req, outbuf_enc, outbuf_dec, vecs-c_size,
+  max_out_len, out_len);
+
+   /* Run RSA decrypt - m = c^d mod n;*/
+   err = wait_async_op(result, crypto_akcipher_decrypt(req));
+   if (err) {
+   pr_err(alg: rsa: decrypt test failed. err %d\n, err);
+   goto free_all;
+   }
+
+   if (out_len != vecs-m_size) {
+   err = -EINVAL;
+   goto free_all;
+   }
+
+   /* verify that decrypted message is equal to the original msg */
+   if (memcmp(vecs-m, outbuf_dec, vecs-m_size)) {
+   pr_err(alg: rsa: encrypt test failed. Invalid output\n);
+   err = -EINVAL;
+   }
+free_all:
+   kfree(outbuf_dec);
+   kfree(outbuf_enc);
+free_req:
+   akcipher_request_free(req);
+   return err;
+}
+
+static int test_rsa(struct crypto_akcipher *tfm, struct akcipher_testvec *vecs,
+   unsigned int tcount)
+{
+   int ret, i;
+
+   for (i = 0; i  tcount; i++) {
+   ret = do_test_rsa(tfm, vecs++);
+   if (ret) {
+   pr_err(alg: rsa: test failed on vector %d, err=%d\n,
+  i + 1, ret);
+   return ret;
+   }
+   }
+   return 0;
+}
+
+static int test_akcipher(struct crypto_akcipher *tfm

[PATCH RFC v5 1/4] MPILIB: add mpi_read_buf() and mpi_get_size() helpers

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

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

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

[PATCH RFC v5 0/4] crypto: Introduce Public Key Encryption API

2015-06-15 Thread Tadeusz Struk
This patch set introduces a Public Key Encryption API.
What is proposed is a new crypto type called crypto_akcipher_type,
plus new struct akcipher_alg and struct crypto_akcipher, together with number
of helper functions to register akcipher type algorithms and allocate
tfm instances. This is to make it similar to how the existing crypto
API works for the ablkcipher, ahash, and aead types.
The operations the new interface will allow to provide are:

int (*sign)(struct akcipher_request *req);
int (*verify)(struct akcipher_request *req);
int (*encrypt)(struct akcipher_request *req);
int (*decrypt)(struct akcipher_request *req);

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

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

struct crypto_akcipher *tfm = crypto_alloc_akcipher(rsa, 0, 0);
struct akcipher_request *req = akcipher_request_alloc(tfm, GFP_KERNEL);
akcipher_request_set_crypt(req, pub_key, signature);
int ret = crypto_akcipher_verify(src, dst, src_len, dst_len, res_len);
akcipher_request_free(req);
crypto_free_akcipher(tfm);
return ret;

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

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

Changes in v3:
 - changed input and output parameters type from sgl to void *
   and added separate src_len  dst_len - requested by Herbert Xu
 - separated rsa implementation into cryptographic primitives and
   left encryption scheme details outside of the algorithm implementation
 - added SW implementation for RSA encrypt, decrypt and sign operation
 - added RSA test vectors 
   
Changes in v2:
 - remodeled not to use obsolete cra_u and crt_u unions
 - changed type/funct names from pke_* to pkey_*
 - retained the enum pkey_algo type for it is external to the kernel
 - added documentation

---
Tadeusz Struk (4):
  MPILIB: add mpi_read_buf(), mpi_copy() and mpi_get_size() helpers
  crypto: add PKE API
  crypto: rsa: add a new rsa generic implementation
  crypto: add tests vectors for RSA


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

[PATCH RFC v6 2/3] crypto: rsa: add a new rsa generic implementation

2015-06-16 Thread Tadeusz Struk
Add a new rsa generic SW implementation.
This implements only cryptographic primitives.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/Kconfig|7 +
 crypto/Makefile   |8 +
 crypto/rsa.c  |  313 +
 crypto/rsa_helper.c   |  124 
 crypto/rsakey.asn1|5 +
 include/crypto/internal/rsa.h |   28 
 6 files changed, 485 insertions(+)
 create mode 100644 crypto/rsa.c
 create mode 100644 crypto/rsa_helper.c
 create mode 100644 crypto/rsakey.asn1
 create mode 100644 include/crypto/internal/rsa.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 264dadb..52467cf 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -102,6 +102,13 @@ config CRYPTO_AKCIPHER
help
  Crypto API interface for public key algorithms.
 
+config CRYPTO_RSA
+   tristate RSA algorithm
+   select AKCIPHER
+   select MPILIB
+   help
+ Generic implementation of the RSA public key algorithm.
+
 config CRYPTO_MANAGER
tristate Cryptographic algorithm manager
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 6f2940a..c6217ea 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -30,6 +30,14 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
 obj-$(CONFIG_CRYPTO_AKCIPHER) += akcipher.o
 
+$(obj)/rsakey-asn1.o: $(obj)/rsakey-asn1.c $(obj)/rsakey-asn1.h
+clean-files += rsakey-asn1.c rsakey-asn1.h
+
+rsa_generic-y := rsakey-asn1.o
+rsa_generic-y += rsa.o
+rsa_generic-y += rsa_helper.o
+obj-$(CONFIG_CRYPTO_RSA) += rsa_generic.o
+
 cryptomgr-y := algboss.o testmgr.o
 
 obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o
diff --git a/crypto/rsa.c b/crypto/rsa.c
new file mode 100644
index 000..33bb7f0
--- /dev/null
+++ b/crypto/rsa.c
@@ -0,0 +1,313 @@
+/* RSA asymmetric public-key algorithm [RFC3447]
+ *
+ * Copyright (c) 2015, Intel Corporation
+ * Authors: Tadeusz Struk tadeusz.st...@intel.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include linux/module.h
+#include crypto/internal/rsa.h
+#include crypto/internal/akcipher.h
+#include crypto/akcipher.h
+
+/*
+ * RSAEP function [RFC3447 sec 5.1.1]
+ * c = m^e mod n;
+ */
+static int _rsa_enc(const struct rsa_key *key, MPI c, MPI m)
+{
+   /* (1) Validate 0 = m  n */
+   if (mpi_cmp_ui(m, 0)  0 || mpi_cmp(m, key-n) = 0)
+   return -EINVAL;
+
+   /* (2) c = m^e mod n */
+   return mpi_powm(c, m, key-e, key-n);
+}
+
+/*
+ * RSADP function [RFC3447 sec 5.1.2]
+ * m = c^d mod n;
+ */
+static int _rsa_dec(const struct rsa_key *key, MPI m, MPI c)
+{
+   /* (1) Validate 0 = c  n */
+   if (mpi_cmp_ui(c, 0)  0 || mpi_cmp(c, key-n) = 0)
+   return -EINVAL;
+
+   /* (2) m = c^d mod n */
+   return mpi_powm(m, c, key-d, key-n);
+}
+
+/*
+ * RSASP1 function [RFC3447 sec 5.2.1]
+ * s = m^d mod n
+ */
+static int _rsa_sign(const struct rsa_key *key, MPI s, MPI m)
+{
+   /* (1) Validate 0 = m  n */
+   if (mpi_cmp_ui(m, 0)  0 || mpi_cmp(m, key-n) = 0)
+   return -EINVAL;
+
+   /* (2) s = m^d mod n */
+   return mpi_powm(s, m, key-d, key-n);
+}
+
+/*
+ * RSAVP1 function [RFC3447 sec 5.2.2]
+ * m = s^e mod n;
+ */
+static int _rsa_verify(const struct rsa_key *key, MPI m, MPI s)
+{
+   /* (1) Validate 0 = s  n */
+   if (mpi_cmp_ui(s, 0)  0 || mpi_cmp(s, key-n) = 0)
+   return -EINVAL;
+
+   /* (2) m = s^e mod n */
+   return mpi_powm(m, s, key-e, key-n);
+}
+
+static struct rsa_key *rsa_get_key(struct crypto_akcipher *tfm)
+{
+   return akcipher_tfm_ctx(tfm);
+}
+
+static int rsa_enc(struct akcipher_request *req)
+{
+   struct crypto_akcipher *tfm = akcipher_request_get_tfm(req);
+   const struct rsa_key *pkey = rsa_get_key(tfm);
+   MPI m, c = mpi_alloc(0);
+   int ret = 0;
+   int sign;
+
+   if (!c)
+   return -ENOMEM;
+
+   if (!pkey-n || !pkey-e || !req-dst_len)
+   return -EINVAL;
+
+   if (*req-dst_len  mpi_get_size(pkey-n)) {
+   *req-dst_len = mpi_get_size(pkey-n);
+   return -EINVAL;
+   }
+
+   m = mpi_read_raw_data(req-src, req-src_len);
+   if (!m) {
+   ret = -ENOMEM;
+   goto err_free_c;
+   }
+
+   ret = _rsa_enc(pkey, c, m);
+   if (ret)
+   goto err_free_m;
+
+   ret = mpi_read_buffer(c, req-dst, *req-dst_len, req-dst_len, sign);
+   if (ret)
+   goto err_free_m;
+
+   if (sign  0) {
+   ret = -EBADMSG;
+   goto err_free_m;
+   }
+
+err_free_m:
+   mpi_free(m);
+err_free_c:
+   mpi_free(c);
+   return ret

[PATCH RFC v6 0/3] crypto: Introduce Public Key Encryption API

2015-06-16 Thread Tadeusz Struk
This patch set introduces a Public Key Encryption API.
What is proposed is a new crypto type called crypto_akcipher_type,
plus new struct akcipher_alg and struct crypto_akcipher, together with number
of helper functions to register akcipher type algorithms and allocate
tfm instances. This is to make it similar to how the existing crypto
API works for the ablkcipher, ahash, and aead types.
The operations the new interface will allow to provide are:

int (*sign)(struct akcipher_request *req);
int (*verify)(struct akcipher_request *req);
int (*encrypt)(struct akcipher_request *req);
int (*decrypt)(struct akcipher_request *req);

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

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

struct crypto_akcipher *tfm = crypto_alloc_akcipher(rsa, 0, 0);
struct akcipher_request *req = akcipher_request_alloc(tfm, GFP_KERNEL);
akcipher_request_set_crypt(req, pub_key, signature);
int ret = crypto_akcipher_verify(src, dst, src_len, dst_len, res_len);
akcipher_request_free(req);
crypto_free_akcipher(tfm);
return ret;

Changes in v6:
 - in FIPS mode only allow key sizes 2K  3K
 - remove result_len and use dst_len as in/out param
 - remove subtype from akcipher reports
 - store rsa_key in tfm ctx and change ras_parse_key to take struct rsa_key
   instead of tfm. 
 - export rsa_free_key, which free memory allocated by ras_parse_key.
 - split akcipher.h into public and internal with public key specific helpers
 - remove maxsize() and set the required size in enc/dec/sign/verify instead
 - add public key vector
 - split AKCIPHER into AKCIPHER and AKCIPHER2 in Kconfig
 - remove MPI patch from the series - already applied

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

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

Changes in v3:
 - changed input and output parameters type from sgl to void *
   and added separate src_len  dst_len - requested by Herbert Xu
 - separated rsa implementation into cryptographic primitives and
   left encryption scheme details outside of the algorithm implementation
 - added SW implementation for RSA encrypt, decrypt and sign operation
 - added RSA test vectors 
   
Changes in v2:
 - remodeled not to use obsolete cra_u and crt_u unions
 - changed type/funct names from pke_* to pkey_*
 - retained the enum pkey_algo type for it is external to the kernel
 - added documentation

---
Tadeusz Struk (3):
  crypto: add PKE API
  crypto: rsa: add a new rsa generic implementation
  crypto: add tests vectors for RSA


 crypto/Kconfig |   19 ++
 crypto/Makefile|9 +
 crypto/akcipher.c  |  100 +++
 crypto/crypto_user.c   |   22 ++
 crypto/rsa.c   |  313 +++
 crypto/rsa_helper.c|  124 ++
 crypto/rsakey.asn1 |5 +
 crypto/testmgr.c   |  161 ++
 crypto/testmgr.h   |  187 +
 include/crypto

[PATCH RFC v6 1/3] crypto: add PKE API

2015-06-16 Thread Tadeusz Struk
Add Public Key Encryption API.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/Kconfig |   11 +
 crypto/Makefile|1 
 crypto/akcipher.c  |  100 +++
 crypto/crypto_user.c   |   22 ++
 include/crypto/akcipher.h  |  323 
 include/crypto/internal/akcipher.h |   66 +++
 include/linux/crypto.h |1 
 include/linux/cryptouser.h |5 +
 8 files changed, 529 insertions(+)
 create mode 100644 crypto/akcipher.c
 create mode 100644 include/crypto/akcipher.h
 create mode 100644 include/crypto/internal/akcipher.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index f6fc054..264dadb 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -91,6 +91,17 @@ config CRYPTO_PCOMP2
tristate
select CRYPTO_ALGAPI2
 
+config CRYPTO_AKCIPHER2
+   tristate
+   select CRYPTO_ALGAPI2
+
+config CRYPTO_AKCIPHER
+   tristate Public Key Algorithms API
+   select CRYPTO_AKCIPHER2
+   select CRYPTO_ALGAPI
+   help
+ Crypto API interface for public key algorithms.
+
 config CRYPTO_MANAGER
tristate Cryptographic algorithm manager
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index c842035..6f2940a 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -28,6 +28,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
+obj-$(CONFIG_CRYPTO_AKCIPHER) += akcipher.o
 
 cryptomgr-y := algboss.o testmgr.o
 
diff --git a/crypto/akcipher.c b/crypto/akcipher.c
new file mode 100644
index 000..eefcc49
--- /dev/null
+++ b/crypto/akcipher.c
@@ -0,0 +1,100 @@
+/*
+ * Public Key Encryption
+ *
+ * Copyright (c) 2015, Intel Corporation
+ * Authors: Tadeusz Struk tadeusz.st...@intel.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include linux/errno.h
+#include linux/kernel.h
+#include linux/module.h
+#include linux/seq_file.h
+#include linux/slab.h
+#include linux/string.h
+#include linux/crypto.h
+#include crypto/algapi.h
+#include linux/cryptouser.h
+#include net/netlink.h
+#include crypto/akcipher.h
+#include crypto/public_key.h
+#include internal.h
+
+#ifdef CONFIG_NET
+static int crypto_akcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_akcipher rakcipher;
+
+   strncpy(rakcipher.type, akcipher, sizeof(rakcipher.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_AKCIPHER,
+   sizeof(struct crypto_report_akcipher), rakcipher))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_akcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+static void crypto_akcipher_show(struct seq_file *m, struct crypto_alg *alg)
+   __attribute__ ((unused));
+
+static void crypto_akcipher_show(struct seq_file *m, struct crypto_alg *alg)
+{
+   seq_puts(m, type : akcipher\n);
+}
+
+static int crypto_akcipher_init_tfm(struct crypto_tfm *tfm)
+{
+   return 0;
+}
+
+static const struct crypto_type crypto_akcipher_type = {
+   .extsize = crypto_alg_extsize,
+   .init_tfm = crypto_akcipher_init_tfm,
+#ifdef CONFIG_PROC_FS
+   .show = crypto_akcipher_show,
+#endif
+   .report = crypto_akcipher_report,
+   .maskclear = ~CRYPTO_ALG_TYPE_MASK,
+   .maskset = CRYPTO_ALG_TYPE_MASK,
+   .type = CRYPTO_ALG_TYPE_AKCIPHER,
+   .tfmsize = offsetof(struct crypto_akcipher, base),
+};
+
+struct crypto_akcipher *crypto_alloc_akcipher(const char *alg_name, u32 type,
+ u32 mask)
+{
+   return crypto_alloc_tfm(alg_name, crypto_akcipher_type, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_alloc_akcipher);
+
+int crypto_register_akcipher(struct akcipher_alg *alg)
+{
+   struct crypto_alg *base = alg-base;
+
+   base-cra_type = crypto_akcipher_type;
+   base-cra_flags = ~CRYPTO_ALG_TYPE_MASK;
+   base-cra_flags |= CRYPTO_ALG_TYPE_AKCIPHER;
+   return crypto_register_alg(base);
+}
+EXPORT_SYMBOL_GPL(crypto_register_akcipher);
+
+void crypto_unregister_akcipher(struct akcipher_alg *alg)
+{
+   crypto_unregister_alg(alg-base);
+}
+EXPORT_SYMBOL_GPL(crypto_unregister_akcipher);
+
+MODULE_LICENSE(GPL);
+MODULE_DESCRIPTION(Generic public key cihper type);
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 41dfe76..11dbd5a 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -27,6 +27,7 @@
 #include net/net_namespace.h
 #include crypto/internal/aead.h
 #include crypto/internal/skcipher.h
+#include crypto/akcipher.h
 
 #include internal.h
 
@@ -110,6

[PATCH RFC v6 3/3] crypto: add tests vectors for RSA

2015-06-16 Thread Tadeusz Struk
New test vectors for RSA algorithm.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/Kconfig   |1 
 crypto/testmgr.c |  161 ++
 crypto/testmgr.h |  187 ++
 3 files changed, 349 insertions(+)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 52467cf..9471ac8 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -122,6 +122,7 @@ config CRYPTO_MANAGER2
select CRYPTO_HASH2
select CRYPTO_BLKCIPHER2
select CRYPTO_PCOMP2
+   select CRYPTO_AKCIPHER2
 
 config CRYPTO_USER
tristate Userspace cryptographic algorithm configuration
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index ccd19cf..c773424 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -30,6 +30,7 @@
 #include linux/string.h
 #include crypto/rng.h
 #include crypto/drbg.h
+#include crypto/akcipher.h
 
 #include internal.h
 
@@ -116,6 +117,11 @@ struct drbg_test_suite {
unsigned int count;
 };
 
+struct akcipher_test_suite {
+   struct akcipher_testvec *vecs;
+   unsigned int count;
+};
+
 struct alg_test_desc {
const char *alg;
int (*test)(const struct alg_test_desc *desc, const char *driver,
@@ -130,6 +136,7 @@ struct alg_test_desc {
struct hash_test_suite hash;
struct cprng_test_suite cprng;
struct drbg_test_suite drbg;
+   struct akcipher_test_suite akcipher;
} suite;
 };
 
@@ -1825,6 +1832,150 @@ static int alg_test_drbg(const struct alg_test_desc 
*desc, const char *driver,
 
 }
 
+static int do_test_rsa(struct crypto_akcipher *tfm,
+  struct akcipher_testvec *vecs)
+{
+   struct akcipher_request *req;
+   void *outbuf_enc = NULL;
+   void *outbuf_dec = NULL;
+   struct tcrypt_result result;
+   unsigned int out_len_max, out_len = 0;
+   int err = -ENOMEM;
+
+   req = akcipher_request_alloc(tfm, GFP_KERNEL);
+   if (!req)
+   return err;
+
+   init_completion(result.completion);
+   err = crypto_akcipher_setkey(tfm, vecs-key, vecs-key_len);
+   if (err)
+   goto free_req;
+
+   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);
+   if (!out_len) {
+   err = -EINVAL;
+   goto free_req;
+   }
+
+   out_len_max = out_len;
+
+   err = -ENOMEM;
+   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);
+   akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ tcrypt_complete, result);
+
+   /* Run RSA encrypt - c = m^e mod n;*/
+   err = wait_async_op(result, crypto_akcipher_encrypt(req));
+   if (err) {
+   pr_err(alg: rsa: encrypt test failed. err %d\n, err);
+   goto free_all;
+   }
+
+   if (out_len != vecs-c_size) {
+   err = -EINVAL;
+   goto free_all;
+   }
+   /* verify that encrypted message is equal to expected */
+   if (memcmp(vecs-c, outbuf_enc, vecs-c_size)) {
+   pr_err(alg: rsa: encrypt test failed. Invalid output\n);
+   err = -EINVAL;
+   goto free_all;
+   }
+
+   /* Don't invoke decrypt for vectors with public key */
+   if (vecs-public_key_test) {
+   err = 0;
+   goto free_all;
+   }
+
+   outbuf_dec = kzalloc(out_len_max, GFP_KERNEL);
+   if (!outbuf_dec) {
+   err = -ENOMEM;
+   goto free_all;
+   }
+
+   init_completion(result.completion);
+   akcipher_request_set_crypt(req, outbuf_enc, outbuf_dec, vecs-c_size,
+  out_len);
+
+   /* Run RSA decrypt - m = c^d mod n;*/
+   err = wait_async_op(result, crypto_akcipher_decrypt(req));
+   if (err) {
+   pr_err(alg: rsa: decrypt test failed. err %d\n, err);
+   goto free_all;
+   }
+
+   if (out_len != vecs-m_size) {
+   err = -EINVAL;
+   goto free_all;
+   }
+
+   /* verify that decrypted message is equal to the original msg */
+   if (memcmp(vecs-m, outbuf_dec, vecs-m_size)) {
+   pr_err(alg: rsa: encrypt test failed. Invalid output\n);
+   err = -EINVAL;
+   }
+free_all:
+   kfree(outbuf_dec);
+   kfree(outbuf_enc);
+free_req:
+   akcipher_request_free(req);
+   return err;
+}
+
+static int test_rsa(struct crypto_akcipher *tfm, struct akcipher_testvec *vecs,
+   unsigned int tcount)
+{
+   int ret, i;
+
+   for (i = 0; i  tcount; i

Re: [PATCH RFC v5 3/4] crypto: rsa: add a new rsa generic implementation

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

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

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


Re: [PATCH RFC v5 2/4] crypto: add PKE API

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

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

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


Re: [PATCH RFC v5 2/4] crypto: add PKE API

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

Ok I wanted to handle everything in the parse_key helper without any help from 
the implementation.
I can change the helper to return the key and implementation will store it in 
the ctx. Is this
what you are suggesting?
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC v4 2/4] crypto: add PKE API

2015-06-12 Thread Tadeusz Struk
On 06/11/2015 07:42 PM, Herbert Xu wrote:
 The testmgr code can mark an entire cipher implementation as fips_allowed=1 
 as 
  already done for RSA. However, unlike with the other ciphers, that flag 
  must 
  go in conjunction with the used key sizes.
  
  For FIPS mode, the following restrictions apply:
  
  - RSA: 2048/3072
  
  - DSA: L 2048 / N 224; L 2048 / N 256; L 3072 / N 256
  
  - ECDSA: only the NIST curves
  
  Any other key sizes for the given ciphers is not allowed in FIPS mode.
  
  Should that constraint be considered here?
 Yes.  However it should be placed into a helper that everybody
 can call so that future hardware implementations can also make
 the same checks.

I will make the algorithm marked as fips allowed always and then fail in setkey 
if fips is enabled
and the given key doesn't meet the fips requirement.
Thanks
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

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

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

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

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


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

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

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

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

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


[PATCH RFC v4 2/4] crypto: add PKE API

2015-06-11 Thread Tadeusz Struk
Add Public Key Encryption API.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/Kconfig |6 +
 crypto/Makefile|1 
 crypto/akcipher.c  |  154 +
 crypto/crypto_user.c   |   23 ++
 include/crypto/akcipher.h  |  408 
 include/linux/crypto.h |1 
 include/linux/cryptouser.h |6 +
 7 files changed, 599 insertions(+)
 create mode 100644 crypto/akcipher.c
 create mode 100644 include/crypto/akcipher.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index cb7806f..d119b38 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -91,6 +91,12 @@ config CRYPTO_PCOMP2
tristate
select CRYPTO_ALGAPI2
 
+config CRYPTO_AKCIPHER
+   tristate Public Key Algorithms API
+   select CRYPTO_ALGAPI
+   help
+ Crypto API interface for public key algorithms.
+
 config CRYPTO_MANAGER
tristate Cryptographic algorithm manager
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index c842035..6f2940a 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -28,6 +28,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
+obj-$(CONFIG_CRYPTO_AKCIPHER) += akcipher.o
 
 cryptomgr-y := algboss.o testmgr.o
 
diff --git a/crypto/akcipher.c b/crypto/akcipher.c
new file mode 100644
index 000..286f31f
--- /dev/null
+++ b/crypto/akcipher.c
@@ -0,0 +1,154 @@
+/*
+ * Public Key Encryption
+ *
+ * Copyright (c) 2015, Intel Corporation
+ * Authors: Tadeusz Struk tadeusz.st...@intel.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include linux/errno.h
+#include linux/kernel.h
+#include linux/module.h
+#include linux/seq_file.h
+#include linux/slab.h
+#include linux/string.h
+#include linux/crypto.h
+#include crypto/algapi.h
+#include linux/cryptouser.h
+#include net/netlink.h
+#include crypto/akcipher.h
+#include crypto/public_key.h
+#include internal.h
+
+#ifdef CONFIG_NET
+static int crypto_akcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_akcipher rakcipher;
+
+   strncpy(rakcipher.type, akcipher, sizeof(rakcipher.type));
+   strncpy(rakcipher.subtype, alg-cra_name, sizeof(rakcipher.subtype));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_AKCIPHER,
+   sizeof(struct crypto_report_akcipher), rakcipher))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_akcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+static void crypto_akcipher_show(struct seq_file *m, struct crypto_alg *alg)
+   __attribute__ ((unused));
+
+static void crypto_akcipher_show(struct seq_file *m, struct crypto_alg *alg)
+{
+   seq_puts(m, type : akcipher\n);
+   seq_printf(m, subtype  : %s\n, alg-cra_name);
+}
+
+static void akcipher_free_key(struct public_key *key)
+{
+   public_key_destroy(key);
+}
+
+static void crypto_akcipher_exit_tfm(struct crypto_tfm *tfm)
+{
+   struct crypto_akcipher *akcipher = __crypto_akcipher_tfm(tfm);
+
+   if (akcipher-pkey)
+   akcipher_free_key(akcipher-pkey);
+
+   akcipher-pkey = NULL;
+}
+
+static int crypto_akcipher_init_tfm(struct crypto_tfm *tfm)
+{
+   struct crypto_akcipher *akcipher = __crypto_akcipher_tfm(tfm);
+
+   akcipher-base.exit = crypto_akcipher_exit_tfm;
+   return 0;
+}
+
+static const struct crypto_type crypto_akcipher_type = {
+   .extsize = crypto_alg_extsize,
+   .init_tfm = crypto_akcipher_init_tfm,
+#ifdef CONFIG_PROC_FS
+   .show = crypto_akcipher_show,
+#endif
+   .report = crypto_akcipher_report,
+   .maskclear = ~CRYPTO_ALG_TYPE_MASK,
+   .maskset = CRYPTO_ALG_TYPE_MASK,
+   .type = CRYPTO_ALG_TYPE_AKCIPHER,
+   .tfmsize = offsetof(struct crypto_akcipher, base),
+};
+
+struct crypto_akcipher *crypto_alloc_akcipher(const char *alg_name, u32 type,
+ u32 mask)
+{
+   return crypto_alloc_tfm(alg_name, crypto_akcipher_type, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_alloc_akcipher);
+
+static int akcipher_clone_key(struct crypto_akcipher *tfm,
+ const struct public_key *pkey)
+{
+   int i, ret = 0;
+
+   tfm-pkey = kzalloc(sizeof(*tfm-pkey), GFP_KERNEL);
+
+   if (!tfm-pkey)
+   return -ENOMEM;
+
+   for (i = 0; i  ARRAY_SIZE(tfm-pkey-mpi); i++) {
+   if (!pkey-mpi[i])
+   continue;
+
+   if (mpi_copy(tfm-pkey-mpi[i], pkey-mpi[i])) {
+   akcipher_free_key(tfm-pkey);
+   tfm

[PATCH RFC v4 1/4] MPILIB: add mpi_read_buf(), mpi_copy() and mpi_get_size() helpers

2015-06-11 Thread Tadeusz Struk
Added a mpi_read_buf() helper function to export MPI to a buf provided by
the user, and a mpi_get_size() helper, that tells the user how big the buf is.
Implemented mpi_copy(), which was declared in mpi.h, but never implemented.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 include/linux/mpi.h |3 ++
 lib/mpi/mpicoder.c  |   86 ---
 lib/mpi/mpiutil.c   |   47 
 3 files changed, 117 insertions(+), 19 deletions(-)

diff --git a/include/linux/mpi.h b/include/linux/mpi.h
index 5af1b81..5e55fd0 100644
--- a/include/linux/mpi.h
+++ b/include/linux/mpi.h
@@ -73,6 +73,7 @@ int mpi_set_ui(MPI w, ulong u);
 MPI mpi_alloc_set_ui(unsigned long u);
 void mpi_m_check(MPI a);
 void mpi_swap(MPI a, MPI b);
+unsigned int mpi_get_size(MPI a);
 
 /*-- mpicoder.c --*/
 MPI do_encode_md(const void *sha_buffer, unsigned nbits);
@@ -81,6 +82,8 @@ MPI mpi_read_from_buffer(const void *buffer, unsigned 
*ret_nread);
 int mpi_fromstr(MPI val, const char *str);
 u32 mpi_get_keyid(MPI a, u32 *keyid);
 void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign);
+int mpi_read_buffer(MPI a, uint8_t *buf, unsigned buf_len, unsigned *nbytes,
+   int *sign);
 void *mpi_get_secure_buffer(MPI a, unsigned *nbytes, int *sign);
 int mpi_set_buffer(MPI a, const void *buffer, unsigned nbytes, int sign);
 
diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c
index 4cc6442..f48b028 100644
--- a/lib/mpi/mpicoder.c
+++ b/lib/mpi/mpicoder.c
@@ -128,28 +128,36 @@ leave:
 }
 EXPORT_SYMBOL_GPL(mpi_read_from_buffer);
 
-/
- * Return an allocated buffer with the MPI (msb first).
- * NBYTES receives the length of this buffer. Caller must free the
- * return string (This function does return a 0 byte buffer with NBYTES
- * set to zero if the value of A is zero. If sign is not NULL, it will
- * be set to the sign of the A.
+/**
+ * mpi_read_buffer() - read MPI to a bufer provided by user (msb first)
+ *
+ * @a: a multi precision integer
+ * @buf:   bufer to which the output will be written to. Needs to be at
+ * leaset mpi_get_size(a) long.
+ * @buf_len:   size of the buf.
+ * @nbytes:receives the actual length of the data written.
+ * @sign:  if not NULL, it will be set to the sign of a.
+ *
+ * Return: 0 on success or error code in case of error
  */
-void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign)
+int mpi_read_buffer(MPI a, uint8_t *buf, unsigned buf_len, unsigned *nbytes,
+   int *sign)
 {
-   uint8_t *p, *buffer;
+   uint8_t *p;
mpi_limb_t alimb;
+   unsigned int n = mpi_get_size(a);
int i;
-   unsigned int n;
+
+   if (buf_len  n || !buf)
+   return -EINVAL;
 
if (sign)
*sign = a-sign;
-   *nbytes = n = a-nlimbs * BYTES_PER_MPI_LIMB;
-   if (!n)
-   n++;/* avoid zero length allocation */
-   p = buffer = kmalloc(n, GFP_KERNEL);
-   if (!p)
-   return NULL;
+
+   if (nbytes)
+   *nbytes = n;
+
+   p = buf;
 
for (i = a-nlimbs - 1; i = 0; i--) {
alimb = a-d[i];
@@ -171,15 +179,55 @@ void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign)
 #error please implement for this limb size.
 #endif
}
+   return 0;
+}
+EXPORT_SYMBOL_GPL(mpi_read_buffer);
+
+/*
+ * mpi_get_buffer() - Returns an allocated buffer with the MPI (msb first).
+ * Caller must free the return string.
+ * This function does return a 0 byte buffer with nbytes set to zero if the
+ * value of A is zero.
+ *
+ * @a: a multi precision integer.
+ * @nbytes:receives the length of this buffer.
+ * @sign:  if not NULL, it will be set to the sign of the a.
+ *
+ * Return: Pointer to MPI buffer or NULL on error
+ */
+void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign)
+{
+   uint8_t *buf, *p;
+   int n, ret;
+
+   if (!nbytes)
+   return NULL;
+
+   n = mpi_get_size(a);
+
+   if (!n)
+   n++;
+
+   buf = kmalloc(n, GFP_KERNEL);
+
+   if (!buf)
+   return NULL;
+
+   ret = mpi_read_buffer(a, buf, n, nbytes, sign);
+
+   if (ret) {
+   kfree(buf);
+   return NULL;
+   }
 
/* this is sub-optimal but we need to do the shift operation
 * because the caller has to free the returned buffer */
-   for (p = buffer; !*p  *nbytes; p++, --*nbytes)
+   for (p = buf; !*p  *nbytes; p++, --*nbytes)
;
-   if (p != buffer)
-   memmove(buffer, p, *nbytes);
+   if (p != buf)
+   memmove(buf, p, *nbytes);
 
-   return buffer;
+   return buf;
 }
 EXPORT_SYMBOL_GPL(mpi_get_buffer);
 
diff --git a/lib/mpi/mpiutil.c b/lib/mpi/mpiutil.c
index bf076d2..ee078e2 100644
--- a/lib/mpi/mpiutil.c
+++ b/lib/mpi/mpiutil.c
@@ -54,6 +54,40 @@ MPI mpi_alloc(unsigned nlimbs

[PATCH RFC v4 3/4] crypto: rsa: add a new rsa generic implementation

2015-06-11 Thread Tadeusz Struk
Add a new rsa generic SW implementation.
This implements only cryptographic primitives.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/Kconfig  |7 +
 crypto/Makefile |1 
 crypto/rsa.c|  289 +++
 3 files changed, 297 insertions(+)
 create mode 100644 crypto/rsa.c

diff --git a/crypto/Kconfig b/crypto/Kconfig
index d119b38..4d1bff3 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -97,6 +97,13 @@ config CRYPTO_AKCIPHER
help
  Crypto API interface for public key algorithms.
 
+config CRYPTO_RSA
+   tristate RSA algorithm
+   select AKCIPHER
+   select MPILIB
+   help
+ Generic implementation of the RSA public key algorithm.
+
 config CRYPTO_MANAGER
tristate Cryptographic algorithm manager
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 6f2940a..7ba05f0 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
 obj-$(CONFIG_CRYPTO_AKCIPHER) += akcipher.o
+obj-$(CONFIG_CRYPTO_RSA) += rsa.o
 
 cryptomgr-y := algboss.o testmgr.o
 
diff --git a/crypto/rsa.c b/crypto/rsa.c
new file mode 100644
index 000..8efef17
--- /dev/null
+++ b/crypto/rsa.c
@@ -0,0 +1,289 @@
+/* RSA asymmetric public-key algorithm [RFC3447]
+ *
+ * Copyright (c) 2015, Intel Corporation
+ * Authors: Tadeusz Struk tadeusz.st...@intel.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include linux/module.h
+#include linux/scatterlist.h
+#include crypto/public_key.h
+#include crypto/akcipher.h
+
+/*
+ * RSAEP function [RFC3447 sec 5.1.1]
+ * c = m^e mod n;
+ */
+static int _rsa_enc(const struct public_key *key, MPI c, MPI m)
+{
+   /* (1) Validate 0 = m  n */
+   if (mpi_cmp_ui(m, 0)  0 || mpi_cmp(m, key-rsa.n) = 0)
+   return -EINVAL;
+
+   /* (2) c = m^e mod n */
+   return mpi_powm(c, m, key-rsa.e, key-rsa.n);
+}
+
+/*
+ * RSADP function [RFC3447 sec 5.1.2]
+ * m = c^d mod n;
+ */
+static int _rsa_dec(const struct public_key *key, MPI m, MPI c)
+{
+   /* (1) Validate 0 = c  n */
+   if (mpi_cmp_ui(c, 0)  0 || mpi_cmp(c, key-rsa.n) = 0)
+   return -EINVAL;
+
+   /* (2) m = c^d mod n */
+   return mpi_powm(m, c, key-rsa.d, key-rsa.n);
+}
+
+/*
+ * RSASP1 function [RFC3447 sec 5.2.1]
+ * s = m^d mod n
+ */
+static int _rsa_sign(const struct public_key *key, MPI s, MPI m)
+{
+   /* (1) Validate 0 = m  n */
+   if (mpi_cmp_ui(m, 0)  0 || mpi_cmp(m, key-rsa.n) = 0)
+   return -EINVAL;
+
+   /* (2) s = m^d mod n */
+   return mpi_powm(s, m, key-rsa.d, key-rsa.n);
+}
+
+/*
+ * RSAVP1 function [RFC3447 sec 5.2.2]
+ * m = s^e mod n;
+ */
+static int _rsa_verify(const struct public_key *key, MPI m, MPI s)
+{
+   /* (1) Validate 0 = s  n */
+   if (mpi_cmp_ui(s, 0)  0 || mpi_cmp(s, key-rsa.n) = 0)
+   return -EINVAL;
+
+   /* (2) m = s^e mod n */
+   return mpi_powm(m, s, key-rsa.e, key-rsa.n);
+}
+
+static int rsa_enc(struct akcipher_request *req)
+{
+   struct crypto_akcipher *tfm = akcipher_request_get_tfm(req);
+   const struct public_key *pkey = crypto_akcipher_getkey(tfm);
+   MPI m, c = mpi_alloc(0);
+   unsigned int len;
+   int ret = 0;
+   int sign;
+
+   if (!c)
+   return -ENOMEM;
+
+   if (!pkey-rsa.e || req-dst_len  mpi_get_size(pkey-rsa.n))
+   return -EINVAL;
+
+   m = mpi_read_raw_data(req-src, req-src_len);
+   if (!m) {
+   ret = -ENOMEM;
+   goto err_free_c;
+   }
+
+   ret = _rsa_enc(pkey, c, m);
+   if (ret)
+   goto err_free_m;
+
+   ret = mpi_read_buffer(c, req-dst, req-dst_len, len, sign);
+   if (ret)
+   goto err_free_m;
+
+   if (sign  0) {
+   ret = -EBADMSG;
+   goto err_free_m;
+   }
+
+   if (req-result_len)
+   *req-result_len = len;
+
+err_free_m:
+   mpi_free(m);
+err_free_c:
+   mpi_free(c);
+   return ret;
+}
+
+static int rsa_dec(struct akcipher_request *req)
+{
+   struct crypto_akcipher *tfm = akcipher_request_get_tfm(req);
+   const struct public_key *pkey = crypto_akcipher_getkey(tfm);
+   MPI c, m = mpi_alloc(0);
+   unsigned int len;
+   int ret = 0;
+   int sign;
+
+   if (!m)
+   return -ENOMEM;
+
+   if (!pkey-rsa.d || req-dst_len  mpi_get_size(pkey-rsa.n))
+   return -EINVAL;
+
+   c = mpi_read_raw_data(req-src, req-src_len);
+   if (!c) {
+   ret = -ENOMEM;
+   goto err_free_m;
+   }
+
+   ret = _rsa_dec(pkey, m, c

[PATCH RFC v4 0/4] crypto: Introduce Public Key Encryption API

2015-06-11 Thread Tadeusz Struk
This patch set introduces a Public Key Encryption API.
What is proposed is a new crypto type called crypto_akcipher_type,
plus new struct akcipher_alg and struct crypto_akcipher, together with number
of helper functions to register akcipher type algorithms and allocate
tfm instances. This is to make it similar to how the existing crypto
API works for the ablkcipher, ahash, and aead types.
The operations the new interface will allow to provide are:

int (*sign)(struct akcipher_request *req);
int (*verify)(struct akcipher_request *req);
int (*encrypt)(struct akcipher_request *req);
int (*decrypt)(struct akcipher_request *req);

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

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

struct crypto_akcipher *tfm = crypto_alloc_akcipher(rsa, 0, 0);
struct akcipher_request *req = akcipher_request_alloc(tfm, GFP_KERNEL);
akcipher_request_set_crypt(req, pub_key, signature);
int ret = crypto_akcipher_verify(src, dst, src_len, dst_len, res_len);
akcipher_request_free(req);
crypto_free_akcipher(tfm);
return ret;

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

Changes in v3:
 - changed input and output parameters type from sgl to void *
   and added separate src_len  dst_len - requested by Herbert Xu
 - separated rsa implementation into cryptographic primitives and
   left encryption scheme details outside of the algorithm implementation
 - added SW implementation for RSA encrypt, decrypt and sign operation
 - added RSA test vectors 
   
Changes in v2:
 - remodeled not to use obsolete cra_u and crt_u unions
 - changed type/funct names from pke_* to pkey_*
 - retained the enum pkey_algo type for it is external to the kernel
 - added documentation

---
Tadeusz Struk (4):
  MPILIB: add mpi_get_buf(), mpi_copy() and mpi_get_size() helpers
  crypto: add PKE API
  crypto: RSA: KEYS: convert rsa and public key to new PKE API
  crypto: add tests vectors for RSA


 crypto/Kconfig |   14 ++
 crypto/Makefile|2 
 crypto/akcipher.c  |  155 +
 crypto/crypto_user.c   |   23 ++
 crypto/rsa.c   |  289 +++
 crypto/testmgr.c   |  164 ++
 crypto/testmgr.h   |  142 +++
 include/crypto/akcipher.h  |  408 
 include/linux/crypto.h |1 
 include/linux/cryptouser.h |6 +
 include/linux/mpi.h|3 
 lib/mpi/mpicoder.c |   85 +++--
 lib/mpi/mpiutil.c  |   46 +
 13 files changed, 1319 insertions(+), 19 deletions(-)
 create mode 100644 crypto/akcipher.c
 create mode 100644 crypto/rsa.c
 create mode 100644 include/crypto/akcipher.h
-- 

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


[PATCH RFC v4 4/4] crypto: add tests vectors for RSA

2015-06-11 Thread Tadeusz Struk
New test vectors for RSA algorithm.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/Kconfig   |1 
 crypto/testmgr.c |  164 ++
 crypto/testmgr.h |  142 +++
 3 files changed, 307 insertions(+)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 4d1bff3..cbae88a 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -107,6 +107,7 @@ config CRYPTO_RSA
 config CRYPTO_MANAGER
tristate Cryptographic algorithm manager
select CRYPTO_MANAGER2
+   select CRYPTO_AKCIPHER
help
  Create default cryptographic template instantiations such as
  cbc(aes).
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index ccd19cf..f984328 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -30,6 +30,8 @@
 #include linux/string.h
 #include crypto/rng.h
 #include crypto/drbg.h
+#include crypto/public_key.h
+#include crypto/akcipher.h
 
 #include internal.h
 
@@ -116,6 +118,11 @@ struct drbg_test_suite {
unsigned int count;
 };
 
+struct akcipher_test_suite {
+   struct akcipher_testvec *vecs;
+   unsigned int count;
+};
+
 struct alg_test_desc {
const char *alg;
int (*test)(const struct alg_test_desc *desc, const char *driver,
@@ -130,6 +137,7 @@ struct alg_test_desc {
struct hash_test_suite hash;
struct cprng_test_suite cprng;
struct drbg_test_suite drbg;
+   struct akcipher_test_suite akcipher;
} suite;
 };
 
@@ -1825,6 +1833,152 @@ static int alg_test_drbg(const struct alg_test_desc 
*desc, const char *driver,
 
 }
 
+static int do_test_rsa(struct crypto_akcipher *tfm,
+  struct akcipher_testvec *vecs)
+{
+   struct akcipher_request *req;
+   struct public_key pkey = {0};
+   void *outbuf_enc = NULL;
+   void *outbuf_dec = NULL;
+   struct tcrypt_result result;
+   unsigned int max_out_len, out_len;
+   int err = -ENOMEM;
+
+   req = akcipher_request_alloc(tfm, GFP_KERNEL);
+   if (!req)
+   return err;
+
+   pkey.rsa.n = mpi_read_raw_data(vecs-pub_key_n, vecs-pub_key_n_size);
+   if (!pkey.rsa.n)
+   goto free_req;
+
+   pkey.rsa.e = mpi_read_raw_data(vecs-pub_key_e, vecs-pub_key_e_size);
+   if (!pkey.rsa.e)
+   goto free_n;
+
+   pkey.rsa.d = mpi_read_raw_data(vecs-sec_key_d, vecs-sec_key_d_size);
+   if (!pkey.rsa.d)
+   goto free_e;
+
+   init_completion(result.completion);
+   crypto_akcipher_setkey(tfm, pkey);
+   max_out_len = crypto_akcipher_maxsize(tfm);
+   if (!(max_out_len  0))
+   goto free_d;
+
+   outbuf_enc = kzalloc(max_out_len, GFP_KERNEL);
+   if (!outbuf_enc)
+   goto free_d;
+
+   akcipher_request_set_crypt(req, vecs-m, outbuf_enc, vecs-m_size,
+  max_out_len, out_len);
+   akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ tcrypt_complete, result);
+
+   /* Run RSA encrypt - c = m^e mod n;*/
+   err = wait_async_op(result, crypto_akcipher_encrypt(req));
+   if (err) {
+   pr_err(alg: rsa: encrypt test failed. err %d\n, err);
+   goto free_all;
+   }
+
+   if (out_len != vecs-c_size) {
+   err = -EINVAL;
+   goto free_all;
+   }
+   /* verify that encrypted message is equal to expected */
+   if (memcmp(vecs-c, outbuf_enc, vecs-c_size)) {
+   pr_err(alg: rsa: encrypt test failed. Invalid output\n);
+   err = -EINVAL;
+   goto free_all;
+   }
+
+   outbuf_dec = kzalloc(max_out_len, GFP_KERNEL);
+   if (!outbuf_dec) {
+   err = -ENOMEM;
+   goto free_all;
+   }
+
+   init_completion(result.completion);
+   akcipher_request_set_crypt(req, outbuf_enc, outbuf_dec, vecs-c_size,
+  max_out_len, out_len);
+
+   /* Run RSA decrypt - m = c^d mod n;*/
+   err = wait_async_op(result, crypto_akcipher_decrypt(req));
+   if (err) {
+   pr_err(alg: rsa: decrypt test failed. err %d\n, err);
+   goto free_all;
+   }
+
+   if (out_len != vecs-m_size) {
+   err = -EINVAL;
+   goto free_all;
+   }
+
+   /* verify that decrypted message is equal to the original msg */
+   if (memcmp(vecs-m, outbuf_dec, vecs-m_size)) {
+   pr_err(alg: rsa: encrypt test failed. Invalid output\n);
+   err = -EINVAL;
+   }
+free_all:
+   kfree(outbuf_dec);
+   kfree(outbuf_enc);
+free_d:
+   mpi_free(pkey.rsa.d);
+free_e:
+   mpi_free(pkey.rsa.e);
+free_n:
+   mpi_free(pkey.rsa.n);
+free_req:
+   akcipher_request_free(req);
+   return err;
+}
+
+static int test_rsa(struct crypto_akcipher *tfm, struct

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

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

The length would be redundant. It can be obtained by sg_nents(reg-inparams)
I don't limit the number of parameters. You can pass as many as you want. For 
instance to pass 3 in and 2 out you do:

struct scatterlist in[3];
struct scatterlist out[2];

sg_init_table(in, 3);
sg_init_table(out, 2);

sg_set_buf(in, first_in_param, len_of_first_in_param);
sg_set_buf(in + 1, second_in_param, len_of_second_in_param);
sg_set_buf(in + 2, third_in_param, len_of_third_in_param);

sg_set_buf(out, first_out_param, len_of_first_out_param);
sg_set_buf(out + 1, second_out_param, len_of_second_out_param);

akcipher_request_set_crypt(req, in, out);

The limitation here is that one parameter can not span multiple sgs. This 
should be ok as they will never be bigger than one page.
In fact MPI limits it to 2K max with #define MAX_EXTERN_MPI_BITS 16384.
I'm ok to rename it to src and dst.

 
 struct akcipher_alg {
 int (*sign)(struct akcipher_request *req);
 int (*verify)(struct akcipher_request *req);
 int (*encrypt)(struct akcipher_request *req);
 int (*decrypt)(struct akcipher_request *req);
 Looks good.  You'll also need a setkey (or perhaps two) function.

I have these two:

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

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

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


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

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

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

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

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

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

unsigned int reqsize;
struct crypto_alg base;
};

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

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


Re: linux-next: Tree for Aug 12 (include/linux/pci.h)

2015-08-12 Thread Tadeusz Struk
Hi,
On 08/12/2015 02:53 PM, Stephen Rothwell wrote:
 On Wed, 12 Aug 2015 11:05:36 -0700 Randy Dunlap rdun...@infradead.org wrote:
 
  on i386 or x86_64:
  
  Many (repeated) errors like this one:
  
  ../include/linux/pci.h:390:12: error: ‘struct pci_dev’ has no member 
  named ‘physfn’
  
  when CONFIG_PCI_ATS is not enabled.
 Maybe caused by commit
 
   dd0f368398ea (crypto: qat - Add qat dh895xcc VF driver)
 
 from the crypto tree Which adds a
 
   select PCI_IOV
 
 to drivers/crypto/qat/Kconfig without the necessary
 
   select PCI
 
 but PCI_IOV selects PCI_ATS, so I am not sure what happened here.  I am
 assuming that your config has PCI_IOV enabled?  What about PCI?

There is a patch submitted, but not yet applied
https://patchwork.kernel.org/patch/6994171/
maybe it will help?
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/2] crypto: qat - Don't move data inside output buffer

2015-08-12 Thread Tadeusz Struk
Don't need to move data inside of the output buffer
because SW doen't need to do this anymore sice the new MPI
mpi_read_buf() has been added. Just set the correct output len.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 drivers/crypto/qat/qat_common/qat_asym_algs.c |3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c 
b/drivers/crypto/qat/qat_common/qat_asym_algs.c
index fe352a6..6ddb13c 100644
--- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
+++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
@@ -144,9 +144,6 @@ static void qat_rsa_cb(struct icp_qat_fw_pke_resp *resp)
ptr++;
}
 
-   if (areq-dst_len != req-ctx-key_sz)
-   memcpy(areq-dst, ptr, areq-dst_len);
-
akcipher_request_complete(areq, err);
 }
 

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


[PATCH 0/2] crypto: KEYS: convert public key to the akcipher API

2015-08-12 Thread Tadeusz Struk
This patch converts the module verification code to the new akcipher API.
RSA implementation from crypto/asymmetric_keys has been removed and the
new API is used for cryptographic primitives. The signature verification
has been moved into a new crypto/asymmetric_keys/rsa_pkcs1_v1_5.c file.
There is no need for MPI above the API anymore.
Modules can be verified with software as well as HW rsa implementations.

Also changed qat rsa implementation not to move data inside
the output buff similarly to SW.

---

Tadeusz Struk (2):
  crypto: KEYS: convert public key to the akcipher API
  crypto: qat - Don't move data inside output buffer


 crypto/asymmetric_keys/Kconfig|2 
 crypto/asymmetric_keys/Makefile   |7 -
 crypto/asymmetric_keys/pkcs7_parser.c |   12 -
 crypto/asymmetric_keys/pkcs7_trust.c  |2 
 crypto/asymmetric_keys/pkcs7_verify.c |2 
 crypto/asymmetric_keys/public_key.c   |   59 +
 crypto/asymmetric_keys/public_key.h   |   36 ---
 crypto/asymmetric_keys/rsa.c  |  278 -
 crypto/asymmetric_keys/rsa_pkcs1_v1_5.c   |  232 +
 crypto/asymmetric_keys/x509_cert_parser.c |   37 +--
 crypto/asymmetric_keys/x509_public_key.c  |   17 +-
 crypto/asymmetric_keys/x509_rsakey.asn1   |4 
 drivers/crypto/qat/qat_common/qat_asym_algs.c |3 
 include/crypto/public_key.h   |   48 +---
 kernel/module_signing.c   |   56 ++---
 security/integrity/digsig_asymmetric.c|   11 -
 16 files changed, 304 insertions(+), 502 deletions(-)
 delete mode 100644 crypto/asymmetric_keys/public_key.h
 delete mode 100644 crypto/asymmetric_keys/rsa.c
 create mode 100644 crypto/asymmetric_keys/rsa_pkcs1_v1_5.c
 delete mode 100644 crypto/asymmetric_keys/x509_rsakey.asn1

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


[PATCH 1/2] crypto: KEYS: convert public key to the akcipher API

2015-08-12 Thread Tadeusz Struk
This patch converts the module verification code to the new akcipher API.
RSA implementation from crypto/asymmetric_keys has been removed and the
new API is used for cryptographic primitives. The signature verification
has been moved into a new crypto/asymmetric_keys/rsa_pkcs1_v1_5.c file.
There is no need for MPI above the API anymore.
Modules can be verified with software as well as HW rsa implementations.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
---
 crypto/asymmetric_keys/Kconfig|2 
 crypto/asymmetric_keys/Makefile   |7 -
 crypto/asymmetric_keys/pkcs7_parser.c |   12 +
 crypto/asymmetric_keys/pkcs7_trust.c  |2 
 crypto/asymmetric_keys/pkcs7_verify.c |2 
 crypto/asymmetric_keys/public_key.c   |   59 ++
 crypto/asymmetric_keys/public_key.h   |   36 
 crypto/asymmetric_keys/rsa.c  |  278 -
 crypto/asymmetric_keys/rsa_pkcs1_v1_5.c   |  229 
 crypto/asymmetric_keys/x509_cert_parser.c |   37 +---
 crypto/asymmetric_keys/x509_public_key.c  |   17 +-
 crypto/asymmetric_keys/x509_rsakey.asn1   |4 
 include/crypto/public_key.h   |   48 +
 kernel/module_signing.c   |   56 ++
 security/integrity/digsig_asymmetric.c|   11 -
 15 files changed, 301 insertions(+), 499 deletions(-)
 delete mode 100644 crypto/asymmetric_keys/public_key.h
 delete mode 100644 crypto/asymmetric_keys/rsa.c
 create mode 100644 crypto/asymmetric_keys/rsa_pkcs1_v1_5.c
 delete mode 100644 crypto/asymmetric_keys/x509_rsakey.asn1

diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
index 4870f28..905d745 100644
--- a/crypto/asymmetric_keys/Kconfig
+++ b/crypto/asymmetric_keys/Kconfig
@@ -22,7 +22,7 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
 
 config PUBLIC_KEY_ALGO_RSA
tristate RSA public-key algorithm
-   select MPILIB
+   select CRYPTO_RSA
help
  This option enables support for the RSA algorithm (PKCS#1, RFC3447).
 
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index e47fcd9..895d8ca 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -7,7 +7,7 @@ obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys.o
 asymmetric_keys-y := asymmetric_type.o signature.o
 
 obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
-obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa.o
+obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa_pkcs1_v1_5.o
 
 #
 # X.509 Certificate handling
@@ -15,16 +15,13 @@ obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa.o
 obj-$(CONFIG_X509_CERTIFICATE_PARSER) += x509_key_parser.o
 x509_key_parser-y := \
x509-asn1.o \
-   x509_rsakey-asn1.o \
x509_cert_parser.o \
x509_public_key.o
 
-$(obj)/x509_cert_parser.o: $(obj)/x509-asn1.h $(obj)/x509_rsakey-asn1.h
+$(obj)/x509_cert_parser.o: $(obj)/x509-asn1.h
 $(obj)/x509-asn1.o: $(obj)/x509-asn1.c $(obj)/x509-asn1.h
-$(obj)/x509_rsakey-asn1.o: $(obj)/x509_rsakey-asn1.c $(obj)/x509_rsakey-asn1.h
 
 clean-files+= x509-asn1.c x509-asn1.h
-clean-files+= x509_rsakey-asn1.c x509_rsakey-asn1.h
 
 #
 # PKCS#7 message handling
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c 
b/crypto/asymmetric_keys/pkcs7_parser.c
index 3bd5a1e..8e3597a 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -15,7 +15,7 @@
 #include linux/slab.h
 #include linux/err.h
 #include linux/oid_registry.h
-#include public_key.h
+#include crypto/public_key.h
 #include pkcs7_parser.h
 #include pkcs7-asn1.h
 
@@ -41,7 +41,7 @@ struct pkcs7_parse_context {
 static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo)
 {
if (sinfo) {
-   mpi_free(sinfo-sig.mpi[0]);
+   kfree(sinfo-sig.s);
kfree(sinfo-sig.digest);
kfree(sinfo-signing_cert_id);
kfree(sinfo);
@@ -374,16 +374,14 @@ int pkcs7_sig_note_signature(void *context, size_t hdrlen,
 const void *value, size_t vlen)
 {
struct pkcs7_parse_context *ctx = context;
-   MPI mpi;
 
BUG_ON(ctx-sinfo-sig.pkey_algo != PKEY_ALGO_RSA);
 
-   mpi = mpi_read_raw_data(value, vlen);
-   if (!mpi)
+   ctx-sinfo-sig.s = kmemdup(value, vlen, GFP_KERNEL);
+   if (!ctx-sinfo-sig.s)
return -ENOMEM;
 
-   ctx-sinfo-sig.mpi[0] = mpi;
-   ctx-sinfo-sig.nr_mpi = 1;
+   ctx-sinfo-sig.s_size = vlen;
return 0;
 }
 
diff --git a/crypto/asymmetric_keys/pkcs7_trust.c 
b/crypto/asymmetric_keys/pkcs7_trust.c
index 1d29376..68ebae2 100644
--- a/crypto/asymmetric_keys/pkcs7_trust.c
+++ b/crypto/asymmetric_keys/pkcs7_trust.c
@@ -17,7 +17,7 @@
 #include linux/asn1.h
 #include linux/key.h
 #include keys/asymmetric-type.h
-#include public_key.h
+#include crypto/public_key.h
 #include pkcs7_parser.h
 
 /**
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c 
b/crypto

Re: [PATCH 2/2] crypto: qat - Don't move data inside output buffer

2015-08-17 Thread Tadeusz Struk
On 08/17/2015 01:50 AM, Herbert Xu wrote:
 If you don't like the first option then we still need this, as you pointed 
 out.
 Yes this looks like the right fix for qat.  Please add a sign-off.
 You might be able to just do it by replying to this thread, and
 patchwork may be able to pick it up and attach it to the patch.

Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] crypto: KEYS: convert public key to the akcipher API

2015-08-24 Thread Tadeusz Struk
Hi Stephan,

On 08/15/2015 11:08 AM, Stephan Mueller wrote:
 Am Mittwoch, 12. August 2015, 20:54:39 schrieb Tadeusz Struk:
 
 Hi Tadeusz,
 
 @@ -41,7 +41,7 @@ struct pkcs7_parse_context {
 static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo)
 {
  if (sinfo) {
 -mpi_free(sinfo-sig.mpi[0]);
 +kfree(sinfo-sig.s);
 
 kzfree?
 
  kfree(sinfo-sig.digest);
 
 kzfree?
 
  kfree(sinfo-signing_cert_id);
  kfree(sinfo);
 
 kzfree (due to -msdigest)?
 

Sorry for late response. I was on vacation.
All these above are module signatures, which are not sensitive,
so no need to zero the buffers on free.
The only thing that is sensitive is the private key,
which is only used for signing modules on make modules_install
and never included in the kernel.
Thanks,
T
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] crypto: KEYS: convert public key to the akcipher API

2015-08-13 Thread Tadeusz Struk
On 08/13/2015 07:23 AM, David Howells wrote:
 Tadeusz Struk tadeusz.st...@intel.com wrote:
 
  const char *const pkey_algo_name[PKEY_ALGO__LAST] = {
 -[PKEY_ALGO_DSA] = DSA,
 -[PKEY_ALGO_RSA] = RSA,
 +[PKEY_ALGO_DSA] = dsa,
 +[PKEY_ALGO_RSA] = rsa,
  };
 
 Be aware that these are exposed to userspace through /proc.  The change
 probably doesn't matter, but you might need to update the documentation.
 
 +int public_key_verify_signature(const struct public_key *pkey,
  const struct public_key_signature *sig)
  {
 ...
 -return algo-verify_signature(pk, sig);
 +return rsa_pkcs1_v1_5_verify_signature(pkey, sig);
  }
 
 No.  You can't assume RSA here.  It's quite likely we'll have to support ECDSA
 or similar soon.  This must be contingent on the algorithm selected.
 
  {
  const struct public_key *pk = key-payload.data;
 +
  return public_key_verify_signature(pk, sig);
  }
 
 That's nothing to do with this patch.
 
 +static int rsa_signture_verify(const u8 *H, const u8 *EM, size_t k,
 
 'signture' - 'signature'.
 
 +/*
 + * Perform the RSA signature verification.
 + * @H: Value of hash of data and metadata
 + * @EM: The computed signature value
 + * @k: The size of EM (EM[0] is an invalid location but should hold 0x00)
 + * @hash_size: The size of H
 + * @asn1_template: The DigestInfo ASN.1 template
 + * @asn1_size: Size of asm1_template[]
 + */
 +static int rsa_signture_verify(const u8 *H, const u8 *EM, size_t k,
 +   size_t hash_size, const u8 *asn1_template,
 +   size_t asn1_size)
 +{
 
 Why is this here and not in crypto/rsa.c?
 
 +/* initlialzie out buf */
 
 'initialise'.
 
 -/* Decode the public key */
 -ret = asn1_ber_decoder(x509_rsakey_decoder, ctx,
 -   ctx-key, ctx-key_size);
 -if (ret  0)
 +cert-pub-key = kmemdup(ctx-key, ctx-key_size, GFP_KERNEL);
 +if (!cert-pub-key)
  goto error_decode;
 
 The generic public key code should *not* see the container wrappings (ASN.1
 from an X.509 cert in this case).  The public key could be supplied by OpenPGP
 instead, for example, or directly by a driver.
 
 Further, at this point, we need to make sure that the data we were given has
 the right bits and emit EBADMSG if it doesn't.
 
 Okay, I can accept that the public_key struct might just have a list of void *
 and size_t fields that get filled in, one for each integer that we extract
 rather than MPIs, but we should not expose the generic code to the stuff we've
 parsed away.
 
  struct public_key {
 -const struct public_key_algorithm *algo;
 -u8  capabilities;
 -#define PKEY_CAN_ENCRYPT0x01
 -#define PKEY_CAN_DECRYPT0x02
 -#define PKEY_CAN_SIGN   0x04
 -#define PKEY_CAN_VERIFY 0x08
 
 You still need the capabilities.  The X.509 certificate and the OpenPGP
 message indicate restrictions on the key that we need to honour.

Thanks David for all your feedback. I'll rework it according to your comments.
Regards,
T 


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


Re: [PATCH 2/2] crypto: qat - Don't move data inside output buffer

2015-08-13 Thread Tadeusz Struk
On 08/12/2015 08:54 PM, Tadeusz Struk wrote:
 Don't need to move data inside of the output buffer
 because SW doen't need to do this anymore sice the new MPI
 mpi_read_buf() has been added. Just set the correct output len.
 
 Signed-off-by: Tadeusz Struk tadeusz.st...@intel.com
 ---
  drivers/crypto/qat/qat_common/qat_asym_algs.c |3 ---
  1 file changed, 3 deletions(-)
 
 diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c 
 b/drivers/crypto/qat/qat_common/qat_asym_algs.c
 index fe352a6..6ddb13c 100644
 --- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
 +++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
 @@ -144,9 +144,6 @@ static void qat_rsa_cb(struct icp_qat_fw_pke_resp *resp)
   ptr++;
   }
  
 - if (areq-dst_len != req-ctx-key_sz)
 - memcpy(areq-dst, ptr, areq-dst_len);
 -
   akcipher_request_complete(areq, err);
  }
  
 

Herbert,
Could you take this one and I'll work with David on the rest.
Thanks,
T
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 0/2] crypto: KEYS: convert public key to the akcipher API

2015-08-13 Thread Tadeusz Struk
On 08/13/2015 06:56 AM, David Howells wrote:
 Can you rebase this on top of:
 
 
 http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=modsign-pkcs7
 
 David
 
Will do.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/2] crypto: qat - Don't move data inside output buffer

2015-08-14 Thread Tadeusz Struk
On 08/13/2015 10:14 PM, Herbert Xu wrote:
 diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c 
 b/drivers/crypto/qat/qat_common/qat_asym_algs.c
  index fe352a6..6ddb13c 100644
  --- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
  +++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
  @@ -144,9 +144,6 @@ static void qat_rsa_cb(struct icp_qat_fw_pke_resp 
  *resp)
 ptr++;
 }
   
  -  if (areq-dst_len != req-ctx-key_sz)
  -  memcpy(areq-dst, ptr, areq-dst_len);
  -
 This looks wrong.  It appears to be trying to remove leading
 zeroes so you can't just change the length because then you end
 up removing the trailing digits equal to the number of leading
 zeroes.

What it does is it sets the size of the output number, not the size of the 
output buffer.
The size of the buffer is set beforehand to the size of the modulo, which is 
the biggest
possible output.

 
 The existing code is also wrong as you should be using memmove
 instead of memcpy.

Right, but we don't need that anymore.

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


  1   2   3   4   5   6   7   >