[PATCH] MAINTAINERS: update maintainer for qat

2017-11-02 Thread Salvatore Benedetto
Removing myself as I'm not longer following QAT development.

Signed-off-by: Salvatore Benedetto 
---
 MAINTAINERS | 1 -
 1 file changed, 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 92df4e8..1171da1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11009,7 +11009,6 @@ F:  drivers/mtd/nand/pxa3xx_nand.c
 
 QAT DRIVER
 M: Giovanni Cabiddu 
-M: Salvatore Benedetto 
 L: qat-li...@intel.com
 S: Supported
 F: drivers/crypto/qat/
-- 
2.7.4



[PATCH] crypto: api - Clear CRYPTO_ALG_DEAD bit before registering an alg

2017-01-13 Thread Salvatore Benedetto
Make sure CRYPTO_ALG_DEAD bit is cleared before proceeding with
the algorithm registration. This fixes qat-dh registration when
driver is restarted

Signed-off-by: Salvatore Benedetto 
---
 crypto/algapi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/crypto/algapi.c b/crypto/algapi.c
index df939b5..1fad2a6 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -356,6 +356,7 @@ int crypto_register_alg(struct crypto_alg *alg)
struct crypto_larval *larval;
int err;
 
+   alg->cra_flags &= ~CRYPTO_ALG_DEAD;
err = crypto_check_alg(alg);
if (err)
return err;
-- 
2.7.4

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


[PATCH] crypto: kpp - clear CRYPTO_ALG_DEAD bit in prepare_alg

2017-01-02 Thread Salvatore Benedetto
Make sure CRYPTO_ALG_DEAD is not set when preparing for
alg registration. This fixes qat-dh registration that occurs
when reloading qat_c62x module.

Signed-off-by: Salvatore Benedetto 
---
 crypto/kpp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/crypto/kpp.c b/crypto/kpp.c
index d36ce05..d1adef8e 100644
--- a/crypto/kpp.c
+++ b/crypto/kpp.c
@@ -101,6 +101,7 @@ static void kpp_prepare_alg(struct kpp_alg *alg)
 
base->cra_type = &crypto_kpp_type;
base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
+   base->cra_flags &= ~CRYPTO_ALG_DEAD;
base->cra_flags |= CRYPTO_ALG_TYPE_KPP;
 }
 
-- 
2.4.11

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


[PATCH] crypto: rsa-pkcs1pad - Fix akcipher request allocation

2016-07-14 Thread Salvatore Benedetto
Embedding the akcipher_request in pkcs1pad_request don't take
into account the context space required by the akcipher object.
This result in memory corruption (and kernel panic) as the
akcipher object will overwrite anything after akcipher_request
structure.

Fix it by dinamically allocating the structure with akcipher_request_alloc.

Software akcipher implementation is working only because it is
synchronous and it does not use a request context.

Signed-off-by: Salvatore Benedetto 
---
 crypto/rsa-pkcs1pad.c | 75 ++-
 1 file changed, 51 insertions(+), 24 deletions(-)

diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
index 880d3db..d663ab6 100644
--- a/crypto/rsa-pkcs1pad.c
+++ b/crypto/rsa-pkcs1pad.c
@@ -101,7 +101,7 @@ struct pkcs1pad_inst_ctx {
 };
 
 struct pkcs1pad_request {
-   struct akcipher_request child_req;
+   struct akcipher_request *child_req;
 
struct scatterlist in_sg[2], out_sg[1];
uint8_t *in_buf, *out_buf;
@@ -192,7 +192,7 @@ static int pkcs1pad_encrypt_sign_complete(struct 
akcipher_request *req, int err)
if (err)
goto out;
 
-   len = req_ctx->child_req.dst_len;
+   len = req_ctx->child_req->dst_len;
pad_len = ctx->key_size - len;
 
/* Four billion to one */
@@ -215,6 +215,7 @@ out:
req->dst_len = ctx->key_size;
 
kfree(req_ctx->in_buf);
+   akcipher_request_free(req_ctx->child_req);
 
return err;
 }
@@ -277,15 +278,21 @@ static int pkcs1pad_encrypt(struct akcipher_request *req)
pkcs1pad_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf,
ctx->key_size, NULL);
 
-   akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
-   akcipher_request_set_callback(&req_ctx->child_req, req->base.flags,
+   req_ctx->child_req = akcipher_request_alloc(ctx->child, GFP_KERNEL);
+   if (!req_ctx->child_req) {
+   kfree(req_ctx->out_buf);
+   kfree(req_ctx->in_buf);
+   return -ENOMEM;
+   }
+   akcipher_request_set_tfm(req_ctx->child_req, ctx->child);
+   akcipher_request_set_callback(req_ctx->child_req, req->base.flags,
pkcs1pad_encrypt_sign_complete_cb, req);
 
/* Reuse output buffer */
-   akcipher_request_set_crypt(&req_ctx->child_req, req_ctx->in_sg,
+   akcipher_request_set_crypt(req_ctx->child_req, req_ctx->in_sg,
   req->dst, ctx->key_size - 1, req->dst_len);
 
-   err = crypto_akcipher_encrypt(&req_ctx->child_req);
+   err = crypto_akcipher_encrypt(req_ctx->child_req);
if (err != -EINPROGRESS &&
(err != -EBUSY ||
 !(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)))
@@ -308,7 +315,7 @@ static int pkcs1pad_decrypt_complete(struct 
akcipher_request *req, int err)
if (err)
goto done;
 
-   if (req_ctx->child_req.dst_len != ctx->key_size - 1) {
+   if (req_ctx->child_req->dst_len != ctx->key_size - 1) {
err = -EINVAL;
goto done;
}
@@ -317,18 +324,18 @@ static int pkcs1pad_decrypt_complete(struct 
akcipher_request *req, int err)
err = -EINVAL;
goto done;
}
-   for (pos = 1; pos < req_ctx->child_req.dst_len; pos++)
+   for (pos = 1; pos < req_ctx->child_req->dst_len; pos++)
if (req_ctx->out_buf[pos] == 0x00)
break;
-   if (pos < 9 || pos == req_ctx->child_req.dst_len) {
+   if (pos < 9 || pos == req_ctx->child_req->dst_len) {
err = -EINVAL;
goto done;
}
pos++;
 
-   if (req->dst_len < req_ctx->child_req.dst_len - pos)
+   if (req->dst_len < req_ctx->child_req->dst_len - pos)
err = -EOVERFLOW;
-   req->dst_len = req_ctx->child_req.dst_len - pos;
+   req->dst_len = req_ctx->child_req->dst_len - pos;
 
if (!err)
sg_copy_from_buffer(req->dst,
@@ -337,6 +344,7 @@ static int pkcs1pad_decrypt_complete(struct 
akcipher_request *req, int err)
 
 done:
kzfree(req_ctx->out_buf);
+   akcipher_request_free(req_ctx->child_req);
 
return err;
 }
@@ -373,16 +381,22 @@ static int pkcs1pad_decrypt(struct akcipher_request *req)
pkcs1pad_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf,
ctx->key_size, NULL);
 
-   akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
-   akcipher_request_set_callback(&req_ctx->child_req, req->base.flags,
+   req_ctx->child_req = akcipher_request_alloc(ctx->child, GFP_KERNE

[PATCH] crypto: qat - Stop dropping leading zeros from RSA output

2016-07-07 Thread Salvatore Benedetto
There is not need to drop leading zeros from the RSA output
operations results.

Signed-off-by: Salvatore Benedetto 
---
 drivers/crypto/qat/qat_common/qat_asym_algs.c | 20 
 1 file changed, 20 deletions(-)

diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c 
b/drivers/crypto/qat/qat_common/qat_asym_algs.c
index 3d56fb8..0d35dca 100644
--- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
+++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
@@ -571,32 +571,12 @@ static void qat_rsa_cb(struct icp_qat_fw_pke_resp *resp)
 
areq->dst_len = req->ctx.rsa->key_sz;
if (req->dst_align) {
-   char *ptr = req->dst_align;
-
-   while (!(*ptr) && areq->dst_len) {
-   areq->dst_len--;
-   ptr++;
-   }
-
-   if (areq->dst_len != req->ctx.rsa->key_sz)
-   memmove(req->dst_align, ptr, areq->dst_len);
-
scatterwalk_map_and_copy(req->dst_align, areq->dst, 0,
 areq->dst_len, 1);
 
dma_free_coherent(dev, req->ctx.rsa->key_sz, req->dst_align,
  req->out.rsa.enc.c);
} else {
-   char *ptr = sg_virt(areq->dst);
-
-   while (!(*ptr) && areq->dst_len) {
-   areq->dst_len--;
-   ptr++;
-   }
-
-   if (sg_virt(areq->dst) != ptr && areq->dst_len)
-   memmove(sg_virt(areq->dst), ptr, areq->dst_len);
-
dma_unmap_single(dev, req->out.rsa.enc.c, req->ctx.rsa->key_sz,
 DMA_FROM_DEVICE);
}
-- 
2.7.4

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


[PATCH] crypto: qat - Add DH support

2016-07-07 Thread Salvatore Benedetto
Add DH support under kpp api. Drop struct qat_rsa_request and
introduce a more generic struct qat_asym_request and share it
between RSA and DH requests.

Signed-off-by: Salvatore Benedetto 
---
 drivers/crypto/qat/Kconfig|   1 +
 drivers/crypto/qat/qat_common/qat_asym_algs.c | 593 ++
 2 files changed, 522 insertions(+), 72 deletions(-)

diff --git a/drivers/crypto/qat/Kconfig b/drivers/crypto/qat/Kconfig
index 571d04d..ce3cae4 100644
--- a/drivers/crypto/qat/Kconfig
+++ b/drivers/crypto/qat/Kconfig
@@ -4,6 +4,7 @@ config CRYPTO_DEV_QAT
select CRYPTO_AUTHENC
select CRYPTO_BLKCIPHER
select CRYPTO_AKCIPHER
+   select CRYPTO_DH
select CRYPTO_HMAC
select CRYPTO_RSA
select CRYPTO_SHA1
diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c 
b/drivers/crypto/qat/qat_common/qat_asym_algs.c
index eaff02a..3d56fb8 100644
--- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
+++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
@@ -49,6 +49,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -119,36 +122,454 @@ struct qat_rsa_ctx {
struct qat_crypto_instance *inst;
 } __packed __aligned(64);
 
-struct qat_rsa_request {
-   struct qat_rsa_input_params in;
-   struct qat_rsa_output_params out;
+struct qat_dh_input_params {
+   union {
+   struct {
+   dma_addr_t b;
+   dma_addr_t xa;
+   dma_addr_t p;
+   } in;
+   struct {
+   dma_addr_t xa;
+   dma_addr_t p;
+   } in_g2;
+   u64 in_tab[8];
+   };
+} __packed __aligned(64);
+
+struct qat_dh_output_params {
+   union {
+   dma_addr_t r;
+   u64 out_tab[8];
+   };
+} __packed __aligned(64);
+
+struct qat_dh_ctx {
+   char *g;
+   char *xa;
+   char *p;
+   dma_addr_t dma_g;
+   dma_addr_t dma_xa;
+   dma_addr_t dma_p;
+   unsigned int p_size;
+   bool g2;
+   struct qat_crypto_instance *inst;
+} __packed __aligned(64);
+
+struct qat_asym_request {
+   union {
+   struct qat_rsa_input_params rsa;
+   struct qat_dh_input_params dh;
+   } in;
+   union {
+   struct qat_rsa_output_params rsa;
+   struct qat_dh_output_params dh;
+   } out;
dma_addr_t phy_in;
dma_addr_t phy_out;
char *src_align;
char *dst_align;
struct icp_qat_fw_pke_request req;
-   struct qat_rsa_ctx *ctx;
+   union {
+   struct qat_rsa_ctx *rsa;
+   struct qat_dh_ctx *dh;
+   } ctx;
+   union {
+   struct akcipher_request *rsa;
+   struct kpp_request *dh;
+   } areq;
int err;
+   void (*cb)(struct icp_qat_fw_pke_resp *resp);
 } __aligned(64);
 
+static void qat_dh_cb(struct icp_qat_fw_pke_resp *resp)
+{
+   struct qat_asym_request *req = (void *)(__force long)resp->opaque;
+   struct kpp_request *areq = req->areq.dh;
+   struct device *dev = &GET_DEV(req->ctx.dh->inst->accel_dev);
+   int err = ICP_QAT_FW_PKE_RESP_PKE_STAT_GET(
+   resp->pke_resp_hdr.comn_resp_flags);
+
+   err = (err == ICP_QAT_FW_COMN_STATUS_FLAG_OK) ? 0 : -EINVAL;
+
+   if (areq->src) {
+   if (req->src_align)
+   dma_free_coherent(dev, req->ctx.dh->p_size,
+ req->src_align, req->in.dh.in.b);
+   else
+   dma_unmap_single(dev, req->in.dh.in.b,
+req->ctx.dh->p_size, DMA_TO_DEVICE);
+   }
+
+   areq->dst_len = req->ctx.dh->p_size;
+   if (req->dst_align) {
+   scatterwalk_map_and_copy(req->dst_align, areq->dst, 0,
+areq->dst_len, 1);
+
+   dma_free_coherent(dev, req->ctx.dh->p_size, req->dst_align,
+ req->out.dh.r);
+   } else {
+   dma_unmap_single(dev, req->out.dh.r, req->ctx.dh->p_size,
+DMA_FROM_DEVICE);
+   }
+
+   dma_unmap_single(dev, req->phy_in, sizeof(struct qat_dh_input_params),
+DMA_TO_DEVICE);
+   dma_unmap_single(dev, req->phy_out,
+sizeof(struct qat_dh_output_params),
+DMA_TO_DEVICE);
+
+   kpp_request_complete(areq, err);
+}
+
+#define PKE_DH_1536 0x390c1a49
+#define PKE_DH_G2_1536 0x2e0b1a3e
+#define PKE_DH_2048 0x4d0c1a60
+#define PKE_DH_G2_2048 0x3e0b1a55
+#define PKE_DH_3072 0x510c1a77
+#define PKE_DH_G2_3072 0x3a0b1a6c
+#define PKE_DH_4096 0x690c1a8e
+#define PKE_DH_G2_4096 0x4a0b1a83
+
+static unsigned long qat

[PATCH 3/3] crypto: qat - Add RSA CRT mode

2016-07-04 Thread Salvatore Benedetto
Extend qat driver to use RSA CRT mode when all CRT related components are
present in the private key. Simplify code in qat_rsa_setkey by adding
qat_rsa_clear_ctx.

Signed-off-by: Salvatore Benedetto 
---
 drivers/crypto/qat/qat_common/qat_asym_algs.c | 234 +++---
 1 file changed, 209 insertions(+), 25 deletions(-)

diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c 
b/drivers/crypto/qat/qat_common/qat_asym_algs.c
index 04b0ef8..eaff02a 100644
--- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
+++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
@@ -73,6 +73,14 @@ struct qat_rsa_input_params {
dma_addr_t d;
dma_addr_t n;
} dec;
+   struct {
+   dma_addr_t c;
+   dma_addr_t p;
+   dma_addr_t q;
+   dma_addr_t dp;
+   dma_addr_t dq;
+   dma_addr_t qinv;
+   } dec_crt;
u64 in_tab[8];
};
 } __packed __aligned(64);
@@ -93,10 +101,21 @@ struct qat_rsa_ctx {
char *n;
char *e;
char *d;
+   char *p;
+   char *q;
+   char *dp;
+   char *dq;
+   char *qinv;
dma_addr_t dma_n;
dma_addr_t dma_e;
dma_addr_t dma_d;
+   dma_addr_t dma_p;
+   dma_addr_t dma_q;
+   dma_addr_t dma_dp;
+   dma_addr_t dma_dq;
+   dma_addr_t dma_qinv;
unsigned int key_sz;
+   bool crt_mode;
struct qat_crypto_instance *inst;
 } __packed __aligned(64);
 
@@ -235,6 +254,35 @@ static unsigned long qat_rsa_dec_fn_id(unsigned int len)
};
 }
 
+#define PKE_RSA_DP2_512 0x1c131b57
+#define PKE_RSA_DP2_1024 0x26131c2d
+#define PKE_RSA_DP2_1536 0x45111d12
+#define PKE_RSA_DP2_2048 0x59121dfa
+#define PKE_RSA_DP2_3072 0x81121ed9
+#define PKE_RSA_DP2_4096 0xbfb2
+
+static unsigned long qat_rsa_dec_fn_id_crt(unsigned int len)
+{
+   unsigned int bitslen = len << 3;
+
+   switch (bitslen) {
+   case 512:
+   return PKE_RSA_DP2_512;
+   case 1024:
+   return PKE_RSA_DP2_1024;
+   case 1536:
+   return PKE_RSA_DP2_1536;
+   case 2048:
+   return PKE_RSA_DP2_2048;
+   case 3072:
+   return PKE_RSA_DP2_3072;
+   case 4096:
+   return PKE_RSA_DP2_4096;
+   default:
+   return 0;
+   };
+}
+
 static int qat_rsa_enc(struct akcipher_request *req)
 {
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
@@ -388,7 +436,9 @@ static int qat_rsa_dec(struct akcipher_request *req)
memset(msg, '\0', sizeof(*msg));
ICP_QAT_FW_PKE_HDR_VALID_FLAG_SET(msg->pke_hdr,
  ICP_QAT_FW_COMN_REQ_FLAG_SET);
-   msg->pke_hdr.cd_pars.func_id = qat_rsa_dec_fn_id(ctx->key_sz);
+   msg->pke_hdr.cd_pars.func_id = ctx->crt_mode ?
+   qat_rsa_dec_fn_id_crt(ctx->key_sz) :
+   qat_rsa_dec_fn_id(ctx->key_sz);
if (unlikely(!msg->pke_hdr.cd_pars.func_id))
return -EINVAL;
 
@@ -398,8 +448,16 @@ static int qat_rsa_dec(struct akcipher_request *req)
ICP_QAT_FW_COMN_FLAGS_BUILD(QAT_COMN_PTR_TYPE_FLAT,
QAT_COMN_CD_FLD_TYPE_64BIT_ADR);
 
-   qat_req->in.dec.d = ctx->dma_d;
-   qat_req->in.dec.n = ctx->dma_n;
+   if (ctx->crt_mode) {
+   qat_req->in.dec_crt.p = ctx->dma_p;
+   qat_req->in.dec_crt.q = ctx->dma_q;
+   qat_req->in.dec_crt.dp = ctx->dma_dp;
+   qat_req->in.dec_crt.dq = ctx->dma_dq;
+   qat_req->in.dec_crt.qinv = ctx->dma_qinv;
+   } else {
+   qat_req->in.dec.d = ctx->dma_d;
+   qat_req->in.dec.n = ctx->dma_n;
+   }
ret = -ENOMEM;
 
/*
@@ -446,7 +504,10 @@ static int qat_rsa_dec(struct akcipher_request *req)
 
}
 
-   qat_req->in.in_tab[3] = 0;
+   if (ctx->crt_mode)
+   qat_req->in.in_tab[6] = 0;
+   else
+   qat_req->in.in_tab[3] = 0;
qat_req->out.out_tab[1] = 0;
qat_req->phy_in = dma_map_single(dev, &qat_req->in.dec.c,
 sizeof(struct qat_rsa_input_params),
@@ -463,7 +524,11 @@ static int qat_rsa_dec(struct akcipher_request *req)
msg->pke_mid.src_data_addr = qat_req->phy_in;
msg->pke_mid.dest_data_addr = qat_req->phy_out;
msg->pke_mid.opaque = (uint64_t)(__force long)req;
-   msg->input_param_count = 3;
+   if (ctx->crt_mode)
+   msg->input_param_count = 6;
+   else
+   msg->input_param_count = 3;
+
msg->output_param_count = 1;
do {
ret = adf_send_message(ctx->i

[PATCH 2/3] crypto: testmgr - Add 4K private key to RSA testvector

2016-07-04 Thread Salvatore Benedetto
Key generated with openssl. It also contains all fields required
for testing CRT mode

Signed-off-by: Salvatore Benedetto 
---
 crypto/testmgr.h | 200 ++-
 1 file changed, 199 insertions(+), 1 deletion(-)

diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 4ce2d86..acb6bbf 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -152,7 +152,7 @@ static char zeroed_string[48];
 #ifdef CONFIG_CRYPTO_FIPS
 #define RSA_TEST_VECTORS   2
 #else
-#define RSA_TEST_VECTORS   4
+#define RSA_TEST_VECTORS   5
 #endif
 static struct akcipher_testvec rsa_tv_template[] = {
{
@@ -338,6 +338,204 @@ static struct akcipher_testvec rsa_tv_template[] = {
.m_size = 8,
.c_size = 256,
.public_key_vec = true,
+   }, {
+   .key =
+   "\x30\x82\x09\x29" /* sequence of 2345 bytes */
+   "\x02\x01\x00" /* version integer of 1 byte */
+   "\x02\x82\x02\x01" /* modulus - integer of 513 bytes */
+   "\x00\xC3\x8B\x55\x7B\x73\x4D\xFF\xE9\x9B\xC6\xDC\x67\x3C\xB4\x8E"
+   "\xA0\x86\xED\xF2\xB9\x50\x5C\x54\x5C\xBA\xE4\xA1\xB2\xA7\xAE\x2F"
+   "\x1B\x7D\xF1\xFB\xAC\x79\xC5\xDF\x1A\x00\xC9\xB2\xC1\x61\x25\x33"
+   "\xE6\x9C\xE9\xCF\xD6\x27\xC4\x4E\x44\x30\x44\x5E\x08\xA1\x87\x52"
+   "\xCC\x6B\x97\x70\x8C\xBC\xA5\x06\x31\x0C\xD4\x2F\xD5\x7D\x26\x24"
+   "\xA2\xE2\xAC\x78\xF4\x53\x14\xCE\xF7\x19\x2E\xD7\xF7\xE6\x0C\xB9"
+   "\x56\x7F\x0B\xF1\xB1\xE2\x43\x70\xBD\x86\x1D\xA1\xCC\x2B\x19\x08"
+   "\x76\xEF\x91\xAC\xBF\x20\x24\x0D\x38\xC0\x89\xB8\x9A\x70\xB3\x64"
+   "\xD9\x8F\x80\x41\x10\x5B\x9F\xB1\xCB\x76\x43\x00\x21\x25\x36\xD4"
+   "\x19\xFC\x55\x95\x10\xE4\x26\x74\x98\x2C\xD9\xBD\x0B\x2B\x04\xC2"
+   "\xAC\x82\x38\xB4\xDD\x4C\x04\x7E\x51\x36\x40\x1E\x0B\xC4\x7C\x25"
+   "\xDD\x4B\xB2\xE7\x20\x0A\x57\xF9\xB4\x94\xC3\x08\x33\x22\x6F\x8B"
+   "\x48\xDB\x03\x68\x5A\x5B\xBA\xAE\xF3\xAD\xCF\xC3\x6D\xBA\xF1\x28"
+   "\x67\x7E\x6C\x79\x07\xDE\xFC\xED\xE7\x96\xE3\x6C\xE0\x2C\x87\xF8"
+   "\x02\x01\x28\x38\x43\x21\x53\x84\x69\x75\x78\x15\x7E\xEE\xD2\x1B"
+   "\xB9\x23\x40\xA8\x86\x1E\x38\x83\xB2\x73\x1D\x53\xFB\x9E\x2A\x8A"
+   "\xB2\x75\x35\x01\xC3\xC3\xC4\x94\xE8\x84\x86\x64\x81\xF4\x42\xAA"
+   "\x3C\x0E\xD6\x4F\xBC\x0A\x09\x2D\xE7\x1B\xD4\x10\xA8\x54\xEA\x89"
+   "\x84\x8A\xCB\xF7\x5A\x3C\xCA\x76\x08\x29\x62\xB4\x6A\x22\xDF\x14"
+   "\x95\x71\xFD\xB6\x86\x39\xB8\x8B\xF8\x91\x7F\x38\xAA\x14\xCD\xE5"
+   "\xF5\x1D\xC2\x6D\x53\x69\x52\x84\x7F\xA3\x1A\x5E\x26\x04\x83\x06"
+   "\x73\x52\x56\xCF\x76\x26\xC9\xDD\x75\xD7\xFC\xF4\x69\xD8\x7B\x55"
+   "\xB7\x68\x13\x53\xB9\xE7\x89\xC3\xE8\xD6\x6E\xA7\x6D\xEA\x81\xFD"
+   "\xC4\xB7\x05\x5A\xB7\x41\x0A\x23\x8E\x03\x8A\x1C\xAE\xD3\x1E\xCE"
+   "\xE3\x5E\xFC\x19\x4A\xEE\x61\x9B\x8E\xE5\xE5\xDD\x85\xF9\x41\xEC"
+   "\x14\x53\x92\xF7\xDD\x06\x85\x02\x91\xE3\xEB\x6C\x43\x03\xB1\x36"
+   "\x7B\x89\x5A\xA8\xEB\xFC\xD5\xA8\x35\xDC\x81\xD9\x5C\xBD\xCA\xDC"
+   "\x9B\x98\x0B\x06\x5D\x0C\x5B\xEE\xF3\xD5\xCC\x57\xC9\x71\x2F\x90"
+   "\x3B\x3C\xF0\x8E\x4E\x35\x48\xAE\x63\x74\xA9\xFC\x72\x75\x8E\x34"
+   "\xA8\xF2\x1F\xEA\xDF\x3A\x37\x2D\xE5\x39\x39\xF8\x57\x58\x3C\x04"
+   "\xFE\x87\x06\x98\xBC\x7B\xD3\x21\x36\x60\x25\x54\xA7\x3D\xFA\x91"
+   "\xCC\xA8\x0B\x92\x8E\xB4\xF7\x06\xFF\x1E\x95\xCB\x07\x76\x97\x3B"
+   "\x9D"
+   "\x02\x03\x01\x00\x01" /* public key integer of 3 bytes */
+   "\x02\x82\x02\x00" /* private key integer of 512 bytes */
+   "\x74\xA9\xE0\x6A\x32\xB4\xCA\x85\xD9\x86\x9F\x60\x88\x7B\x40\xCC"
+   "\xCD\x33\x91\xA8\xB6\x25\x1F\xBF\xE3\x51\x1C\x97\xB6\x2A\xD9\xB8"
+   "\x11\x40\x19\xE3\x21\x13\xC8\xB3\x7E\xDC\xD7\x65\x40\x4C\x2D\xD6"
+   "\xDC\xAF\x32\x6C\x96\x75\x2C\x2C\xCA\x8F\x3F\x7A\xEE\xC4\x09\xC6"
+   "\x24\x3A\xC9\xCF\x6D\x8D\x17\x50\x94\x52\xD3\xE7\x0F\x2F\x7E\x94"
+   "\x1F\xA0\xBE\xD9\x25\xE8\x38\x42\x7C\x27\xD2\x79\xF8\x2A\x87\x38"
+   "\xEF\xBB\x74\x8B\xA8\x6E\x8C\x08\xC6\xC7\x4F\x0C\xBC\x79\xC6\xEF"
+   "\x0E\xA7\x5E\xE4\xF8\x8C\x09\xC7\x5E\x37\xCC\x87\x77\xCD\xCF\xD1"
+   "\x6D\x28\x1B\xA9\x62\xC0\xB8\x16\xA7\x8B\xF9\xBB\xCC\xB4\x15\x7F"
+   "\x1B\x69\x03\xF2\x7B\xEB\xE5\x8C\x14\xD6\x23\x4F\x52\x6F\x18\xA6"
+   "\x4B\x5B\x01\xAD\x35\xF9\x48\x53\xB3\x86\x35\x66\xD7\xE7\x29\xC0"
+   "\x09\xB5\xC6\xE6\xFA\xC4\xDA\x19\xBE\xD7\x4D\x41\x14\xBE\x6F\xDF"
+   "\x1B\xAB\xC0\xCA\x88\x07\xAC\xF1\x7D\x35

[PATCH 1/3] crypto: rsa - Store rest of the private key components

2016-07-04 Thread Salvatore Benedetto
When parsing a private key, store all non-optional fields. These
are required for enabling CRT mode for decrypt and verify

Signed-off-by: Salvatore Benedetto 
---
 crypto/rsa_helper.c   | 75 +++
 crypto/rsaprivkey.asn1| 10 +++---
 include/crypto/internal/rsa.h | 20 
 3 files changed, 100 insertions(+), 5 deletions(-)

diff --git a/crypto/rsa_helper.c b/crypto/rsa_helper.c
index 583656a..4df6451 100644
--- a/crypto/rsa_helper.c
+++ b/crypto/rsa_helper.c
@@ -78,6 +78,81 @@ int rsa_get_d(void *context, size_t hdrlen, unsigned char 
tag,
return 0;
 }
 
+int rsa_get_p(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+   struct rsa_key *key = context;
+
+   /* invalid key provided */
+   if (!value || !vlen || vlen > key->n_sz)
+   return -EINVAL;
+
+   key->p = value;
+   key->p_sz = vlen;
+
+   return 0;
+}
+
+int rsa_get_q(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+   struct rsa_key *key = context;
+
+   /* invalid key provided */
+   if (!value || !vlen || vlen > key->n_sz)
+   return -EINVAL;
+
+   key->q = value;
+   key->q_sz = vlen;
+
+   return 0;
+}
+
+int rsa_get_dp(void *context, size_t hdrlen, unsigned char tag,
+  const void *value, size_t vlen)
+{
+   struct rsa_key *key = context;
+
+   /* invalid key provided */
+   if (!value || !vlen || vlen > key->n_sz)
+   return -EINVAL;
+
+   key->dp = value;
+   key->dp_sz = vlen;
+
+   return 0;
+}
+
+int rsa_get_dq(void *context, size_t hdrlen, unsigned char tag,
+  const void *value, size_t vlen)
+{
+   struct rsa_key *key = context;
+
+   /* invalid key provided */
+   if (!value || !vlen || vlen > key->n_sz)
+   return -EINVAL;
+
+   key->dq = value;
+   key->dq_sz = vlen;
+
+   return 0;
+}
+
+int rsa_get_qinv(void *context, size_t hdrlen, unsigned char tag,
+const void *value, size_t vlen)
+{
+   struct rsa_key *key = context;
+
+   /* invalid key provided */
+   if (!value || !vlen || vlen > key->n_sz)
+   return -EINVAL;
+
+   key->qinv = value;
+   key->qinv_sz = vlen;
+
+   return 0;
+}
+
 /**
  * rsa_parse_pub_key() - decodes the BER encoded buffer and stores in the
  *   provided struct rsa_key, pointers to the raw key as 
is,
diff --git a/crypto/rsaprivkey.asn1 b/crypto/rsaprivkey.asn1
index 731aea5..4ce0675 100644
--- a/crypto/rsaprivkey.asn1
+++ b/crypto/rsaprivkey.asn1
@@ -3,9 +3,9 @@ RsaPrivKey ::= SEQUENCE {
n   INTEGER ({ rsa_get_n }),
e   INTEGER ({ rsa_get_e }),
d   INTEGER ({ rsa_get_d }),
-   prime1  INTEGER,
-   prime2  INTEGER,
-   exponent1   INTEGER,
-   exponent2   INTEGER,
-   coefficient INTEGER
+   prime1  INTEGER ({ rsa_get_p }),
+   prime2  INTEGER ({ rsa_get_q }),
+   exponent1   INTEGER ({ rsa_get_dp }),
+   exponent2   INTEGER ({ rsa_get_dq }),
+   coefficient INTEGER ({ rsa_get_qinv })
 }
diff --git a/include/crypto/internal/rsa.h b/include/crypto/internal/rsa.h
index d6c042a..9e8f159 100644
--- a/include/crypto/internal/rsa.h
+++ b/include/crypto/internal/rsa.h
@@ -19,17 +19,37 @@
  * @n   : RSA modulus raw byte stream
  * @e   : RSA public exponent raw byte stream
  * @d   : RSA private exponent raw byte stream
+ * @p   : RSA prime factor p of n raw byte stream
+ * @q   : RSA prime factor q of n raw byte stream
+ * @dp  : RSA exponent d mod (p - 1) raw byte stream
+ * @dq  : RSA exponent d mod (q - 1) raw byte stream
+ * @qinv: RSA CRT coefficient q^(-1) mod p raw byte stream
  * @n_sz: length in bytes of RSA modulus n
  * @e_sz: length in bytes of RSA public exponent
  * @d_sz: length in bytes of RSA private exponent
+ * @p_sz: length in bytes of p field
+ * @q_sz: length in bytes of q field
+ * @dp_sz   : length in bytes of dp field
+ * @dq_sz   : length in bytes of dq field
+ * @qinv_sz : length in bytes of qinv field
  */
 struct rsa_key {
const u8 *n;
const u8 *e;
const u8 *d;
+   const u8 *p;
+   const u8 *q;
+   const u8 *dp;
+   const u8 *dq;
+   const u8 *qinv;
size_t n_sz;
size_t e_sz;
size_t d_sz;
+   size_t p_sz;
+   size_t q_sz;
+   size_t dp_sz;
+   size_t dq_sz;
+   size_t qinv_sz;
 };
 
 int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body 

[PATCH 0/3] Add RSA CRT mode to qat driver

2016-07-04 Thread Salvatore Benedetto
Hi Herbert,

this patchset add CRT mode to qat driver.
First patch extend the parsing of the private key so that all required CRT
fields are saved. Second patch add a 4K test key. Third patch extend qat
to use CRT. This latest patch is based on my patch that drop asn1 from qat
driver.

Salvatore Benedetto (3):
  crypto: rsa - Store rest of the private key components
  crypto: testmgr - Add 4K private key to RSA testvector
  crypto: qat - Add RSA CRT mode

 crypto/rsa_helper.c   |  75 +
 crypto/rsaprivkey.asn1|  10 +-
 crypto/testmgr.h  | 200 +-
 drivers/crypto/qat/qat_common/qat_asym_algs.c | 234 +++---
 include/crypto/internal/rsa.h |  20 +++
 5 files changed, 508 insertions(+), 31 deletions(-)

-- 
2.7.4

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


[PATCH] crypto: testmgr - Set err before proceeding

2016-07-04 Thread Salvatore Benedetto
Report correct error in case of failure

Signed-off-by: Salvatore Benedetto 
---
 crypto/testmgr.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 8ea0d3f..769cc2a 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -1941,6 +1941,7 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
if (err)
goto free_req;
 
+   err = -ENOMEM;
out_len_max = crypto_akcipher_maxsize(tfm);
outbuf_enc = kzalloc(out_len_max, GFP_KERNEL);
if (!outbuf_enc)
-- 
2.7.4

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


[PATCH v2] crypto: qat - Switch to new rsa_helper functions

2016-07-04 Thread Salvatore Benedetto
Drop all asn1 related code and use the new rsa_helper
functions rsa_parse_[pub|priv]_key for parsing the key

Signed-off-by: Salvatore Benedetto 
---

changes from v1:
 - Remove testmgr unrelated changes
 - Rebased on latest cryptodev-2.6

 drivers/crypto/qat/Kconfig|  2 +-
 drivers/crypto/qat/qat_common/Makefile| 10 -
 drivers/crypto/qat/qat_common/qat_asym_algs.c | 49 +--
 drivers/crypto/qat/qat_common/qat_rsaprivkey.asn1 | 11 -
 drivers/crypto/qat/qat_common/qat_rsapubkey.asn1  |  4 --
 5 files changed, 21 insertions(+), 55 deletions(-)
 delete mode 100644 drivers/crypto/qat/qat_common/qat_rsaprivkey.asn1
 delete mode 100644 drivers/crypto/qat/qat_common/qat_rsapubkey.asn1

diff --git a/drivers/crypto/qat/Kconfig b/drivers/crypto/qat/Kconfig
index 85b44e5..571d04d 100644
--- a/drivers/crypto/qat/Kconfig
+++ b/drivers/crypto/qat/Kconfig
@@ -5,11 +5,11 @@ config CRYPTO_DEV_QAT
select CRYPTO_BLKCIPHER
select CRYPTO_AKCIPHER
select CRYPTO_HMAC
+   select CRYPTO_RSA
select CRYPTO_SHA1
select CRYPTO_SHA256
select CRYPTO_SHA512
select FW_LOADER
-   select ASN1
 
 config CRYPTO_DEV_QAT_DH895xCC
tristate "Support for Intel(R) DH895xCC"
diff --git a/drivers/crypto/qat/qat_common/Makefile 
b/drivers/crypto/qat/qat_common/Makefile
index 6d74b91..92fb6ff 100644
--- a/drivers/crypto/qat/qat_common/Makefile
+++ b/drivers/crypto/qat/qat_common/Makefile
@@ -1,11 +1,3 @@
-$(obj)/qat_rsapubkey-asn1.o: $(obj)/qat_rsapubkey-asn1.c \
-$(obj)/qat_rsapubkey-asn1.h
-$(obj)/qat_rsaprivkey-asn1.o: $(obj)/qat_rsaprivkey-asn1.c \
- $(obj)/qat_rsaprivkey-asn1.h
-
-clean-files += qat_rsapubkey-asn1.c qat_rsapubkey-asn1.h
-clean-files += qat_rsaprivkey-asn1.c qat_rsaprivkey-asn1.h
-
 obj-$(CONFIG_CRYPTO_DEV_QAT) += intel_qat.o
 intel_qat-objs := adf_cfg.o \
adf_isr.o \
@@ -19,8 +11,6 @@ intel_qat-objs := adf_cfg.o \
adf_hw_arbiter.o \
qat_crypto.o \
qat_algs.o \
-   qat_rsapubkey-asn1.o \
-   qat_rsaprivkey-asn1.o \
qat_asym_algs.o \
qat_uclo.o \
qat_hal.o
diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c 
b/drivers/crypto/qat/qat_common/qat_asym_algs.c
index 05f49d4..04b0ef8 100644
--- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
+++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
@@ -52,8 +52,6 @@
 #include 
 #include 
 #include 
-#include "qat_rsapubkey-asn1.h"
-#include "qat_rsaprivkey-asn1.h"
 #include "icp_qat_fw_pke.h"
 #include "adf_accel_devices.h"
 #include "adf_transport.h"
@@ -502,10 +500,8 @@ unmap_src:
return ret;
 }
 
-int qat_rsa_get_n(void *context, size_t hdrlen, unsigned char tag,
- const void *value, size_t vlen)
+int qat_rsa_set_n(struct qat_rsa_ctx *ctx, const char *value, size_t vlen)
 {
-   struct qat_rsa_ctx *ctx = context;
struct qat_crypto_instance *inst = ctx->inst;
struct device *dev = &GET_DEV(inst->accel_dev);
const char *ptr = value;
@@ -518,11 +514,6 @@ int qat_rsa_get_n(void *context, size_t hdrlen, unsigned 
char tag,
 
ctx->key_sz = vlen;
ret = -EINVAL;
-   /* In FIPS mode only allow key size 2K & 3K */
-   if (fips_enabled && (ctx->key_sz != 256 && ctx->key_sz != 384)) {
-   pr_err("QAT: RSA: key size not allowed in FIPS mode\n");
-   goto err;
-   }
/* invalid key size provided */
if (!qat_rsa_enc_fn_id(ctx->key_sz))
goto err;
@@ -540,10 +531,8 @@ err:
return ret;
 }
 
-int qat_rsa_get_e(void *context, size_t hdrlen, unsigned char tag,
- const void *value, size_t vlen)
+int qat_rsa_set_e(struct qat_rsa_ctx *ctx, const char *value, size_t vlen)
 {
-   struct qat_rsa_ctx *ctx = context;
struct qat_crypto_instance *inst = ctx->inst;
struct device *dev = &GET_DEV(inst->accel_dev);
const char *ptr = value;
@@ -559,18 +548,15 @@ int qat_rsa_get_e(void *context, size_t hdrlen, unsigned 
char tag,
}
 
ctx->e = dma_zalloc_coherent(dev, ctx->key_sz, &ctx->dma_e, GFP_KERNEL);
-   if (!ctx->e) {
-   ctx->e = NULL;
+   if (!ctx->e)
return -ENOMEM;
-   }
+
memcpy(ctx->e + (ctx->key_sz - vlen), ptr, vlen);
return 0;
 }
 
-int qat_rsa_get_d(void *context, size_t hdrlen, unsigned char tag,
- const void *value, size_t vlen)
+int qat_rsa_set_d(struct qat_rsa_ctx *ctx, const char *value, size_t vlen)
 {
-   struct qat_rsa_ctx *ctx = context;
struct qat_crypto_instance *inst = ctx->inst;
struct device *dev = &GET_DEV(inst->accel_dev);
const char *ptr = value;
@@ -585,12 +571,6 @@ int qat_rsa

[PATCH] crypto: qat - Switch to new rsa_helper functions

2016-06-30 Thread Salvatore Benedetto
Drop all asn1 related code in qat and use the new rsa_helper
functions rsa_parse_[pub|priv]_key for parsing the key

Signed-off-by: Salvatore Benedetto 
---
 crypto/testmgr.c  |  1 +
 drivers/crypto/qat/Kconfig|  2 +-
 drivers/crypto/qat/qat_common/Makefile| 10 -
 drivers/crypto/qat/qat_common/qat_asym_algs.c | 49 +--
 drivers/crypto/qat/qat_common/qat_rsaprivkey.asn1 | 11 -
 drivers/crypto/qat/qat_common/qat_rsapubkey.asn1  |  4 --
 6 files changed, 22 insertions(+), 55 deletions(-)
 delete mode 100644 drivers/crypto/qat/qat_common/qat_rsaprivkey.asn1
 delete mode 100644 drivers/crypto/qat/qat_common/qat_rsapubkey.asn1

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 537fdc3..b52a81c 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -1941,6 +1941,7 @@ static int do_test_rsa(struct crypto_akcipher *tfm,
if (err)
goto free_req;
 
+   err = -ENOMEM;
out_len_max = crypto_akcipher_maxsize(tfm);
outbuf_enc = kzalloc(out_len_max, GFP_KERNEL);
if (!outbuf_enc)
diff --git a/drivers/crypto/qat/Kconfig b/drivers/crypto/qat/Kconfig
index 85b44e5..571d04d 100644
--- a/drivers/crypto/qat/Kconfig
+++ b/drivers/crypto/qat/Kconfig
@@ -5,11 +5,11 @@ config CRYPTO_DEV_QAT
select CRYPTO_BLKCIPHER
select CRYPTO_AKCIPHER
select CRYPTO_HMAC
+   select CRYPTO_RSA
select CRYPTO_SHA1
select CRYPTO_SHA256
select CRYPTO_SHA512
select FW_LOADER
-   select ASN1
 
 config CRYPTO_DEV_QAT_DH895xCC
tristate "Support for Intel(R) DH895xCC"
diff --git a/drivers/crypto/qat/qat_common/Makefile 
b/drivers/crypto/qat/qat_common/Makefile
index 6d74b91..92fb6ff 100644
--- a/drivers/crypto/qat/qat_common/Makefile
+++ b/drivers/crypto/qat/qat_common/Makefile
@@ -1,11 +1,3 @@
-$(obj)/qat_rsapubkey-asn1.o: $(obj)/qat_rsapubkey-asn1.c \
-$(obj)/qat_rsapubkey-asn1.h
-$(obj)/qat_rsaprivkey-asn1.o: $(obj)/qat_rsaprivkey-asn1.c \
- $(obj)/qat_rsaprivkey-asn1.h
-
-clean-files += qat_rsapubkey-asn1.c qat_rsapubkey-asn1.h
-clean-files += qat_rsaprivkey-asn1.c qat_rsaprivkey-asn1.h
-
 obj-$(CONFIG_CRYPTO_DEV_QAT) += intel_qat.o
 intel_qat-objs := adf_cfg.o \
adf_isr.o \
@@ -19,8 +11,6 @@ intel_qat-objs := adf_cfg.o \
adf_hw_arbiter.o \
qat_crypto.o \
qat_algs.o \
-   qat_rsapubkey-asn1.o \
-   qat_rsaprivkey-asn1.o \
qat_asym_algs.o \
qat_uclo.o \
qat_hal.o
diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c 
b/drivers/crypto/qat/qat_common/qat_asym_algs.c
index 05f49d4..04b0ef8 100644
--- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
+++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
@@ -52,8 +52,6 @@
 #include 
 #include 
 #include 
-#include "qat_rsapubkey-asn1.h"
-#include "qat_rsaprivkey-asn1.h"
 #include "icp_qat_fw_pke.h"
 #include "adf_accel_devices.h"
 #include "adf_transport.h"
@@ -502,10 +500,8 @@ unmap_src:
return ret;
 }
 
-int qat_rsa_get_n(void *context, size_t hdrlen, unsigned char tag,
- const void *value, size_t vlen)
+int qat_rsa_set_n(struct qat_rsa_ctx *ctx, const char *value, size_t vlen)
 {
-   struct qat_rsa_ctx *ctx = context;
struct qat_crypto_instance *inst = ctx->inst;
struct device *dev = &GET_DEV(inst->accel_dev);
const char *ptr = value;
@@ -518,11 +514,6 @@ int qat_rsa_get_n(void *context, size_t hdrlen, unsigned 
char tag,
 
ctx->key_sz = vlen;
ret = -EINVAL;
-   /* In FIPS mode only allow key size 2K & 3K */
-   if (fips_enabled && (ctx->key_sz != 256 && ctx->key_sz != 384)) {
-   pr_err("QAT: RSA: key size not allowed in FIPS mode\n");
-   goto err;
-   }
/* invalid key size provided */
if (!qat_rsa_enc_fn_id(ctx->key_sz))
goto err;
@@ -540,10 +531,8 @@ err:
return ret;
 }
 
-int qat_rsa_get_e(void *context, size_t hdrlen, unsigned char tag,
- const void *value, size_t vlen)
+int qat_rsa_set_e(struct qat_rsa_ctx *ctx, const char *value, size_t vlen)
 {
-   struct qat_rsa_ctx *ctx = context;
struct qat_crypto_instance *inst = ctx->inst;
struct device *dev = &GET_DEV(inst->accel_dev);
const char *ptr = value;
@@ -559,18 +548,15 @@ int qat_rsa_get_e(void *context, size_t hdrlen, unsigned 
char tag,
}
 
ctx->e = dma_zalloc_coherent(dev, ctx->key_sz, &ctx->dma_e, GFP_KERNEL);
-   if (!ctx->e) {
-   ctx->e = NULL;
+   if (!ctx->e)
return -ENOMEM;
-   }
+
memcpy(ctx->e + (ctx->key_sz - vlen), ptr, vlen);
return 0;
 }
 
-int qat_rsa_get_d(void *context, size_t h

[PATCH v5] Bluetooth: convert smp and selftest to crypto kpp API

2016-06-24 Thread Salvatore Benedetto
 * Convert both smp and selftest to new crypto kpp API
 * Remove module ecc as not more required
 * Add ecdh_helper functions for wrapping kpp async calls

Signed-off-by: Salvatore Benedetto 
---

Patch is based on 
http://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git

Tested with self-testing only. Need to be tested with real hardware.

Changes from v4:
 * Patch adjusted to API change. crypto_kpp_set_params and crypto_kpp_set_secret
   are now merged and a crypto_ecdh_encode_key helper is provided for packing
   the secret.

Changes from v3:
 * Patch adjusted to minor API change. crypto_kpp_set_params no longer
   takes len as input parameter

Changes from v2:
 * Remove header guard in internal header
 * Shorter name for ecdh wrappers and fix 80chars issue
 * Add CRYPTO_ECDH dependency in bluetooth Kconfig

Changes from v1:
 * Convert ecc_make_key to kpp API


 net/bluetooth/Kconfig   |   1 +
 net/bluetooth/Makefile  |   2 +-
 net/bluetooth/ecc.c | 816 
 net/bluetooth/ecc.h |  54 ---
 net/bluetooth/ecdh_helper.c | 216 
 net/bluetooth/ecdh_helper.h |  27 ++
 net/bluetooth/selftest.c|   6 +-
 net/bluetooth/smp.c |   8 +-
 8 files changed, 252 insertions(+), 878 deletions(-)
 delete mode 100644 net/bluetooth/ecc.c
 delete mode 100644 net/bluetooth/ecc.h
 create mode 100644 net/bluetooth/ecdh_helper.c
 create mode 100644 net/bluetooth/ecdh_helper.h

diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
index 06c31b9..68f951b 100644
--- a/net/bluetooth/Kconfig
+++ b/net/bluetooth/Kconfig
@@ -13,6 +13,7 @@ menuconfig BT
select CRYPTO_CMAC
select CRYPTO_ECB
select CRYPTO_SHA256
+   select CRYPTO_ECDH
help
  Bluetooth is low-cost, low-power, short-range wireless technology.
  It was designed as a replacement for cables and other short-range
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index b3ff12e..c54d790 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -13,7 +13,7 @@ bluetooth_6lowpan-y := 6lowpan.o
 
 bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \
hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o lib.o \
-   ecc.o hci_request.o mgmt_util.o
+   ecdh_helper.o hci_request.o mgmt_util.o
 
 bluetooth-$(CONFIG_BT_BREDR) += sco.o
 bluetooth-$(CONFIG_BT_HS) += a2mp.o amp.o
diff --git a/net/bluetooth/ecc.c b/net/bluetooth/ecc.c
deleted file mode 100644
index e1709f8..000
--- a/net/bluetooth/ecc.c
+++ /dev/null
@@ -1,816 +0,0 @@
-/*
- * Copyright (c) 2013, Kenneth MacKay
- * All rights reserved.
- *
- * 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.
- *
- * 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
- * HOLDER 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 
-
-#include "ecc.h"
-
-/* 256-bit curve */
-#define ECC_BYTES 32
-
-#define MAX_TRIES 16
-
-/* Number of u64's needed */
-#define NUM_ECC_DIGITS (ECC_BYTES / 8)
-
-struct ecc_point {
-   u64 x[NUM_ECC_DIGITS];
-   u64 y[NUM_ECC_DIGITS];
-};
-
-typedef struct {
-   u64 m_low;
-   u64 m_high;
-} uint128_t;
-
-#define CURVE_P_32 {   0xull, 0xull, \
-   0xull, 0x0001ull }
-
-#define CURVE_G_32 { \
-   {   0xF4A13945D898C296ull, 0x77037D812DEB33A0ull,   \
-   0xF8BCE6E563A440F2ull, 0x6B17D1F2E12C4247ull }, \
-   {   0xCBB6406837BF51F5ull, 0x2BCE33576B315ECEull,   \
-   0x8EE7EB4A7C0F9E16ull, 0x4FE342E2FE1A7F9Bull }  \
-}
-
-#define CURVE_N_32 {   0xF3B9CAC2FC632551ull, 0xBCE6FAADA7179E84ull,   \
-   0xull, 0xul

Re: [cryptodev:master 79/79] (.text+0x330de0): multiple definition of `ecdh_shared_secret'

2016-06-23 Thread Salvatore Benedetto
On Fri, Jun 24, 2016 at 07:23:16AM +0100, Herbert Xu wrote:
> On Fri, Jun 24, 2016 at 02:10:12PM +0800, Herbert Xu wrote:
> > On Fri, Jun 24, 2016 at 07:06:49AM +0100, Salvatore Benedetto wrote:
> > >
> > > can you squash the following patch?
> > 
> > No, please prune anything that we don't use from ecc.c.
> 
> I take that back.  I see it's actually coming from bluetooth.
> 
> How about moving ecc.c to lib so that it's shared between the
> two?

The patch was based on the current tree. I just pulled.
There is not point in moving to lib because bluetooth is
about to be converted to kpp. 
That patch I believe will go up the bluetooth tree, so
my suggestion is to simply accept that I fail to properly
name that symbol.

Renaming the symbol in net/bluetooth/ecc which I think will conflict
with the patch where I remove it completely which, again, I believe
will go up the BT tree.

Thanks,
Salvatore

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


Re: [cryptodev:master 79/79] (.text+0x330de0): multiple definition of `ecdh_shared_secret'

2016-06-23 Thread Salvatore Benedetto
On Fri, Jun 24, 2016 at 02:10:12PM +0800, Herbert Xu wrote:
> On Fri, Jun 24, 2016 at 07:06:49AM +0100, Salvatore Benedetto wrote:
> >
> > can you squash the following patch?
> 
> No, please prune anything that we don't use from ecc.c.

We do use the symbol in question, and I'm pretty sure we use
all of crypto/ecc.c. I was going to send a patch where
I remove the net/bluetooth/ecc.c

How do you want me to proceed with this build failure?
Do you want me to send a new patch so that you can revert
3c4b23901a0c766879dff680cd6bdab47bcdbbd2 ?

Thanks,
Salvatore

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


Re: [cryptodev:master 79/79] (.text+0x330de0): multiple definition of `ecdh_shared_secret'

2016-06-23 Thread Salvatore Benedetto
On Fri, Jun 24, 2016 at 03:47:04AM +0800, kbuild test robot wrote:
> tree:   
> https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git 
> master
> head:   3c4b23901a0c766879dff680cd6bdab47bcdbbd2
> commit: 3c4b23901a0c766879dff680cd6bdab47bcdbbd2 [79/79] crypto: ecdh - Add 
> ECDH software support
> config: i386-allyesconfig (attached as .config)
> compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430
> reproduce:
> git checkout 3c4b23901a0c766879dff680cd6bdab47bcdbbd2
> # save the attached .config to linux build tree
> make ARCH=i386 
> 
> All errors (new ones prefixed by >>):
> 
>net/built-in.o: In function `ecdh_shared_secret':
> >> (.text+0x330de0): multiple definition of `ecdh_shared_secret'
>crypto/built-in.o:(.text+0xb1b0): first defined here
> 
> ---
> 0-DAY kernel test infrastructureOpen Source Technology Center
> https://lists.01.org/pipermail/kbuild-all   Intel Corporation

Hi Herbert,

can you squash the following patch?

Thanks,
Salvatore

---8<---
Rename ecdh_shared_secret

Signed-off-by: Salvatore Benedetto 
---
 crypto/ecc.c  |  8 
 crypto/ecc.h  | 12 ++--
 crypto/ecdh.c |  8 
 3 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/crypto/ecc.c b/crypto/ecc.c
index 9aedec6..1ba2436 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -966,10 +966,10 @@ out:
return ret;
 }
 
-int ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
-  const u8 *private_key, unsigned int private_key_len,
-  const u8 *public_key, unsigned int public_key_len,
-  u8 *secret, unsigned int secret_len)
+int ecdh_compute_ss(unsigned int curve_id, unsigned int ndigits,
+   const u8 *private_key, unsigned int private_key_len,
+   const u8 *public_key, unsigned int public_key_len,
+   u8 *secret, unsigned int secret_len)
 {
int ret = 0;
struct ecc_point *product, *pk;
diff --git a/crypto/ecc.h b/crypto/ecc.h
index b5db4b9..a856175 100644
--- a/crypto/ecc.h
+++ b/crypto/ecc.h
@@ -60,7 +60,7 @@ int ecdh_make_pub_key(const unsigned int curve_id, unsigned 
int ndigits,
  u8 *public_key, unsigned int public_key_len);
 
 /**
- * ecdh_shared_secret() - Compute a shared secret
+ * ecdh_compute_ss() - Compute a shared secret
  *
  * @curve_id:  id representing the curve to use
  * @private_key:   private key of part A
@@ -70,14 +70,14 @@ int ecdh_make_pub_key(const unsigned int curve_id, unsigned 
int ndigits,
  * @secret:buffer for storing the calculated shared secret
  * @secret_len:length of the secret buffer
  *
- * Note: It is recommended that you hash the result of ecdh_shared_secret
+ * Note: It is recommended that you hash the result of ecdh_compute_ss
  * before using it for symmetric encryption or HMAC.
  *
  * Returns 0 if the shared secret was generated successfully, a negative value
  * if an error occurred.
  */
-int ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
-  const u8 *private_key, unsigned int private_key_len,
-  const u8 *public_key, unsigned int public_key_len,
-  u8 *secret, unsigned int secret_len);
+int ecdh_compute_ss(unsigned int curve_id, unsigned int ndigits,
+   const u8 *private_key, unsigned int private_key_len,
+   const u8 *public_key, unsigned int public_key_len,
+   u8 *secret, unsigned int secret_len);
 #endif
diff --git a/crypto/ecdh.c b/crypto/ecdh.c
index d3a9eec..7e12a34 100644
--- a/crypto/ecdh.c
+++ b/crypto/ecdh.c
@@ -79,10 +79,10 @@ static int ecdh_compute_value(struct kpp_request *req)
if (copied != 2 * nbytes)
return -EINVAL;
 
-   ret = ecdh_shared_secret(ctx->curve_id, ctx->ndigits,
-(const u8 *)ctx->private_key, nbytes,
-(const u8 *)ctx->public_key, 2 * 
nbytes,
-(u8 *)ctx->shared_secret, nbytes);
+   ret = ecdh_compute_ss(ctx->curve_id, ctx->ndigits,
+ (const u8 *)ctx->private_key, nbytes,
+ (const u8 *)ctx->public_key, 2 * nbytes,
+ (u8 *)ctx->shared_secret, nbytes);
 
buf = ctx->shared_secret;
} else {
-- 
2.7.4

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


[PATCH v11 0/3] Key-agreement Protocol Primitives (KPP) API

2016-06-22 Thread Salvatore Benedetto
Hi Herb,

the following patchset introduces a new API for abstracting key-agreement
protocols such as DH and ECDH. It provides the primitives required for 
implementing
the protocol, thus the name KPP (Key-agreement Protocol Primitives).

Regards,
Salvatore

Changes from v10:
* Remove all DH/ECDH code from testmgr. Secret is now encoded both
  in little and big endian in the testvector

Changes from v9:
* Fix encoding/decoding of buffer packed with kpp_secret.

Changes from v8:
* set_secret accept a buffer packed and prefixed with a tiny header of
  2 fields: type and len. Each kpp type define its own type and provide
  helper for user (encoder) and drivers (decoder)

Changed from v7:
* API change: merge set_param and set_key to set_key. Params and private
  key are now provided together. Params have always to be provided.
* Merge generate_public_key and compute_shared_secret into compute_val.
  API stay as it is
* Add ecc_is_key_valid to validate private key when set. Now that params
  and key are set together we can validate the key right away. Before the
  check was deferred to generate_public_key.

Changes from v6:
* Remove len parameter from crypto_kpp_set_params. Adjust rest of code
  accordingly
* Remove the while loop in ecdh_make_pub_key as the private key is fixed and
  iterating is pointless. EAGAIN is now to returned to make the user aware
  that he needs to regenerate/reset the private key

Changes from v5:
* Fix ecdh loading in fips mode.

Changes from v4:
* If fips_enabled is set allow only P256 (or higher) as Stephan suggested
* Pass ndigits as argument to ecdh_make_pub_key and ecdh_shared_secret
  so that VLA can be used like in the rest of the module

Changes from v3:
* Move curve ID definition to public header ecdh.h as users need to
  have access to those ids when selecting the curve

Changes from v2:
* Add support for ECDH (curve P192 and P256). I reused the ecc module
  already present in net/bluetooth and extended it in order to select
  different curves at runtime. Code for P192 was taken from tinycrypt.

Changes from v1:
* Change check in dh_check_params_length based on Stephan review

Salvatore Benedetto (3):
  crypto: Key-agreement Protocol Primitives API (KPP)
  crypto: kpp - Add DH software implementation
  crypto: kpp - Add ECDH software support

*** BLURB HERE ***

Salvatore Benedetto (3):
  crypto: Key-agreement Protocol Primitives API (KPP)
  crypto: kpp - Add DH software implementation
  crypto: kpp - Add ECDH software support

 crypto/Kconfig  |   23 +
 crypto/Makefile |9 +
 crypto/crypto_user.c|   20 +
 crypto/dh.c |  189 
 crypto/dh_helper.c  |   95 
 crypto/ecc.c| 1018 +++
 crypto/ecc.h|   83 
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  151 ++
 crypto/ecdh_helper.c|   86 
 crypto/kpp.c|  123 +
 crypto/testmgr.c|  154 ++
 crypto/testmgr.h|  323 +
 include/crypto/dh.h |   29 ++
 include/crypto/ecdh.h   |   30 ++
 include/crypto/internal/kpp.h   |   64 +++
 include/crypto/kpp.h|  330 +
 include/linux/crypto.h  |1 +
 include/uapi/linux/cryptouser.h |5 +
 19 files changed, 2790 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 crypto/dh_helper.c
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 crypto/ecdh_helper.c
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/dh.h
 create mode 100644 include/crypto/ecdh.h
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

-- 
2.7.4

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


[PATCH v11 3/3] crypto: kpp - Add ECDH software support

2016-06-22 Thread Salvatore Benedetto
 * Implement ECDH under kpp API
 * Provide ECC software support for curve P-192 and
   P-256.
 * Add kpp test for ECDH with data generated by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |5 +
 crypto/Makefile |4 +
 crypto/ecc.c| 1018 +++
 crypto/ecc.h|   83 
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  151 +++
 crypto/ecdh_helper.c|   86 
 crypto/testmgr.c|   10 +
 crypto/testmgr.h|   93 +
 include/crypto/ecdh.h   |   30 ++
 include/crypto/kpp.h|1 +
 11 files changed, 1538 insertions(+)
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 crypto/ecdh_helper.c
 create mode 100644 include/crypto/ecdh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 162d2f9..5baaa9d 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -118,6 +118,11 @@ config CRYPTO_DH
help
  Generic implementation of the Diffie-Hellman algorithm.
 
+config CRYPTO_ECDH
+   tristate "ECDH algorithm"
+   select CRYTPO_KPP
+   help
+ Generic implementation of the ECDH algorithm
 
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
diff --git a/crypto/Makefile b/crypto/Makefile
index 8289720..df1bcfb 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -35,6 +35,10 @@ obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 dh_generic-y := dh.o
 dh_generic-y += dh_helper.o
 obj-$(CONFIG_CRYPTO_DH) += dh_generic.o
+ecdh_generic-y := ecc.o
+ecdh_generic-y += ecdh.o
+ecdh_generic-y += ecdh_helper.o
+obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/ecc.c b/crypto/ecc.c
new file mode 100644
index 000..9aedec6
--- /dev/null
+++ b/crypto/ecc.c
@@ -0,0 +1,1018 @@
+/*
+ * Copyright (c) 2013, Kenneth MacKay
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * 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
+ * HOLDER 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 
+#include 
+#include 
+#include 
+#include 
+
+#include "ecc.h"
+#include "ecc_curve_defs.h"
+
+typedef struct {
+   u64 m_low;
+   u64 m_high;
+} uint128_t;
+
+static inline const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
+{
+   switch (curve_id) {
+   /* In FIPS mode only allow P256 and higher */
+   case ECC_CURVE_NIST_P192:
+   return fips_enabled ? NULL : &nist_p192;
+   case ECC_CURVE_NIST_P256:
+   return &nist_p256;
+   default:
+   return NULL;
+   }
+}
+
+static u64 *ecc_alloc_digits_space(unsigned int ndigits)
+{
+   size_t len = ndigits * sizeof(u64);
+
+   if (!len)
+   return NULL;
+
+   return kmalloc(len, GFP_KERNEL);
+}
+
+static void ecc_free_digits_space(u64 *space)
+{
+   kzfree(space);
+}
+
+static struct ecc_point *ecc_alloc_point(unsigned int ndigits)
+{
+   struct ecc_point *p = kmalloc(sizeof(*p), GFP_KERNEL);
+
+   if (!p)
+   return NULL;
+
+   p->x = ecc_alloc_digits_space(ndigits);
+   if (!p->x)
+   goto err_alloc_x;
+
+   p->y = ecc_alloc_digits_space(ndigits);
+   if (!p->y)
+   goto err_alloc_y;
+
+   p->ndigits = ndigits;
+
+   return p;
+
+err_alloc_y:
+   ecc_free_digits_space(p->x);
+err_alloc_x:
+   kfree(p);
+   return NULL;
+}
+
+static void ecc_free_point(struct ecc_point *p)
+{
+   if (!p)
+   return;
+

[PATCH v11 1/3] crypto: Key-agreement Protocol Primitives API (KPP)

2016-06-22 Thread Salvatore Benedetto
Add key-agreement protocol primitives (kpp) API which allows to
implement primitives required by protocols such as DH and ECDH.
The API is composed mainly by the following functions
 * set_secret() - It allows the user to set his secret, also
   referred to as his private key, along with the parameters
   known to both parties involved in the key-agreement session.
 * generate_public_key() - It generates the public key to be sent to
   the other counterpart involved in the key-agreement session. The
   function has to be called after set_params() and set_secret()
 * generate_secret() - It generates the shared secret for the session

Other functions such as init() and exit() are provided for allowing
cryptographic hardware to be inizialized properly before use

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |  10 ++
 crypto/Makefile |   1 +
 crypto/crypto_user.c|  20 +++
 crypto/kpp.c| 123 +++
 include/crypto/internal/kpp.h   |  64 
 include/crypto/kpp.h| 328 
 include/linux/crypto.h  |   1 +
 include/uapi/linux/cryptouser.h |   5 +
 8 files changed, 552 insertions(+)
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 6881d1a..e72c427 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -93,6 +93,15 @@ config CRYPTO_AKCIPHER
select CRYPTO_AKCIPHER2
select CRYPTO_ALGAPI
 
+config CRYPTO_KPP2
+   tristate
+   select CRYPTO_ALGAPI2
+
+config CRYPTO_KPP
+   tristate
+   select CRYPTO_ALGAPI
+   select CRYPTO_KPP2
+
 config CRYPTO_RSA
tristate "RSA algorithm"
select CRYPTO_AKCIPHER
@@ -115,6 +124,7 @@ config CRYPTO_MANAGER2
select CRYPTO_HASH2
select CRYPTO_BLKCIPHER2
select CRYPTO_AKCIPHER2
+   select CRYPTO_KPP2
 
 config CRYPTO_USER
tristate "Userspace cryptographic algorithm configuration"
diff --git a/crypto/Makefile b/crypto/Makefile
index 0b82c47..07b0f51 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -30,6 +30,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
+obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index f71960d..e7a0a9d 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "internal.h"
 
@@ -126,6 +127,21 @@ nla_put_failure:
return -EMSGSIZE;
 }
 
+static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   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)
 {
@@ -176,6 +192,10 @@ static int crypto_report_one(struct crypto_alg *alg,
goto nla_put_failure;
 
break;
+   case CRYPTO_ALG_TYPE_KPP:
+   if (crypto_report_kpp(skb, alg))
+   goto nla_put_failure;
+   break;
}
 
 out:
diff --git a/crypto/kpp.c b/crypto/kpp.c
new file mode 100644
index 000..d36ce05
--- /dev/null
+++ b/crypto/kpp.c
@@ -0,0 +1,123 @@
+/*
+ * Key-agreement Protocol Primitives (KPP)
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "internal.h"
+
+#ifdef CONFIG_NET
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+static void crypto_kpp_show(struct

[PATCH v11 2/3] crypto: kpp - Add DH software implementation

2016-06-22 Thread Salvatore Benedetto
 * Implement MPI based Diffie-Hellman under kpp API
 * Test provided uses data generad by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig   |   8 ++
 crypto/Makefile  |   4 +
 crypto/dh.c  | 189 ++
 crypto/dh_helper.c   |  95 +
 crypto/testmgr.c | 144 
 crypto/testmgr.h | 230 +++
 include/crypto/dh.h  |  29 +++
 include/crypto/kpp.h |   1 +
 8 files changed, 700 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 crypto/dh_helper.c
 create mode 100644 include/crypto/dh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index e72c427..162d2f9 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -111,6 +111,14 @@ config CRYPTO_RSA
help
  Generic implementation of the RSA public key algorithm.
 
+config CRYPTO_DH
+   tristate "Diffie-Hellman algorithm"
+   select CRYPTO_KPP
+   select MPILIB
+   help
+ Generic implementation of the Diffie-Hellman algorithm.
+
+
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 07b0f51..8289720 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -32,6 +32,10 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
+dh_generic-y := dh.o
+dh_generic-y += dh_helper.o
+obj-$(CONFIG_CRYPTO_DH) += dh_generic.o
+
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
 clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
diff --git a/crypto/dh.c b/crypto/dh.c
new file mode 100644
index 000..5e960fe
--- /dev/null
+++ b/crypto/dh.c
@@ -0,0 +1,189 @@
+/*  Diffie-Hellman Key Agreement Method [RFC2631]
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+
+struct dh_ctx {
+   MPI p;
+   MPI g;
+   MPI xa;
+};
+
+static inline void dh_clear_params(struct dh_ctx *ctx)
+{
+   mpi_free(ctx->p);
+   mpi_free(ctx->g);
+   ctx->p = NULL;
+   ctx->g = NULL;
+}
+
+static void dh_free_ctx(struct dh_ctx *ctx)
+{
+   dh_clear_params(ctx);
+   mpi_free(ctx->xa);
+   ctx->xa = NULL;
+}
+
+/*
+ * If base is g we compute the public key
+ * ya = g^xa mod p; [RFC2631 sec 2.1.1]
+ * else if base if the counterpart public key we compute the shared secret
+ * ZZ = yb^xa mod p; [RFC2631 sec 2.1.1]
+ */
+static int _compute_val(const struct dh_ctx *ctx, MPI base, MPI val)
+{
+   /* val = base^xa mod p */
+   return mpi_powm(val, base, ctx->xa, ctx->p);
+}
+
+static inline struct dh_ctx *dh_get_ctx(struct crypto_kpp *tfm)
+{
+   return kpp_tfm_ctx(tfm);
+}
+
+static int dh_check_params_length(unsigned int p_len)
+{
+   return (p_len < 1536) ? -EINVAL : 0;
+}
+
+static int dh_set_params(struct dh_ctx *ctx, struct dh *params)
+{
+   if (unlikely(!params->p || !params->g))
+   return -EINVAL;
+
+   if (dh_check_params_length(params->p_size << 3))
+   return -EINVAL;
+
+   ctx->p = mpi_read_raw_data(params->p, params->p_size);
+   if (!ctx->p)
+   return -EINVAL;
+
+   ctx->g = mpi_read_raw_data(params->g, params->g_size);
+   if (!ctx->g) {
+   mpi_free(ctx->p);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int dh_set_secret(struct crypto_kpp *tfm, void *buf, unsigned int len)
+{
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+   struct dh params;
+
+   if (crypto_dh_decode_key(buf, len, ¶ms) < 0)
+   return -EINVAL;
+
+   if (dh_set_params(ctx, ¶ms) < 0)
+   return -EINVAL;
+
+   ctx->xa = mpi_read_raw_data(params.key, params.key_size);
+   if (!ctx->xa) {
+   dh_clear_params(ctx);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int dh_compute_value(struct kpp_request *req)
+{
+   struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+   MPI base, val = mpi_alloc(0);
+   int ret = 0;
+   int sign;
+
+   if (!val)
+   return -ENOMEM;
+
+   if (unlikely(!ctx->xa)) {
+   ret = -EINVAL;
+   goto err_free_val;
+   }
+
+   if (req->src) {
+   base = mpi_read_raw_from_sgl(req->src, req->src_l

[PATCH v10 2/3] crypto: kpp - Add DH software implementation

2016-06-21 Thread Salvatore Benedetto
 * Implement MPI based Diffie-Hellman under kpp API
 * Test provided uses data generad by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig   |   8 ++
 crypto/Makefile  |   4 +
 crypto/dh.c  | 189 ++
 crypto/dh_helper.c   |  95 +++
 crypto/testmgr.c | 201 +
 crypto/testmgr.h | 208 +++
 include/crypto/dh.h  |  29 +++
 include/crypto/kpp.h |   1 +
 8 files changed, 735 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 crypto/dh_helper.c
 create mode 100644 include/crypto/dh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index e72c427..162d2f9 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -111,6 +111,14 @@ config CRYPTO_RSA
help
  Generic implementation of the RSA public key algorithm.
 
+config CRYPTO_DH
+   tristate "Diffie-Hellman algorithm"
+   select CRYPTO_KPP
+   select MPILIB
+   help
+ Generic implementation of the Diffie-Hellman algorithm.
+
+
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 07b0f51..8289720 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -32,6 +32,10 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
+dh_generic-y := dh.o
+dh_generic-y += dh_helper.o
+obj-$(CONFIG_CRYPTO_DH) += dh_generic.o
+
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
 clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
diff --git a/crypto/dh.c b/crypto/dh.c
new file mode 100644
index 000..5e960fe
--- /dev/null
+++ b/crypto/dh.c
@@ -0,0 +1,189 @@
+/*  Diffie-Hellman Key Agreement Method [RFC2631]
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+
+struct dh_ctx {
+   MPI p;
+   MPI g;
+   MPI xa;
+};
+
+static inline void dh_clear_params(struct dh_ctx *ctx)
+{
+   mpi_free(ctx->p);
+   mpi_free(ctx->g);
+   ctx->p = NULL;
+   ctx->g = NULL;
+}
+
+static void dh_free_ctx(struct dh_ctx *ctx)
+{
+   dh_clear_params(ctx);
+   mpi_free(ctx->xa);
+   ctx->xa = NULL;
+}
+
+/*
+ * If base is g we compute the public key
+ * ya = g^xa mod p; [RFC2631 sec 2.1.1]
+ * else if base if the counterpart public key we compute the shared secret
+ * ZZ = yb^xa mod p; [RFC2631 sec 2.1.1]
+ */
+static int _compute_val(const struct dh_ctx *ctx, MPI base, MPI val)
+{
+   /* val = base^xa mod p */
+   return mpi_powm(val, base, ctx->xa, ctx->p);
+}
+
+static inline struct dh_ctx *dh_get_ctx(struct crypto_kpp *tfm)
+{
+   return kpp_tfm_ctx(tfm);
+}
+
+static int dh_check_params_length(unsigned int p_len)
+{
+   return (p_len < 1536) ? -EINVAL : 0;
+}
+
+static int dh_set_params(struct dh_ctx *ctx, struct dh *params)
+{
+   if (unlikely(!params->p || !params->g))
+   return -EINVAL;
+
+   if (dh_check_params_length(params->p_size << 3))
+   return -EINVAL;
+
+   ctx->p = mpi_read_raw_data(params->p, params->p_size);
+   if (!ctx->p)
+   return -EINVAL;
+
+   ctx->g = mpi_read_raw_data(params->g, params->g_size);
+   if (!ctx->g) {
+   mpi_free(ctx->p);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int dh_set_secret(struct crypto_kpp *tfm, void *buf, unsigned int len)
+{
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+   struct dh params;
+
+   if (crypto_dh_decode_key(buf, len, ¶ms) < 0)
+   return -EINVAL;
+
+   if (dh_set_params(ctx, ¶ms) < 0)
+   return -EINVAL;
+
+   ctx->xa = mpi_read_raw_data(params.key, params.key_size);
+   if (!ctx->xa) {
+   dh_clear_params(ctx);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int dh_compute_value(struct kpp_request *req)
+{
+   struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+   MPI base, val = mpi_alloc(0);
+   int ret = 0;
+   int sign;
+
+   if (!val)
+   return -ENOMEM;
+
+   if (unlikely(!ctx->xa)) {
+   ret = -EINVAL;
+   goto err_free_val;
+   }
+
+   if (req->src) {
+   base = mpi_r

[PATCH v10 1/3] crypto: Key-agreement Protocol Primitives API (KPP)

2016-06-21 Thread Salvatore Benedetto
Add key-agreement protocol primitives (kpp) API which allows to
implement primitives required by protocols such as DH and ECDH.
The API is composed mainly by the following functions
 * set_secret() - It allows the user to set his secret, also
   referred to as his private key, along with the parameters
   known to both parties involved in the key-agreement session.
 * generate_public_key() - It generates the public key to be sent to
   the other counterpart involved in the key-agreement session. The
   function has to be called after set_params() and set_secret()
 * generate_secret() - It generates the shared secret for the session

Other functions such as init() and exit() are provided for allowing
cryptographic hardware to be inizialized properly before use

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |  10 ++
 crypto/Makefile |   1 +
 crypto/crypto_user.c|  20 +++
 crypto/kpp.c| 123 +++
 include/crypto/internal/kpp.h   |  64 
 include/crypto/kpp.h| 328 
 include/linux/crypto.h  |   1 +
 include/uapi/linux/cryptouser.h |   5 +
 8 files changed, 552 insertions(+)
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 6881d1a..e72c427 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -93,6 +93,15 @@ config CRYPTO_AKCIPHER
select CRYPTO_AKCIPHER2
select CRYPTO_ALGAPI
 
+config CRYPTO_KPP2
+   tristate
+   select CRYPTO_ALGAPI2
+
+config CRYPTO_KPP
+   tristate
+   select CRYPTO_ALGAPI
+   select CRYPTO_KPP2
+
 config CRYPTO_RSA
tristate "RSA algorithm"
select CRYPTO_AKCIPHER
@@ -115,6 +124,7 @@ config CRYPTO_MANAGER2
select CRYPTO_HASH2
select CRYPTO_BLKCIPHER2
select CRYPTO_AKCIPHER2
+   select CRYPTO_KPP2
 
 config CRYPTO_USER
tristate "Userspace cryptographic algorithm configuration"
diff --git a/crypto/Makefile b/crypto/Makefile
index 0b82c47..07b0f51 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -30,6 +30,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
+obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index f71960d..e7a0a9d 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "internal.h"
 
@@ -126,6 +127,21 @@ nla_put_failure:
return -EMSGSIZE;
 }
 
+static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   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)
 {
@@ -176,6 +192,10 @@ static int crypto_report_one(struct crypto_alg *alg,
goto nla_put_failure;
 
break;
+   case CRYPTO_ALG_TYPE_KPP:
+   if (crypto_report_kpp(skb, alg))
+   goto nla_put_failure;
+   break;
}
 
 out:
diff --git a/crypto/kpp.c b/crypto/kpp.c
new file mode 100644
index 000..d36ce05
--- /dev/null
+++ b/crypto/kpp.c
@@ -0,0 +1,123 @@
+/*
+ * Key-agreement Protocol Primitives (KPP)
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "internal.h"
+
+#ifdef CONFIG_NET
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+static void crypto_kpp_show(struct

[PATCH v10 0/3] Key-agreement Protocol Primitives (KPP) API

2016-06-21 Thread Salvatore Benedetto
Hi Herb,

the following patchset introduces a new API for abstracting key-agreement
protocols such as DH and ECDH. It provides the primitives required for 
implementing
the protocol, thus the name KPP (Key-agreement Protocol Primitives).

Regards,
Salvatore

Changes from v9:
* Fix encoding/decoding of buffer packed with kpp_secret.

Changes from v8:
* set_secret accept a buffer packed and prefixed with a tiny header of
  2 fields: type and len. Each kpp type define its own type and provide
  helper for user (encoder) and drivers (decoder)

Changed from v7:
* API change: merge set_param and set_key to set_key. Params and private
  key are now provided together. Params have always to be provided.
* Merge generate_public_key and compute_shared_secret into compute_val.
  API stay as it is
* Add ecc_is_key_valid to validate private key when set. Now that params
  and key are set together we can validate the key right away. Before the
  check was deferred to generate_public_key.

Changes from v6:
* Remove len parameter from crypto_kpp_set_params. Adjust rest of code
  accordingly
* Remove the while loop in ecdh_make_pub_key as the private key is fixed and
  iterating is pointless. EAGAIN is now to returned to make the user aware
  that he needs to regenerate/reset the private key

Changes from v5:
* Fix ecdh loading in fips mode.

Changes from v4:
* If fips_enabled is set allow only P256 (or higher) as Stephan suggested
* Pass ndigits as argument to ecdh_make_pub_key and ecdh_shared_secret
  so that VLA can be used like in the rest of the module

Changes from v3:
* Move curve ID definition to public header ecdh.h as users need to
  have access to those ids when selecting the curve

Changes from v2:
* Add support for ECDH (curve P192 and P256). I reused the ecc module
  already present in net/bluetooth and extended it in order to select
  different curves at runtime. Code for P192 was taken from tinycrypt.

Changes from v1:
* Change check in dh_check_params_length based on Stephan review

Salvatore Benedetto (3):
  crypto: Key-agreement Protocol Primitives API (KPP)
  crypto: kpp - Add DH software implementation
  crypto: kpp - Add ECDH software support

 crypto/Kconfig  |   23 +
 crypto/Makefile |9 +
 crypto/crypto_user.c|   20 +
 crypto/dh.c |  189 
 crypto/dh_helper.c  |   95 
 crypto/ecc.c| 1018 +++
 crypto/ecc.h|   83 
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  151 ++
 crypto/ecdh_helper.c|   86 
 crypto/kpp.c|  123 +
 crypto/testmgr.c|  354 ++
 crypto/testmgr.h|  286 +++
 include/crypto/dh.h |   29 ++
 include/crypto/ecdh.h   |   30 ++
 include/crypto/internal/kpp.h   |   64 +++
 include/crypto/kpp.h|  330 +
 include/linux/crypto.h  |1 +
 include/uapi/linux/cryptouser.h |5 +
 19 files changed, 2953 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 crypto/dh_helper.c
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 crypto/ecdh_helper.c
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/dh.h
 create mode 100644 include/crypto/ecdh.h
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

-- 
2.7.4

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


[PATCH v10 3/3] crypto: kpp - Add ECDH software support

2016-06-21 Thread Salvatore Benedetto
 * Implement ECDH under kpp API
 * Provide ECC software support for curve P-192 and
   P-256.
 * Add kpp test for ECDH with data generated by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |5 +
 crypto/Makefile |4 +
 crypto/ecc.c| 1018 +++
 crypto/ecc.h|   83 
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  151 +++
 crypto/ecdh_helper.c|   86 
 crypto/testmgr.c|  171 +++-
 crypto/testmgr.h|   78 
 include/crypto/ecdh.h   |   30 ++
 include/crypto/kpp.h|1 +
 11 files changed, 1675 insertions(+), 9 deletions(-)
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 crypto/ecdh_helper.c
 create mode 100644 include/crypto/ecdh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 162d2f9..5baaa9d 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -118,6 +118,11 @@ config CRYPTO_DH
help
  Generic implementation of the Diffie-Hellman algorithm.
 
+config CRYPTO_ECDH
+   tristate "ECDH algorithm"
+   select CRYTPO_KPP
+   help
+ Generic implementation of the ECDH algorithm
 
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
diff --git a/crypto/Makefile b/crypto/Makefile
index 8289720..df1bcfb 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -35,6 +35,10 @@ obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 dh_generic-y := dh.o
 dh_generic-y += dh_helper.o
 obj-$(CONFIG_CRYPTO_DH) += dh_generic.o
+ecdh_generic-y := ecc.o
+ecdh_generic-y += ecdh.o
+ecdh_generic-y += ecdh_helper.o
+obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/ecc.c b/crypto/ecc.c
new file mode 100644
index 000..9aedec6
--- /dev/null
+++ b/crypto/ecc.c
@@ -0,0 +1,1018 @@
+/*
+ * Copyright (c) 2013, Kenneth MacKay
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * 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
+ * HOLDER 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 
+#include 
+#include 
+#include 
+#include 
+
+#include "ecc.h"
+#include "ecc_curve_defs.h"
+
+typedef struct {
+   u64 m_low;
+   u64 m_high;
+} uint128_t;
+
+static inline const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
+{
+   switch (curve_id) {
+   /* In FIPS mode only allow P256 and higher */
+   case ECC_CURVE_NIST_P192:
+   return fips_enabled ? NULL : &nist_p192;
+   case ECC_CURVE_NIST_P256:
+   return &nist_p256;
+   default:
+   return NULL;
+   }
+}
+
+static u64 *ecc_alloc_digits_space(unsigned int ndigits)
+{
+   size_t len = ndigits * sizeof(u64);
+
+   if (!len)
+   return NULL;
+
+   return kmalloc(len, GFP_KERNEL);
+}
+
+static void ecc_free_digits_space(u64 *space)
+{
+   kzfree(space);
+}
+
+static struct ecc_point *ecc_alloc_point(unsigned int ndigits)
+{
+   struct ecc_point *p = kmalloc(sizeof(*p), GFP_KERNEL);
+
+   if (!p)
+   return NULL;
+
+   p->x = ecc_alloc_digits_space(ndigits);
+   if (!p->x)
+   goto err_alloc_x;
+
+   p->y = ecc_alloc_digits_space(ndigits);
+   if (!p->y)
+   goto err_alloc_y;
+
+   p->ndigits = ndigits;
+
+   return p;
+
+err_alloc_y:
+   ecc_free_digits_space(p->x);
+err_alloc_x:
+   kfree(p);
+   return NULL;
+}
+
+static void ecc_free_point(struct ecc_point *p)
+{
+  

[PATCH v9 1/3] crypto: Key-agreement Protocol Primitives API (KPP)

2016-06-17 Thread Salvatore Benedetto
Add key-agreement protocol primitives (kpp) API which allows to
implement primitives required by protocols such as DH and ECDH.
The API is composed mainly by the following functions
 * set_secret() - It allows the user to set his secret, also
   referred to as his private key, along with the parameters
   known to both parties involved in the key-agreement session.
 * generate_public_key() - It generates the public key to be sent to
   the other counterpart involved in the key-agreement session. The
   function has to be called after set_params() and set_secret()
 * generate_secret() - It generates the shared secret for the session

Other functions such as init() and exit() are provided for allowing
cryptographic hardware to be inizialized properly before use

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |  10 ++
 crypto/Makefile |   1 +
 crypto/crypto_user.c|  20 +++
 crypto/kpp.c| 123 +++
 include/crypto/internal/kpp.h   |  64 
 include/crypto/kpp.h| 328 
 include/linux/crypto.h  |   1 +
 include/uapi/linux/cryptouser.h |   5 +
 8 files changed, 552 insertions(+)
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index c903f18..8070678 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -93,6 +93,15 @@ config CRYPTO_AKCIPHER
select CRYPTO_AKCIPHER2
select CRYPTO_ALGAPI
 
+config CRYPTO_KPP2
+   tristate
+   select CRYPTO_ALGAPI2
+
+config CRYPTO_KPP
+   tristate
+   select CRYPTO_ALGAPI
+   select CRYPTO_KPP2
+
 config CRYPTO_RSA
tristate "RSA algorithm"
select CRYPTO_AKCIPHER
@@ -115,6 +124,7 @@ config CRYPTO_MANAGER2
select CRYPTO_HASH2
select CRYPTO_BLKCIPHER2
select CRYPTO_AKCIPHER2
+   select CRYPTO_KPP2
 
 config CRYPTO_USER
tristate "Userspace cryptographic algorithm configuration"
diff --git a/crypto/Makefile b/crypto/Makefile
index 4f4ef7e..5b60890 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -30,6 +30,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
+obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index f71960d..e7a0a9d 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "internal.h"
 
@@ -126,6 +127,21 @@ nla_put_failure:
return -EMSGSIZE;
 }
 
+static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   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)
 {
@@ -176,6 +192,10 @@ static int crypto_report_one(struct crypto_alg *alg,
goto nla_put_failure;
 
break;
+   case CRYPTO_ALG_TYPE_KPP:
+   if (crypto_report_kpp(skb, alg))
+   goto nla_put_failure;
+   break;
}
 
 out:
diff --git a/crypto/kpp.c b/crypto/kpp.c
new file mode 100644
index 000..d36ce05
--- /dev/null
+++ b/crypto/kpp.c
@@ -0,0 +1,123 @@
+/*
+ * Key-agreement Protocol Primitives (KPP)
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "internal.h"
+
+#ifdef CONFIG_NET
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+static void crypto_kpp_show(struct

[PATCH v9 0/3] Key-agreement Protocol Primitives (KPP) API

2016-06-17 Thread Salvatore Benedetto
Hi Herb,

the following patchset introduces a new API for abstracting key-agreement
protocols such as DH and ECDH. It provides the primitives required for 
implementing
the protocol, thus the name KPP (Key-agreement Protocol Primitives).

Regards,
Salvatore

Changes from v8:
* set_secret accept a buffer packed and prefixed with a tiny header of
  2 fields: type and len. Each kpp type define its own type and provide
  helper for user (encoder) and drivers (decoder)

Changed from v7:
* API change: merge set_param and set_key to set_key. Params and private
  key are now provided together. Params have always to be provided.
* Merge generate_public_key and compute_shared_secret into compute_val.
  API stay as it is
* Add ecc_is_key_valid to validate private key when set. Now that params
  and key are set together we can validate the key right away. Before the
  check was deferred to generate_public_key.

Changes from v6:
* Remove len parameter from crypto_kpp_set_params. Adjust rest of code
  accordingly
* Remove the while loop in ecdh_make_pub_key as the private key is fixed and
  iterating is pointless. EAGAIN is now to returned to make the user aware
  that he needs to regenerate/reset the private key

Changes from v5:
* Fix ecdh loading in fips mode.

Changes from v4:
* If fips_enabled is set allow only P256 (or higher) as Stephan suggested
* Pass ndigits as argument to ecdh_make_pub_key and ecdh_shared_secret
  so that VLA can be used like in the rest of the module

Changes from v3:
* Move curve ID definition to public header ecdh.h as users need to
  have access to those ids when selecting the curve

Changes from v2:
* Add support for ECDH (curve P192 and P256). I reused the ecc module
  already present in net/bluetooth and extended it in order to select
  different curves at runtime. Code for P192 was taken from tinycrypt.

Changes from v1:
* Change check in dh_check_params_length based on Stephan review


Salvatore Benedetto (3):
  crypto: Key-agreement Protocol Primitives API (KPP)
  crypto: kpp - Add DH software implementation
  crypto: kpp - Add ECDH software support

 crypto/Kconfig  |   23 +
 crypto/Makefile |9 +
 crypto/crypto_user.c|   20 +
 crypto/dh.c |  189 
 crypto/dh_helper.c  |   84 
 crypto/ecc.c| 1018 +++
 crypto/ecc.h|   83 
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  151 ++
 crypto/ecdh_helper.c|   75 +++
 crypto/kpp.c|  123 +
 crypto/testmgr.c|  362 ++
 crypto/testmgr.h|  286 +++
 include/crypto/dh.h |   29 ++
 include/crypto/ecdh.h   |   30 ++
 include/crypto/internal/kpp.h   |   64 +++
 include/crypto/kpp.h|  330 +
 include/linux/crypto.h  |1 +
 include/uapi/linux/cryptouser.h |5 +
 19 files changed, 2939 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 crypto/dh_helper.c
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 crypto/ecdh_helper.c
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/dh.h
 create mode 100644 include/crypto/ecdh.h
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

-- 
2.7.4

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


[PATCH v9 3/3] crypto: kpp - Add ECDH software support

2016-06-17 Thread Salvatore Benedetto
 * Implement ECDH under kpp API
 * Provide ECC software support for curve P-192 and
   P-256.
 * Add kpp test for ECDH with data generated by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |5 +
 crypto/Makefile |4 +
 crypto/ecc.c| 1018 +++
 crypto/ecc.h|   83 
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  151 +++
 crypto/ecdh_helper.c|   75 
 crypto/testmgr.c|  176 +++-
 crypto/testmgr.h|   78 
 include/crypto/ecdh.h   |   30 ++
 include/crypto/kpp.h|1 +
 11 files changed, 1669 insertions(+), 9 deletions(-)
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 crypto/ecdh_helper.c
 create mode 100644 include/crypto/ecdh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 92b5f0b..d0492ae 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -118,6 +118,11 @@ config CRYPTO_DH
help
  Generic implementation of the Diffie-Hellman algorithm.
 
+config CRYPTO_ECDH
+   tristate "ECDH algorithm"
+   select CRYTPO_KPP
+   help
+ Generic implementation of the ECDH algorithm
 
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
diff --git a/crypto/Makefile b/crypto/Makefile
index 28e8708..47b1fae 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -35,6 +35,10 @@ obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 dh_generic-y := dh.o
 dh_generic-y += dh_helper.o
 obj-$(CONFIG_CRYPTO_DH) += dh_generic.o
+ecdh_generic-y := ecc.o
+ecdh_generic-y += ecdh.o
+ecdh_generic-y += ecdh_helper.o
+obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/ecc.c b/crypto/ecc.c
new file mode 100644
index 000..9aedec6
--- /dev/null
+++ b/crypto/ecc.c
@@ -0,0 +1,1018 @@
+/*
+ * Copyright (c) 2013, Kenneth MacKay
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * 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
+ * HOLDER 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 
+#include 
+#include 
+#include 
+#include 
+
+#include "ecc.h"
+#include "ecc_curve_defs.h"
+
+typedef struct {
+   u64 m_low;
+   u64 m_high;
+} uint128_t;
+
+static inline const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
+{
+   switch (curve_id) {
+   /* In FIPS mode only allow P256 and higher */
+   case ECC_CURVE_NIST_P192:
+   return fips_enabled ? NULL : &nist_p192;
+   case ECC_CURVE_NIST_P256:
+   return &nist_p256;
+   default:
+   return NULL;
+   }
+}
+
+static u64 *ecc_alloc_digits_space(unsigned int ndigits)
+{
+   size_t len = ndigits * sizeof(u64);
+
+   if (!len)
+   return NULL;
+
+   return kmalloc(len, GFP_KERNEL);
+}
+
+static void ecc_free_digits_space(u64 *space)
+{
+   kzfree(space);
+}
+
+static struct ecc_point *ecc_alloc_point(unsigned int ndigits)
+{
+   struct ecc_point *p = kmalloc(sizeof(*p), GFP_KERNEL);
+
+   if (!p)
+   return NULL;
+
+   p->x = ecc_alloc_digits_space(ndigits);
+   if (!p->x)
+   goto err_alloc_x;
+
+   p->y = ecc_alloc_digits_space(ndigits);
+   if (!p->y)
+   goto err_alloc_y;
+
+   p->ndigits = ndigits;
+
+   return p;
+
+err_alloc_y:
+   ecc_free_digits_space(p->x);
+err_alloc_x:
+   kfree(p);
+   return NULL;
+}
+
+static void ecc_free_point(struct ecc_point *p)
+{
+  

[PATCH v9 2/3] crypto: kpp - Add DH software implementation

2016-06-17 Thread Salvatore Benedetto
 * Implement MPI based Diffie-Hellman under kpp API
 * Test provided uses data generad by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig   |   8 ++
 crypto/Makefile  |   4 +
 crypto/dh.c  | 189 ++
 crypto/dh_helper.c   |  84 +
 crypto/testmgr.c | 204 ++
 crypto/testmgr.h | 208 +++
 include/crypto/dh.h  |  29 +++
 include/crypto/kpp.h |   1 +
 8 files changed, 727 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 crypto/dh_helper.c
 create mode 100644 include/crypto/dh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 8070678..92b5f0b 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -111,6 +111,14 @@ config CRYPTO_RSA
help
  Generic implementation of the RSA public key algorithm.
 
+config CRYPTO_DH
+   tristate "Diffie-Hellman algorithm"
+   select CRYPTO_KPP
+   select MPILIB
+   help
+ Generic implementation of the Diffie-Hellman algorithm.
+
+
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 5b60890..28e8708 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -32,6 +32,10 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
+dh_generic-y := dh.o
+dh_generic-y += dh_helper.o
+obj-$(CONFIG_CRYPTO_DH) += dh_generic.o
+
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
 clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
diff --git a/crypto/dh.c b/crypto/dh.c
new file mode 100644
index 000..d060b11
--- /dev/null
+++ b/crypto/dh.c
@@ -0,0 +1,189 @@
+/*  Diffie-Hellman Key Agreement Method [RFC2631]
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+
+struct dh_ctx {
+   MPI p;
+   MPI g;
+   MPI xa;
+};
+
+static inline void dh_clear_params(struct dh_ctx *ctx)
+{
+   mpi_free(ctx->p);
+   mpi_free(ctx->g);
+   ctx->p = NULL;
+   ctx->g = NULL;
+}
+
+static void dh_free_ctx(struct dh_ctx *ctx)
+{
+   dh_clear_params(ctx);
+   mpi_free(ctx->xa);
+   ctx->xa = NULL;
+}
+
+/*
+ * If base is g we compute the public key
+ * ya = g^xa mod p; [RFC2631 sec 2.1.1]
+ * else if base if the counterpart public key we compute the shared secret
+ * ZZ = yb^xa mod p; [RFC2631 sec 2.1.1]
+ */
+static int _compute_val(const struct dh_ctx *ctx, MPI base, MPI val)
+{
+   /* val = base^xa mod p */
+   return mpi_powm(val, base, ctx->xa, ctx->p);
+}
+
+static inline struct dh_ctx *dh_get_ctx(struct crypto_kpp *tfm)
+{
+   return kpp_tfm_ctx(tfm);
+}
+
+static int dh_check_params_length(unsigned int p_len)
+{
+   return (p_len < 1536) ? -EINVAL : 0;
+}
+
+static int dh_set_params(struct dh_ctx *ctx, struct dh *params)
+{
+   if (unlikely(!params->p || !params->g))
+   return -EINVAL;
+
+   if (dh_check_params_length(params->p_size << 3))
+   return -EINVAL;
+
+   ctx->p = mpi_read_raw_data(params->p, params->p_size);
+   if (!ctx->p)
+   return -EINVAL;
+
+   ctx->g = mpi_read_raw_data(params->g, params->g_size);
+   if (!ctx->g) {
+   mpi_free(ctx->p);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int dh_set_secret(struct crypto_kpp *tfm, void *buf, unsigned int len)
+{
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+   struct dh *params = NULL;
+
+   if (crypto_dh_decode_key(buf, len, ¶ms) < 0)
+   return -EINVAL;
+
+   if (dh_set_params(ctx, params) < 0)
+   return -EINVAL;
+
+   ctx->xa = mpi_read_raw_data(params->key, params->key_size);
+   if (!ctx->xa) {
+   dh_clear_params(ctx);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int dh_compute_value(struct kpp_request *req)
+{
+   struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+   MPI base, val = mpi_alloc(0);
+   int ret = 0;
+   int sign;
+
+   if (!val)
+   return -ENOMEM;
+
+   if (unlikely(!ctx->xa)) {
+   ret = -EINVAL;
+   goto err_free_val;
+   }
+
+   if (req->src) {
+   base =

[PATCH v8 3/3] crypto: kpp - Add ECDH software support

2016-06-13 Thread Salvatore Benedetto
 * Implement ECDH under kpp API
 * Provide ECC software support for curve P-192 and
   P-256.
 * Add kpp test for ECDH with data generated by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |5 +
 crypto/Makefile |3 +
 crypto/ecc.c| 1018 +++
 crypto/ecc.h|   83 
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  151 +++
 crypto/testmgr.c|  135 ++-
 crypto/testmgr.h|   78 
 include/crypto/ecdh.h   |   26 ++
 9 files changed, 1547 insertions(+), 9 deletions(-)
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 include/crypto/ecdh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 4190e0d..5533c69 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -118,6 +118,11 @@ config CRYPTO_DH
help
  Generic implementation of the Diffie-Hellman algorithm.
 
+config CRYPTO_ECDH
+   tristate "ECDH algorithm"
+   select CRYTPO_KPP
+   help
+ Generic implementation of the ECDH algorithm
 
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
diff --git a/crypto/Makefile b/crypto/Makefile
index 101f8fd..ba03079 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -33,6 +33,9 @@ obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
 obj-$(CONFIG_CRYPTO_DH) += dh.o
+ecdh_generic-y := ecc.o
+ecdh_generic-y += ecdh.o
+obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/ecc.c b/crypto/ecc.c
new file mode 100644
index 000..9aedec6
--- /dev/null
+++ b/crypto/ecc.c
@@ -0,0 +1,1018 @@
+/*
+ * Copyright (c) 2013, Kenneth MacKay
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * 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
+ * HOLDER 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 
+#include 
+#include 
+#include 
+#include 
+
+#include "ecc.h"
+#include "ecc_curve_defs.h"
+
+typedef struct {
+   u64 m_low;
+   u64 m_high;
+} uint128_t;
+
+static inline const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
+{
+   switch (curve_id) {
+   /* In FIPS mode only allow P256 and higher */
+   case ECC_CURVE_NIST_P192:
+   return fips_enabled ? NULL : &nist_p192;
+   case ECC_CURVE_NIST_P256:
+   return &nist_p256;
+   default:
+   return NULL;
+   }
+}
+
+static u64 *ecc_alloc_digits_space(unsigned int ndigits)
+{
+   size_t len = ndigits * sizeof(u64);
+
+   if (!len)
+   return NULL;
+
+   return kmalloc(len, GFP_KERNEL);
+}
+
+static void ecc_free_digits_space(u64 *space)
+{
+   kzfree(space);
+}
+
+static struct ecc_point *ecc_alloc_point(unsigned int ndigits)
+{
+   struct ecc_point *p = kmalloc(sizeof(*p), GFP_KERNEL);
+
+   if (!p)
+   return NULL;
+
+   p->x = ecc_alloc_digits_space(ndigits);
+   if (!p->x)
+   goto err_alloc_x;
+
+   p->y = ecc_alloc_digits_space(ndigits);
+   if (!p->y)
+   goto err_alloc_y;
+
+   p->ndigits = ndigits;
+
+   return p;
+
+err_alloc_y:
+   ecc_free_digits_space(p->x);
+err_alloc_x:
+   kfree(p);
+   return NULL;
+}
+
+static void ecc_free_point(struct ecc_point *p)
+{
+   if (!p)
+   return;
+
+   kzfree(p->x);
+   kzfree(p->y);
+   kzfree(p);
+}
+
+static void vli_clear(u64 *vli, unsigned int ndigits)
+{

[PATCH v8 2/3] crypto: kpp - Add DH software implementation

2016-06-13 Thread Salvatore Benedetto
 * Implement MPI based Diffie-Hellman under kpp API
 * Test provided uses data generad by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |   8 ++
 crypto/Makefile |   2 +
 crypto/dh.c | 189 +++
 crypto/testmgr.c| 157 +++
 crypto/testmgr.h| 208 
 include/crypto/dh.h |  25 +++
 6 files changed, 589 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 include/crypto/dh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 0bd6d7f..4190e0d 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -111,6 +111,14 @@ config CRYPTO_RSA
help
  Generic implementation of the RSA public key algorithm.
 
+config CRYPTO_DH
+   tristate "Diffie-Hellman algorithm"
+   select CRYPTO_KPP
+   select MPILIB
+   help
+ Generic implementation of the Diffie-Hellman algorithm.
+
+
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 5b60890..101f8fd 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -32,6 +32,8 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
+obj-$(CONFIG_CRYPTO_DH) += dh.o
+
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
 clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
diff --git a/crypto/dh.c b/crypto/dh.c
new file mode 100644
index 000..7d29056
--- /dev/null
+++ b/crypto/dh.c
@@ -0,0 +1,189 @@
+/*  Diffie-Hellman Key Agreement Method [RFC2631]
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+
+struct dh_ctx {
+   MPI p;
+   MPI g;
+   MPI xa;
+};
+
+static inline void dh_clear_params(struct dh_ctx *ctx)
+{
+   mpi_free(ctx->p);
+   mpi_free(ctx->g);
+   ctx->p = NULL;
+   ctx->g = NULL;
+}
+
+static void dh_free_ctx(struct dh_ctx *ctx)
+{
+   dh_clear_params(ctx);
+   mpi_free(ctx->xa);
+   ctx->xa = NULL;
+}
+
+/*
+ * If base is g we compute the public key
+ * ya = g^xa mod p; [RFC2631 sec 2.1.1]
+ * else if base if the counterpart public key we compute the shared secret
+ * ZZ = yb^xa mod p; [RFC2631 sec 2.1.1]
+ */
+static int _compute_val(const struct dh_ctx *ctx, MPI base, MPI val)
+{
+   /* val = base^xa mod p */
+   return mpi_powm(val, base, ctx->xa, ctx->p);
+}
+
+static inline struct dh_ctx *dh_get_ctx(struct crypto_kpp *tfm)
+{
+   return kpp_tfm_ctx(tfm);
+}
+
+static int dh_check_params_length(unsigned int p_len)
+{
+   return (p_len < 1536) ? -EINVAL : 0;
+}
+
+static int dh_set_params(struct dh_ctx *ctx, struct dh *params)
+{
+   if (unlikely(!params->p || !params->g))
+   return -EINVAL;
+
+   if (dh_check_params_length(params->p_size << 3))
+   return -EINVAL;
+
+   ctx->p = mpi_read_raw_data(params->p, params->p_size);
+   if (!ctx->p)
+   return -EINVAL;
+
+   ctx->g = mpi_read_raw_data(params->g, params->g_size);
+   if (!ctx->g) {
+   mpi_free(ctx->p);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int dh_set_secret(struct crypto_kpp *tfm, void *buffer)
+{
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+   struct dh *params = (struct dh *)buffer;
+
+   if (unlikely(!buffer))
+   return -EINVAL;
+
+   if (dh_set_params(ctx, params) < 0)
+   return -EINVAL;
+
+   ctx->xa = mpi_read_raw_data(params->key, params->key_size);
+   if (!ctx->xa) {
+   dh_clear_params(ctx);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int dh_compute_value(struct kpp_request *req)
+{
+   struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+   MPI base, val = mpi_alloc(0);
+   int ret = 0;
+   int sign;
+
+   if (!val)
+   return -ENOMEM;
+
+   if (unlikely(!ctx->xa)) {
+   ret = -EINVAL;
+   goto err_free_val;
+   }
+
+   if (req->src) {
+   base = mpi_read_raw_from_sgl(req->src, req->src_len);
+   if (!base) {
+   ret = EINVAL;
+   goto err_free_val;
+   }
+   } else {
+   base = ctx->g;
+  

[PATCH v8 1/3] crypto: Key-agreement Protocol Primitives API (KPP)

2016-06-13 Thread Salvatore Benedetto
Add key-agreement protocol primitives (kpp) API which allows to
implement primitives required by protocols such as DH and ECDH.
The API is composed mainly by the following functions
 * set_secret() - It allows the user to set his secret, also
   referred to as his private key, along with the parameters
   known to both parties involved in the key-agreement session.
 * generate_public_key() - It generates the public key to be sent to
   the other counterpart involved in the key-agreement session. The
   function has to be called after set_params() and set_secret()
 * generate_secret() - It generates the shared secret for the session

Other functions such as init() and exit() are provided for allowing
cryptographic hardware to be inizialized properly before use

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |  10 ++
 crypto/Makefile |   1 +
 crypto/crypto_user.c|  20 +++
 crypto/kpp.c| 123 
 include/crypto/internal/kpp.h   |  64 +
 include/crypto/kpp.h| 310 
 include/linux/crypto.h  |   1 +
 include/uapi/linux/cryptouser.h |   5 +
 8 files changed, 534 insertions(+)
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 1d33beb..0bd6d7f 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -93,6 +93,15 @@ config CRYPTO_AKCIPHER
select CRYPTO_AKCIPHER2
select CRYPTO_ALGAPI
 
+config CRYPTO_KPP2
+   tristate
+   select CRYPTO_ALGAPI2
+
+config CRYPTO_KPP
+   tristate
+   select CRYPTO_ALGAPI
+   select CRYPTO_KPP2
+
 config CRYPTO_RSA
tristate "RSA algorithm"
select CRYPTO_AKCIPHER
@@ -115,6 +124,7 @@ config CRYPTO_MANAGER2
select CRYPTO_HASH2
select CRYPTO_BLKCIPHER2
select CRYPTO_AKCIPHER2
+   select CRYPTO_KPP2
 
 config CRYPTO_USER
tristate "Userspace cryptographic algorithm configuration"
diff --git a/crypto/Makefile b/crypto/Makefile
index 4f4ef7e..5b60890 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -30,6 +30,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
+obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index f71960d..e7a0a9d 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "internal.h"
 
@@ -126,6 +127,21 @@ nla_put_failure:
return -EMSGSIZE;
 }
 
+static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   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)
 {
@@ -176,6 +192,10 @@ static int crypto_report_one(struct crypto_alg *alg,
goto nla_put_failure;
 
break;
+   case CRYPTO_ALG_TYPE_KPP:
+   if (crypto_report_kpp(skb, alg))
+   goto nla_put_failure;
+   break;
}
 
 out:
diff --git a/crypto/kpp.c b/crypto/kpp.c
new file mode 100644
index 000..d36ce05
--- /dev/null
+++ b/crypto/kpp.c
@@ -0,0 +1,123 @@
+/*
+ * Key-agreement Protocol Primitives (KPP)
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "internal.h"
+
+#ifdef CONFIG_NET
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+static void crypto_kpp_show(struct

[PATCH v8 0/3] Key-agreement Protocol Primitives (KPP) API

2016-06-13 Thread Salvatore Benedetto
Hi Herb,

the following patchset introduces a new API for abstracting key-agreement
protocols such as DH and ECDH. It provides the primitives required for 
implementing
the protocol, thus the name KPP (Key-agreement Protocol Primitives).

Regards,
Salvatore

Changed from v7:
* API change: merge set_param and set_key to set_key. Params and private
  key are now provided together. Params have always to be provided.
* Merge generate_public_key and compute_shared_secret into compute_val.
  API stay as it is
* Add ecc_is_key_valid to validate private key when set. Now that params
  and key are set together we can validate the key right away. Before the
  check was deferred to generate_public_key.

Changes from v6:
* Remove len parameter from crypto_kpp_set_params. Adjust rest of code
  accordingly
* Remove the while loop in ecdh_make_pub_key as the private key is fixed and
  iterating is pointless. EAGAIN is now to returned to make the user aware
  that he needs to regenerate/reset the private key

Changes from v5:
* Fix ecdh loading in fips mode.

Changes from v4:
* If fips_enabled is set allow only P256 (or higher) as Stephan suggested
* Pass ndigits as argument to ecdh_make_pub_key and ecdh_shared_secret
  so that VLA can be used like in the rest of the module

Changes from v3:
* Move curve ID definition to public header ecdh.h as users need to
  have access to those ids when selecting the curve

Changes from v2:
* Add support for ECDH (curve P192 and P256). I reused the ecc module
  already present in net/bluetooth and extended it in order to select
  different curves at runtime. Code for P192 was taken from tinycrypt.

Changes from v1:
* Change check in dh_check_params_length based on Stephan review


Salvatore Benedetto (3):
  crypto: Key-agreement Protocol Primitives API (KPP)
  crypto: kpp - Add DH software implementation
  crypto: kpp - Add ECDH software support

 crypto/Kconfig  |   23 +
 crypto/Makefile |6 +
 crypto/crypto_user.c|   20 +
 crypto/dh.c |  189 
 crypto/ecc.c| 1022 +++
 crypto/ecc.h|   83 
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  151 ++
 crypto/kpp.c|  123 +
 crypto/testmgr.c|  274 +++
 crypto/testmgr.h|  286 +++
 include/crypto/dh.h |   25 +
 include/crypto/ecdh.h   |   26 +
 include/crypto/internal/kpp.h   |   64 +++
 include/crypto/kpp.h|  310 
 include/linux/crypto.h  |1 +
 include/uapi/linux/cryptouser.h |5 +
 17 files changed, 2665 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/dh.h
 create mode 100644 include/crypto/ecdh.h
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

-- 
2.7.4

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


Re: [PATCH v5 1/3] crypto: Key-agreement Protocol Primitives API (KPP)

2016-06-08 Thread Salvatore Benedetto
On Wed, Jun 08, 2016 at 10:54:51AM +0800, Herbert Xu wrote:
> On Thu, Jun 02, 2016 at 12:06:48PM +, Benedetto, Salvatore wrote:
> >
> > Off the top of my head, with ECDH when the user gets a EGAIN, he wants
> > to reset the secret key only, not the params.
> 
> I don't see any performance benefit in changing one and not the
> other.  Besides, you could always check the params in the algo
> and only update if necessary.
>

I'm OK with merging set_params and set_key and allow the user to
pass either both, or only the key in which case params previously
set are reused, although I don't see any particular benefit with this.

> > > >  * generate_public_key() - It generates the public key to be sent to
> > > >the other counterpart involved in the key-agreement session. The
> > > >function has to be called after set_params() and set_secret()
> > > >  * generate_secret() - It generates the shared secret for the session
> > > 
> > > Ditto, we only need one operation and that is multiplication by the 
> > > secret.
> > 
> > Sorry, but I don't understand your point.
> > We do always need one math operation with different params.
> 
> Look at your actual implementations of DH and ECDH, they are the
> same except for the multiplicand, which is fixed to G for the
> public key.
> 
> Now you could argue that having to reparse G every time could be
> bad for performance, but that's easily fixed by making the case
> of a zero-length input value an implicit request to use G.
> 
> Even better, just drop G from the params and you won't need to
> reparse it or do anything special.
> 
> The point of all this is to make the lives of future driver authors
> simpler, the less they have to do the less that could go wrong.

I really would like to keep the interface as it is because it's
very clear what each function does. I'm OK with remapping both
function to the same one, and if src is zero, g/G will be used.

Keep in mind that while for DH g is always provided by the user,
for ECDH G is a public value which we already have and I don't see
why the user should pass that.

Having said that, are you OK with as far as the interface goes
to only merge set_param and set_key, and keeping the rest as it is?
For the implementation of DH and ECDH I'll merge the two operations
functions into one as you suggested. If so, I'll send a new version.

Thanks for your inputs.

Regards,
Salvatore

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


[PATCH v4] Bluetooth: convert smp and selftest to crypto kpp API

2016-06-01 Thread Salvatore Benedetto
 * Convert both smp and selftest to crypto kpp API
 * Remove module ecc as not more required
 * Add ecdh_helper functions for wrapping kpp async calls

Signed-off-by: Salvatore Benedetto 
---

Patch based on https://patchwork.kernel.org/patch/9145037/

Changes from v3:
 * Patch adjusted to minor API change. crypto_kpp_set_params no longer
   takes len as input parameter

Changes from v2:
 * Remove header guard in internal header
 * Shorter name for ecdh wrappers and fix 80chars issue
 * Add CRYPTO_ECDH dependency in bluetooth Kconfig

Changes from v1:
 * Convert ecc_make_key to kpp API


 net/bluetooth/Kconfig   |   1 +
 net/bluetooth/Makefile  |   2 +-
 net/bluetooth/ecc.c | 816 
 net/bluetooth/ecc.h |  54 ---
 net/bluetooth/ecdh_helper.c | 204 +++
 net/bluetooth/ecdh_helper.h |  27 ++
 net/bluetooth/selftest.c|   6 +-
 net/bluetooth/smp.c |   8 +-
 8 files changed, 240 insertions(+), 878 deletions(-)
 delete mode 100644 net/bluetooth/ecc.c
 delete mode 100644 net/bluetooth/ecc.h
 create mode 100644 net/bluetooth/ecdh_helper.c
 create mode 100644 net/bluetooth/ecdh_helper.h

diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
index 06c31b9..68f951b 100644
--- a/net/bluetooth/Kconfig
+++ b/net/bluetooth/Kconfig
@@ -13,6 +13,7 @@ menuconfig BT
select CRYPTO_CMAC
select CRYPTO_ECB
select CRYPTO_SHA256
+   select CRYPTO_ECDH
help
  Bluetooth is low-cost, low-power, short-range wireless technology.
  It was designed as a replacement for cables and other short-range
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index b3ff12e..c54d790 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -13,7 +13,7 @@ bluetooth_6lowpan-y := 6lowpan.o
 
 bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \
hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o lib.o \
-   ecc.o hci_request.o mgmt_util.o
+   ecdh_helper.o hci_request.o mgmt_util.o
 
 bluetooth-$(CONFIG_BT_BREDR) += sco.o
 bluetooth-$(CONFIG_BT_HS) += a2mp.o amp.o
diff --git a/net/bluetooth/ecc.c b/net/bluetooth/ecc.c
deleted file mode 100644
index e1709f8..000
--- a/net/bluetooth/ecc.c
+++ /dev/null
@@ -1,816 +0,0 @@
-/*
- * Copyright (c) 2013, Kenneth MacKay
- * All rights reserved.
- *
- * 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.
- *
- * 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
- * HOLDER 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 
-
-#include "ecc.h"
-
-/* 256-bit curve */
-#define ECC_BYTES 32
-
-#define MAX_TRIES 16
-
-/* Number of u64's needed */
-#define NUM_ECC_DIGITS (ECC_BYTES / 8)
-
-struct ecc_point {
-   u64 x[NUM_ECC_DIGITS];
-   u64 y[NUM_ECC_DIGITS];
-};
-
-typedef struct {
-   u64 m_low;
-   u64 m_high;
-} uint128_t;
-
-#define CURVE_P_32 {   0xull, 0xull, \
-   0xull, 0x0001ull }
-
-#define CURVE_G_32 { \
-   {   0xF4A13945D898C296ull, 0x77037D812DEB33A0ull,   \
-   0xF8BCE6E563A440F2ull, 0x6B17D1F2E12C4247ull }, \
-   {   0xCBB6406837BF51F5ull, 0x2BCE33576B315ECEull,   \
-   0x8EE7EB4A7C0F9E16ull, 0x4FE342E2FE1A7F9Bull }  \
-}
-
-#define CURVE_N_32 {   0xF3B9CAC2FC632551ull, 0xBCE6FAADA7179E84ull,   \
-   0xull, 0xull }
-
-static u64 curve_p[NUM_ECC_DIGITS] = CURVE_P_32;
-static struct ecc_point curve_g = CURVE_G_32;
-static u64 curve_n[NUM_ECC_DIGITS] = CURVE_N_32;
-
-static void vli_clear(u64 *vli)
-{
-   int i;
-
-   for (i = 0; i < NUM_ECC_DIGITS; i++)
-   vli[i] = 0;
-}
-
-/* Returns true 

[PATCH v7 1/3] crypto: Key-agreement Protocol Primitives API (KPP)

2016-05-31 Thread Salvatore Benedetto
Add key-agreement protocol primitives (kpp) API which allows to
implement primitives required by protocols such as DH and ECDH.
The API is composed mainly by the following functions
 * set_params() - It allows the user to set the parameters known to
   both parties involved in the key-agreement session
 * set_secret() - It allows the user to set his secret, also
   referred to as his private key
 * generate_public_key() - It generates the public key to be sent to
   the other counterpart involved in the key-agreement session. The
   function has to be called after set_params() and set_secret()
 * generate_secret() - It generates the shared secret for the session

Other functions such as init() and exit() are provided for allowing
cryptographic hardware to be inizialized properly before use

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |  10 ++
 crypto/Makefile |   1 +
 crypto/crypto_user.c|  20 +++
 crypto/kpp.c| 123 +++
 include/crypto/internal/kpp.h   |  64 
 include/crypto/kpp.h| 331 
 include/linux/crypto.h  |   1 +
 include/uapi/linux/cryptouser.h |   5 +
 8 files changed, 555 insertions(+)
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 1d33beb..0bd6d7f 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -93,6 +93,15 @@ config CRYPTO_AKCIPHER
select CRYPTO_AKCIPHER2
select CRYPTO_ALGAPI
 
+config CRYPTO_KPP2
+   tristate
+   select CRYPTO_ALGAPI2
+
+config CRYPTO_KPP
+   tristate
+   select CRYPTO_ALGAPI
+   select CRYPTO_KPP2
+
 config CRYPTO_RSA
tristate "RSA algorithm"
select CRYPTO_AKCIPHER
@@ -115,6 +124,7 @@ config CRYPTO_MANAGER2
select CRYPTO_HASH2
select CRYPTO_BLKCIPHER2
select CRYPTO_AKCIPHER2
+   select CRYPTO_KPP2
 
 config CRYPTO_USER
tristate "Userspace cryptographic algorithm configuration"
diff --git a/crypto/Makefile b/crypto/Makefile
index 4f4ef7e..5b60890 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -30,6 +30,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
+obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index f71960d..e7a0a9d 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "internal.h"
 
@@ -126,6 +127,21 @@ nla_put_failure:
return -EMSGSIZE;
 }
 
+static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   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)
 {
@@ -176,6 +192,10 @@ static int crypto_report_one(struct crypto_alg *alg,
goto nla_put_failure;
 
break;
+   case CRYPTO_ALG_TYPE_KPP:
+   if (crypto_report_kpp(skb, alg))
+   goto nla_put_failure;
+   break;
}
 
 out:
diff --git a/crypto/kpp.c b/crypto/kpp.c
new file mode 100644
index 000..d36ce05
--- /dev/null
+++ b/crypto/kpp.c
@@ -0,0 +1,123 @@
+/*
+ * Key-agreement Protocol Primitives (KPP)
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "internal.h"
+
+#ifdef CONFIG_NET
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+st

[PATCH v7 3/3] crypto: kpp - Add ECDH software support

2016-05-31 Thread Salvatore Benedetto
 * Implement ECDH under kpp API
 * Provide ECC software support for curve P-192 and
   P-256.
 * Add kpp test for ECDH with data generated by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |5 +
 crypto/Makefile |3 +
 crypto/ecc.c| 1011 +++
 crypto/ecc.h|   70 
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  170 
 crypto/testmgr.c|  136 ++-
 crypto/testmgr.h|   78 
 include/crypto/ecdh.h   |   24 ++
 9 files changed, 1545 insertions(+), 9 deletions(-)
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 include/crypto/ecdh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 4190e0d..5533c69 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -118,6 +118,11 @@ config CRYPTO_DH
help
  Generic implementation of the Diffie-Hellman algorithm.
 
+config CRYPTO_ECDH
+   tristate "ECDH algorithm"
+   select CRYTPO_KPP
+   help
+ Generic implementation of the ECDH algorithm
 
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
diff --git a/crypto/Makefile b/crypto/Makefile
index 101f8fd..ba03079 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -33,6 +33,9 @@ obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
 obj-$(CONFIG_CRYPTO_DH) += dh.o
+ecdh_generic-y := ecc.o
+ecdh_generic-y += ecdh.o
+obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/ecc.c b/crypto/ecc.c
new file mode 100644
index 000..ca2febf
--- /dev/null
+++ b/crypto/ecc.c
@@ -0,0 +1,1011 @@
+/*
+ * Copyright (c) 2013, Kenneth MacKay
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * 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
+ * HOLDER 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 
+#include 
+#include 
+#include 
+#include 
+
+#include "ecc.h"
+#include "ecc_curve_defs.h"
+
+typedef struct {
+   u64 m_low;
+   u64 m_high;
+} uint128_t;
+
+static inline const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
+{
+   switch (curve_id) {
+   /* In FIPS mode only allow P256 and higher */
+   case ECC_CURVE_NIST_P192:
+   return fips_enabled ? NULL : &nist_p192;
+   case ECC_CURVE_NIST_P256:
+   return &nist_p256;
+   default:
+   return NULL;
+   }
+}
+
+static u64 *ecc_alloc_digits_space(unsigned int ndigits)
+{
+   size_t len = ndigits * sizeof(u64);
+
+   if (!len)
+   return NULL;
+
+   return kmalloc(len, GFP_KERNEL);
+}
+
+static void ecc_free_digits_space(u64 *space)
+{
+   kzfree(space);
+}
+
+static struct ecc_point *ecc_alloc_point(unsigned int ndigits)
+{
+   struct ecc_point *p = kmalloc(sizeof(*p), GFP_KERNEL);
+
+   if (!p)
+   return NULL;
+
+   p->x = ecc_alloc_digits_space(ndigits);
+   if (!p->x)
+   goto err_alloc_x;
+
+   p->y = ecc_alloc_digits_space(ndigits);
+   if (!p->y)
+   goto err_alloc_y;
+
+   p->ndigits = ndigits;
+
+   return p;
+
+err_alloc_y:
+   ecc_free_digits_space(p->x);
+err_alloc_x:
+   kfree(p);
+   return NULL;
+}
+
+static void ecc_free_point(struct ecc_point *p)
+{
+   if (!p)
+   return;
+
+   kzfree(p->x);
+   kzfree(p->y);
+   kzfree(p);
+}
+
+static void vli_clear(u64 *vli, unsigned int ndigits)
+{

[PATCH v7 2/3] crypto: kpp - Add DH software implementation

2016-05-31 Thread Salvatore Benedetto
 * Implement MPI based Diffie-Hellman under kpp API
 * Test provided uses data generad by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |   8 ++
 crypto/Makefile |   2 +
 crypto/dh.c | 223 
 crypto/testmgr.c| 157 
 crypto/testmgr.h| 208 
 include/crypto/dh.h |  23 ++
 6 files changed, 621 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 include/crypto/dh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 0bd6d7f..4190e0d 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -111,6 +111,14 @@ config CRYPTO_RSA
help
  Generic implementation of the RSA public key algorithm.
 
+config CRYPTO_DH
+   tristate "Diffie-Hellman algorithm"
+   select CRYPTO_KPP
+   select MPILIB
+   help
+ Generic implementation of the Diffie-Hellman algorithm.
+
+
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 5b60890..101f8fd 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -32,6 +32,8 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
+obj-$(CONFIG_CRYPTO_DH) += dh.o
+
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
 clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
diff --git a/crypto/dh.c b/crypto/dh.c
new file mode 100644
index 000..8a13d3b
--- /dev/null
+++ b/crypto/dh.c
@@ -0,0 +1,223 @@
+/*  Diffie-Hellman Key Agreement Method [RFC2631]
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+
+struct dh_ctx {
+   MPI p;
+   MPI g;
+   MPI xa;
+};
+
+static void dh_free_ctx(struct dh_ctx *ctx)
+{
+   mpi_free(ctx->p);
+   mpi_free(ctx->g);
+   mpi_free(ctx->xa);
+   ctx->p = NULL;
+   ctx->g = NULL;
+   ctx->xa = NULL;
+}
+
+/*
+ * Public key generation function [RFC2631 sec 2.1.1]
+ * ya = g^xa mod p;
+ */
+static int _generate_public_key(const struct dh_ctx *ctx, MPI ya)
+{
+   /* ya = g^xa mod p */
+   return mpi_powm(ya, ctx->g, ctx->xa, ctx->p);
+}
+
+/*
+ * ZZ generation function [RFC2631 sec 2.1.1]
+ * ZZ = yb^xa mod p;
+ */
+static int _compute_shared_secret(const struct dh_ctx *ctx, MPI yb,
+ MPI zz)
+{
+   /* ZZ = yb^xa mod p */
+   return mpi_powm(zz, yb, ctx->xa, ctx->p);
+}
+
+static inline struct dh_ctx *dh_get_ctx(struct crypto_kpp *tfm)
+{
+   return kpp_tfm_ctx(tfm);
+}
+
+static int dh_check_params_length(unsigned int p_len)
+{
+   return (p_len < 1536) ? -EINVAL : 0;
+}
+
+static int dh_set_params(struct crypto_kpp *tfm, void *buffer)
+{
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+   struct dh_params *params = (struct dh_params *)buffer;
+
+   if (unlikely(!buffer))
+   return -EINVAL;
+
+   if (unlikely(!params->p || !params->g))
+   return -EINVAL;
+
+   if (dh_check_params_length(params->p_size << 3))
+   return -EINVAL;
+
+   ctx->p = mpi_read_raw_data(params->p, params->p_size);
+   if (!ctx->p)
+   return -EINVAL;
+
+   ctx->g = mpi_read_raw_data(params->g, params->g_size);
+   if (!ctx->g) {
+   mpi_free(ctx->p);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int dh_set_secret(struct crypto_kpp *tfm, void *buffer,
+unsigned int len)
+{
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+
+   if (unlikely(!buffer || !len))
+   return -EINVAL;
+
+   ctx->xa = mpi_read_raw_data(buffer, len);
+
+   if (!ctx->xa)
+   return -EINVAL;
+
+   return 0;
+}
+
+static int dh_generate_public_key(struct kpp_request *req)
+{
+   struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+   const struct dh_ctx *ctx = dh_get_ctx(tfm);
+   MPI ya = mpi_alloc(0);
+   int ret = 0;
+   int sign;
+
+   if (!ya)
+   return -ENOMEM;
+
+   if (unlikely(!ctx->p || !ctx->g || !ctx->xa)) {
+   ret = -EINVAL;
+   goto err_free_ya;
+   }
+   ret = _generate_public_key(ctx, ya);
+   if (ret)
+   goto err_free_ya;
+
+   ret = mpi_write_to_sgl(ya, req->dst, &req->dst_len, &s

[PATCH v7 0/3] Key-agreement Protocol Primitives (KPP) API

2016-05-31 Thread Salvatore Benedetto
Hi Herb,

the following patchset introduces a new API for abstracting key-agreement
protocols such as DH and ECDH. It provides the primitives required for 
implementing
the protocol, thus the name KPP (Key-agreement Protocol Primitives).

Regards,
Salvatore

Changes from v6:
* Remove len parameter from crypto_kpp_set_params. Adjust rest of code
  accordingly
* Remove the while loop in ecdh_make_pub_key as the private key is fixed and
  iterating is pointless. EAGAIN is now to returned to make the user aware
  that he needs to regenerate/reset the private key

Changes from v5:
* Fix ecdh loading in fips mode.

Changes from v4:
* If fips_enabled is set allow only P256 (or higher) as Stephan suggested
* Pass ndigits as argument to ecdh_make_pub_key and ecdh_shared_secret
  so that VLA can be used like in the rest of the module

Changes from v3:
* Move curve ID definition to public header ecdh.h as users need to
  have access to those ids when selecting the curve

Changes from v2:
* Add support for ECDH (curve P192 and P256). I reused the ecc module
  already present in net/bluetooth and extended it in order to select
  different curves at runtime. Code for P192 was taken from tinycrypt.

Changes from v1:
* Change check in dh_check_params_length based on Stephan review


Salvatore Benedetto (3):
  crypto: Key-agreement Protocol Primitives API (KPP)
  crypto: kpp - Add DH software implementation
  crypto: kpp - Add ECDH software support

 crypto/Kconfig  |   23 +
 crypto/Makefile |6 +
 crypto/crypto_user.c|   20 +
 crypto/dh.c |  223 +
 crypto/ecc.c| 1011 +++
 crypto/ecc.h|   70 +++
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  170 +++
 crypto/kpp.c|  123 +
 crypto/testmgr.c|  275 +++
 crypto/testmgr.h|  286 +++
 include/crypto/dh.h |   23 +
 include/crypto/ecdh.h   |   24 +
 include/crypto/internal/kpp.h   |   64 +++
 include/crypto/kpp.h|  331 +
 include/linux/crypto.h  |1 +
 include/uapi/linux/cryptouser.h |5 +
 17 files changed, 2712 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/dh.h
 create mode 100644 include/crypto/ecdh.h
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

-- 
2.7.4

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


[PATCH v3] Bluetooth: convert smp and selftest to crypto kpp API

2016-05-13 Thread Salvatore Benedetto
 * Convert both smp and selftest to crypto kpp API
 * Remove module ecc as not more required
 * Add ecdh_helper functions for wrapping kpp async calls

Signed-off-by: Salvatore Benedetto 
---
Patch based on https://patchwork.kernel.org/patch/9065591/

Changes from v2:
 * Remove header guard in internal header
 * Shorter name for ecdh wrappers and fix 80chars issue
 * Add CRYPTO_ECDH dependency in bluetooth Kconfig

Changes from v1:
 * Convert ecc_make_key to kpp API

 net/bluetooth/Kconfig   |   1 +
 net/bluetooth/Makefile  |   2 +-
 net/bluetooth/ecc.c | 816 
 net/bluetooth/ecc.h |  54 ---
 net/bluetooth/ecdh_helper.c | 204 +++
 net/bluetooth/ecdh_helper.h |  27 ++
 net/bluetooth/selftest.c|   6 +-
 net/bluetooth/smp.c |   8 +-
 8 files changed, 240 insertions(+), 878 deletions(-)
 delete mode 100644 net/bluetooth/ecc.c
 delete mode 100644 net/bluetooth/ecc.h
 create mode 100644 net/bluetooth/ecdh_helper.c
 create mode 100644 net/bluetooth/ecdh_helper.h

diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
index 06c31b9..68f951b 100644
--- a/net/bluetooth/Kconfig
+++ b/net/bluetooth/Kconfig
@@ -13,6 +13,7 @@ menuconfig BT
select CRYPTO_CMAC
select CRYPTO_ECB
select CRYPTO_SHA256
+   select CRYPTO_ECDH
help
  Bluetooth is low-cost, low-power, short-range wireless technology.
  It was designed as a replacement for cables and other short-range
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index b3ff12e..c54d790 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -13,7 +13,7 @@ bluetooth_6lowpan-y := 6lowpan.o
 
 bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \
hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o lib.o \
-   ecc.o hci_request.o mgmt_util.o
+   ecdh_helper.o hci_request.o mgmt_util.o
 
 bluetooth-$(CONFIG_BT_BREDR) += sco.o
 bluetooth-$(CONFIG_BT_HS) += a2mp.o amp.o
diff --git a/net/bluetooth/ecc.c b/net/bluetooth/ecc.c
deleted file mode 100644
index e1709f8..000
--- a/net/bluetooth/ecc.c
+++ /dev/null
@@ -1,816 +0,0 @@
-/*
- * Copyright (c) 2013, Kenneth MacKay
- * All rights reserved.
- *
- * 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.
- *
- * 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
- * HOLDER 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 
-
-#include "ecc.h"
-
-/* 256-bit curve */
-#define ECC_BYTES 32
-
-#define MAX_TRIES 16
-
-/* Number of u64's needed */
-#define NUM_ECC_DIGITS (ECC_BYTES / 8)
-
-struct ecc_point {
-   u64 x[NUM_ECC_DIGITS];
-   u64 y[NUM_ECC_DIGITS];
-};
-
-typedef struct {
-   u64 m_low;
-   u64 m_high;
-} uint128_t;
-
-#define CURVE_P_32 {   0xull, 0xull, \
-   0xull, 0x0001ull }
-
-#define CURVE_G_32 { \
-   {   0xF4A13945D898C296ull, 0x77037D812DEB33A0ull,   \
-   0xF8BCE6E563A440F2ull, 0x6B17D1F2E12C4247ull }, \
-   {   0xCBB6406837BF51F5ull, 0x2BCE33576B315ECEull,   \
-   0x8EE7EB4A7C0F9E16ull, 0x4FE342E2FE1A7F9Bull }  \
-}
-
-#define CURVE_N_32 {   0xF3B9CAC2FC632551ull, 0xBCE6FAADA7179E84ull,   \
-   0xull, 0xull }
-
-static u64 curve_p[NUM_ECC_DIGITS] = CURVE_P_32;
-static struct ecc_point curve_g = CURVE_G_32;
-static u64 curve_n[NUM_ECC_DIGITS] = CURVE_N_32;
-
-static void vli_clear(u64 *vli)
-{
-   int i;
-
-   for (i = 0; i < NUM_ECC_DIGITS; i++)
-   vli[i] = 0;
-}
-
-/* Returns true if vli == 0, false otherwise. */
-static bool vli_is_zero(const u64 *vli)
-{
-   int i;
-
-   for (i = 0; i < NUM_ECC_DI

[PATCH v6 3/3] crypto: kpp - Add ECDH software support

2016-05-11 Thread Salvatore Benedetto
 * Implement ECDH under kpp API
 * Provide ECC software support for curve P-192 and
   P-256.
 * Add kpp test for ECDH with data generated by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |5 +
 crypto/Makefile |3 +
 crypto/ecc.c| 1016 +++
 crypto/ecc.h|   70 
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  171 
 crypto/testmgr.c|  136 ++-
 crypto/testmgr.h|   78 
 include/crypto/ecdh.h   |   24 ++
 9 files changed, 1551 insertions(+), 9 deletions(-)
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 include/crypto/ecdh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 89db25c..08a1a3b 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -117,6 +117,11 @@ config CRYPTO_DH
help
  Generic implementation of the Diffie-Hellman algorithm.
 
+config CRYPTO_ECDH
+   tristate "ECDH algorithm"
+   select CRYTPO_KPP
+   help
+ Generic implementation of the ECDH algorithm
 
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
diff --git a/crypto/Makefile b/crypto/Makefile
index 101f8fd..ba03079 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -33,6 +33,9 @@ obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
 obj-$(CONFIG_CRYPTO_DH) += dh.o
+ecdh_generic-y := ecc.o
+ecdh_generic-y += ecdh.o
+obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/ecc.c b/crypto/ecc.c
new file mode 100644
index 000..65b3134
--- /dev/null
+++ b/crypto/ecc.c
@@ -0,0 +1,1016 @@
+/*
+ * Copyright (c) 2013, Kenneth MacKay
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * 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
+ * HOLDER 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 
+#include 
+#include 
+#include 
+#include 
+
+#include "ecc.h"
+#include "ecc_curve_defs.h"
+
+#define MAX_TRIES 16
+
+typedef struct {
+   u64 m_low;
+   u64 m_high;
+} uint128_t;
+
+static inline const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
+{
+   switch (curve_id) {
+   /* In FIPS mode only allow P256 and higher */
+   case ECC_CURVE_NIST_P192:
+   return fips_enabled ? NULL : &nist_p192;
+   case ECC_CURVE_NIST_P256:
+   return &nist_p256;
+   default:
+   return NULL;
+   }
+}
+
+static u64 *ecc_alloc_digits_space(unsigned int ndigits)
+{
+   size_t len = ndigits * sizeof(u64);
+
+   if (!len)
+   return NULL;
+
+   return kmalloc(len, GFP_KERNEL);
+}
+
+static void ecc_free_digits_space(u64 *space)
+{
+   kzfree(space);
+}
+
+static struct ecc_point *ecc_alloc_point(unsigned int ndigits)
+{
+   struct ecc_point *p = kmalloc(sizeof(*p), GFP_KERNEL);
+
+   if (!p)
+   return NULL;
+
+   p->x = ecc_alloc_digits_space(ndigits);
+   if (!p->x)
+   goto err_alloc_x;
+
+   p->y = ecc_alloc_digits_space(ndigits);
+   if (!p->y)
+   goto err_alloc_y;
+
+   p->ndigits = ndigits;
+
+   return p;
+
+err_alloc_y:
+   ecc_free_digits_space(p->x);
+err_alloc_x:
+   kfree(p);
+   return NULL;
+}
+
+static void ecc_free_point(struct ecc_point *p)
+{
+   if (!p)
+   return;
+
+   kzfree(p->x);
+   kzfree(p->y);
+   kzfree(p);
+}
+
+static void vli_clear(u64 

[PATCH v6 2/3] crypto: kpp - Add DH software implementation

2016-05-11 Thread Salvatore Benedetto
 * Implement MPI based Diffie-Hellman under kpp API
 * Test provided uses data generad by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |   8 ++
 crypto/Makefile |   2 +
 crypto/dh.c | 224 
 crypto/testmgr.c| 157 
 crypto/testmgr.h| 208 
 include/crypto/dh.h |  23 ++
 6 files changed, 622 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 include/crypto/dh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 31bf962..89db25c 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -110,6 +110,14 @@ config CRYPTO_RSA
help
  Generic implementation of the RSA public key algorithm.
 
+config CRYPTO_DH
+   tristate "Diffie-Hellman algorithm"
+   select CRYPTO_KPP
+   select MPILIB
+   help
+ Generic implementation of the Diffie-Hellman algorithm.
+
+
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 5b60890..101f8fd 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -32,6 +32,8 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
+obj-$(CONFIG_CRYPTO_DH) += dh.o
+
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
 clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
diff --git a/crypto/dh.c b/crypto/dh.c
new file mode 100644
index 000..06e4805
--- /dev/null
+++ b/crypto/dh.c
@@ -0,0 +1,224 @@
+/*  Diffie-Hellman Key Agreement Method [RFC2631]
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+
+struct dh_ctx {
+   MPI p;
+   MPI g;
+   MPI xa;
+};
+
+static void dh_free_ctx(struct dh_ctx *ctx)
+{
+   mpi_free(ctx->p);
+   mpi_free(ctx->g);
+   mpi_free(ctx->xa);
+   ctx->p = NULL;
+   ctx->g = NULL;
+   ctx->xa = NULL;
+}
+
+/*
+ * Public key generation function [RFC2631 sec 2.1.1]
+ * ya = g^xa mod p;
+ */
+static int _generate_public_key(const struct dh_ctx *ctx, MPI ya)
+{
+   /* ya = g^xa mod p */
+   return mpi_powm(ya, ctx->g, ctx->xa, ctx->p);
+}
+
+/*
+ * ZZ generation function [RFC2631 sec 2.1.1]
+ * ZZ = yb^xa mod p;
+ */
+static int _compute_shared_secret(const struct dh_ctx *ctx, MPI yb,
+ MPI zz)
+{
+   /* ZZ = yb^xa mod p */
+   return mpi_powm(zz, yb, ctx->xa, ctx->p);
+}
+
+static inline struct dh_ctx *dh_get_ctx(struct crypto_kpp *tfm)
+{
+   return kpp_tfm_ctx(tfm);
+}
+
+static int dh_check_params_length(unsigned int p_len)
+{
+   return (p_len < 1536) ? -EINVAL : 0;
+}
+
+static int dh_set_params(struct crypto_kpp *tfm, void *buffer,
+unsigned int len)
+{
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+   struct dh_params *params = (struct dh_params *)buffer;
+
+   if (unlikely(!buffer || !len))
+   return -EINVAL;
+
+   if (unlikely(!params->p || !params->g))
+   return -EINVAL;
+
+   if (dh_check_params_length(params->p_size << 3))
+   return -EINVAL;
+
+   ctx->p = mpi_read_raw_data(params->p, params->p_size);
+   if (!ctx->p)
+   return -EINVAL;
+
+   ctx->g = mpi_read_raw_data(params->g, params->g_size);
+   if (!ctx->g) {
+   mpi_free(ctx->p);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int dh_set_secret(struct crypto_kpp *tfm, void *buffer,
+unsigned int len)
+{
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+
+   if (unlikely(!buffer || !len))
+   return -EINVAL;
+
+   ctx->xa = mpi_read_raw_data(buffer, len);
+
+   if (!ctx->xa)
+   return -EINVAL;
+
+   return 0;
+}
+
+static int dh_generate_public_key(struct kpp_request *req)
+{
+   struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+   const struct dh_ctx *ctx = dh_get_ctx(tfm);
+   MPI ya = mpi_alloc(0);
+   int ret = 0;
+   int sign;
+
+   if (!ya)
+   return -ENOMEM;
+
+   if (unlikely(!ctx->p || !ctx->g || !ctx->xa)) {
+   ret = -EINVAL;
+   goto err_free_ya;
+   }
+   ret = _generate_public_key(ctx, ya);
+   if (ret)
+   goto err_free_ya;
+
+   ret = mpi_write_to_s

[PATCH v6 1/3] crypto: Key-agreement Protocol Primitives API (KPP)

2016-05-11 Thread Salvatore Benedetto
Add key-agreement protocol primitives (kpp) API which allows to
implement primitives required by protocols such as DH and ECDH.
The API is composed mainly by the following functions
 * set_params() - It allows the user to set the parameters known to
   both parties involved in the key-agreement session
 * set_secret() - It allows the user to set his secret, also
   referred to as his private key
 * generate_public_key() - It generates the public key to be sent to
   the other counterpart involved in the key-agreement session. The
   function has to be called after set_params() and set_secret()
 * generate_secret() - It generates the shared secret for the session

Other functions such as init() and exit() are provided for allowing
cryptographic hardware to be inizialized properly before use

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |  10 ++
 crypto/Makefile |   1 +
 crypto/crypto_user.c|  20 +++
 crypto/kpp.c| 123 +++
 include/crypto/internal/kpp.h   |  64 
 include/crypto/kpp.h| 333 
 include/linux/crypto.h  |   1 +
 include/uapi/linux/cryptouser.h |   5 +
 8 files changed, 557 insertions(+)
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 93a1fdc..31bf962 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -93,6 +93,15 @@ config CRYPTO_AKCIPHER
select CRYPTO_AKCIPHER2
select CRYPTO_ALGAPI
 
+config CRYPTO_KPP2
+   tristate
+   select CRYPTO_ALGAPI2
+
+config CRYPTO_KPP
+   tristate
+   select CRYPTO_ALGAPI
+   select CRYPTO_KPP2
+
 config CRYPTO_RSA
tristate "RSA algorithm"
select CRYPTO_AKCIPHER
@@ -114,6 +123,7 @@ config CRYPTO_MANAGER2
select CRYPTO_HASH2
select CRYPTO_BLKCIPHER2
select CRYPTO_AKCIPHER2
+   select CRYPTO_KPP2
 
 config CRYPTO_USER
tristate "Userspace cryptographic algorithm configuration"
diff --git a/crypto/Makefile b/crypto/Makefile
index 4f4ef7e..5b60890 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -30,6 +30,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
+obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 43fe85f..d28513fb 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "internal.h"
 
@@ -126,6 +127,21 @@ nla_put_failure:
return -EMSGSIZE;
 }
 
+static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   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)
 {
@@ -176,6 +192,10 @@ static int crypto_report_one(struct crypto_alg *alg,
goto nla_put_failure;
 
break;
+   case CRYPTO_ALG_TYPE_KPP:
+   if (crypto_report_kpp(skb, alg))
+   goto nla_put_failure;
+   break;
}
 
 out:
diff --git a/crypto/kpp.c b/crypto/kpp.c
new file mode 100644
index 000..d36ce05
--- /dev/null
+++ b/crypto/kpp.c
@@ -0,0 +1,123 @@
+/*
+ * Key-agreement Protocol Primitives (KPP)
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "internal.h"
+
+#ifdef CONFIG_NET
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+st

[PATCH v6 0/3] Key-agreement Protocol Primitives (KPP) API

2016-05-11 Thread Salvatore Benedetto
Hi Herb,

the following patchset introduces a new API for abstracting key-agreement
protocols such as DH and ECDH. It provides the primitives required for 
implementing
the protocol, thus the name KPP (Key-agreement Protocol Primitives).

Regards,
Salvatore

Changes from v5:
* Fix ecdh loading in fips mode.

Changes from v4:
* If fips_enabled is set allow only P256 (or higher) as Stephan suggested
* Pass ndigits as argument to ecdh_make_pub_key and ecdh_shared_secret
  so that VLA can be used like in the rest of the module

Changes from v3:
* Move curve ID definition to public header ecdh.h as users need to
  have access to those ids when selecting the curve

Changes from v2:
* Add support for ECDH (curve P192 and P256). I reused the ecc module
  already present in net/bluetooth and extended it in order to select
  different curves at runtime. Code for P192 was taken from tinycrypt.

Changes from v1:
* Change check in dh_check_params_length based on Stephan review


Salvatore Benedetto (3):
  crypto: Key-agreement Protocol Primitives API (KPP)
  crypto: kpp - Add DH software implementation
  crypto: kpp - Add ECDH software support

 crypto/Kconfig  |   23 +
 crypto/Makefile |6 +
 crypto/crypto_user.c|   20 +
 crypto/dh.c |  224 +
 crypto/ecc.c| 1016 +++
 crypto/ecc.h|   70 +++
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  171 +++
 crypto/kpp.c|  123 +
 crypto/testmgr.c|  275 +++
 crypto/testmgr.h|  286 +++
 include/crypto/dh.h |   23 +
 include/crypto/ecdh.h   |   24 +
 include/crypto/internal/kpp.h   |   64 +++
 include/crypto/kpp.h|  333 +
 include/linux/crypto.h  |1 +
 include/uapi/linux/cryptouser.h |5 +
 17 files changed, 2721 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/dh.h
 create mode 100644 include/crypto/ecdh.h
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

-- 
2.5.0

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


[PATCH v2] Bluetooth: convert smp and selftest to crypto kpp API

2016-05-09 Thread Salvatore Benedetto
 * Convert both smp and selftest to crypto kpp API
 * Remove module ecc as not more required
 * Add ecdh_helper functions for wrapping kpp async calls

This patch has been tested *only* with selftest, which is called on
module loading. smp-tester passes all tests but the first one, which
often times out. Same behavior is observed without this patch though.

This patch is based on https://patchwork.kernel.org/patch/9050061/

Signed-off-by: Salvatore Benedetto 
---
 net/bluetooth/Makefile  |   2 +-
 net/bluetooth/ecc.c | 816 
 net/bluetooth/ecc.h |  54 ---
 net/bluetooth/ecdh_helper.c | 204 +++
 net/bluetooth/ecdh_helper.h |  32 ++
 net/bluetooth/selftest.c|   6 +-
 net/bluetooth/smp.c |   8 +-
 7 files changed, 244 insertions(+), 878 deletions(-)
 delete mode 100644 net/bluetooth/ecc.c
 delete mode 100644 net/bluetooth/ecc.h
 create mode 100644 net/bluetooth/ecdh_helper.c
 create mode 100644 net/bluetooth/ecdh_helper.h

diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index b3ff12e..c54d790 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -13,7 +13,7 @@ bluetooth_6lowpan-y := 6lowpan.o
 
 bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \
hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o lib.o \
-   ecc.o hci_request.o mgmt_util.o
+   ecdh_helper.o hci_request.o mgmt_util.o
 
 bluetooth-$(CONFIG_BT_BREDR) += sco.o
 bluetooth-$(CONFIG_BT_HS) += a2mp.o amp.o
diff --git a/net/bluetooth/ecc.c b/net/bluetooth/ecc.c
deleted file mode 100644
index e1709f8..000
--- a/net/bluetooth/ecc.c
+++ /dev/null
@@ -1,816 +0,0 @@
-/*
- * Copyright (c) 2013, Kenneth MacKay
- * All rights reserved.
- *
- * 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.
- *
- * 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
- * HOLDER 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 
-
-#include "ecc.h"
-
-/* 256-bit curve */
-#define ECC_BYTES 32
-
-#define MAX_TRIES 16
-
-/* Number of u64's needed */
-#define NUM_ECC_DIGITS (ECC_BYTES / 8)
-
-struct ecc_point {
-   u64 x[NUM_ECC_DIGITS];
-   u64 y[NUM_ECC_DIGITS];
-};
-
-typedef struct {
-   u64 m_low;
-   u64 m_high;
-} uint128_t;
-
-#define CURVE_P_32 {   0xull, 0xull, \
-   0xull, 0x0001ull }
-
-#define CURVE_G_32 { \
-   {   0xF4A13945D898C296ull, 0x77037D812DEB33A0ull,   \
-   0xF8BCE6E563A440F2ull, 0x6B17D1F2E12C4247ull }, \
-   {   0xCBB6406837BF51F5ull, 0x2BCE33576B315ECEull,   \
-   0x8EE7EB4A7C0F9E16ull, 0x4FE342E2FE1A7F9Bull }  \
-}
-
-#define CURVE_N_32 {   0xF3B9CAC2FC632551ull, 0xBCE6FAADA7179E84ull,   \
-   0xull, 0xull }
-
-static u64 curve_p[NUM_ECC_DIGITS] = CURVE_P_32;
-static struct ecc_point curve_g = CURVE_G_32;
-static u64 curve_n[NUM_ECC_DIGITS] = CURVE_N_32;
-
-static void vli_clear(u64 *vli)
-{
-   int i;
-
-   for (i = 0; i < NUM_ECC_DIGITS; i++)
-   vli[i] = 0;
-}
-
-/* Returns true if vli == 0, false otherwise. */
-static bool vli_is_zero(const u64 *vli)
-{
-   int i;
-
-   for (i = 0; i < NUM_ECC_DIGITS; i++) {
-   if (vli[i])
-   return false;
-   }
-
-   return true;
-}
-
-/* Returns nonzero if bit bit of vli is set. */
-static u64 vli_test_bit(const u64 *vli, unsigned int bit)
-{
-   return (vli[bit / 64] & ((u64) 1 << (bit % 64)));
-}
-
-/* Counts the number of 64-bit "digits" in vli. */
-static unsigned int vli_num_digits(const u64 *vli)
-{
-   int i;
-
-   /* Search from the end until we find a non-ze

[PATCH v5 3/3] crypto: kpp - Add ECDH software support

2016-05-09 Thread Salvatore Benedetto
 * Implement ECDH under kpp API
 * Provide ECC software support for curve P-192 and
   P-256.
 * Add kpp test for ECDH with data generated by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |5 +
 crypto/Makefile |3 +
 crypto/ecc.c| 1016 +++
 crypto/ecc.h|   70 
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  171 
 crypto/testmgr.c|  136 ++-
 crypto/testmgr.h|   73 
 include/crypto/ecdh.h   |   24 ++
 9 files changed, 1546 insertions(+), 9 deletions(-)
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 include/crypto/ecdh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 89db25c..08a1a3b 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -117,6 +117,11 @@ config CRYPTO_DH
help
  Generic implementation of the Diffie-Hellman algorithm.
 
+config CRYPTO_ECDH
+   tristate "ECDH algorithm"
+   select CRYTPO_KPP
+   help
+ Generic implementation of the ECDH algorithm
 
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
diff --git a/crypto/Makefile b/crypto/Makefile
index 101f8fd..ba03079 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -33,6 +33,9 @@ obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
 obj-$(CONFIG_CRYPTO_DH) += dh.o
+ecdh_generic-y := ecc.o
+ecdh_generic-y += ecdh.o
+obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/ecc.c b/crypto/ecc.c
new file mode 100644
index 000..2a05de5
--- /dev/null
+++ b/crypto/ecc.c
@@ -0,0 +1,1016 @@
+/*
+ * Copyright (c) 2013, Kenneth MacKay
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * 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
+ * HOLDER 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 
+#include 
+#include 
+#include 
+#include 
+
+#include "ecc.h"
+#include "ecc_curve_defs.h"
+
+#define MAX_TRIES 16
+
+typedef struct {
+   u64 m_low;
+   u64 m_high;
+} uint128_t;
+
+static inline const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
+{
+   switch (curve_id) {
+   /* In FIPS mode only allow P256 and higher */
+   case ECC_CURVE_NIST_P192:
+   return fips_enabled ? NULL : &nist_p192;
+   case ECC_CURVE_NIST_P256:
+   return &nist_p256;
+   default:
+   return NULL;
+   }
+}
+
+static u64 *ecc_alloc_digits_space(unsigned int ndigits)
+{
+   size_t len = ndigits * sizeof(u64);
+
+   if (!len)
+   return NULL;
+
+   return kmalloc(len, GFP_KERNEL);
+}
+
+static void ecc_free_digits_space(u64 *space)
+{
+   kzfree(space);
+}
+
+static struct ecc_point *ecc_alloc_point(unsigned int ndigits)
+{
+   struct ecc_point *p = kmalloc(sizeof(*p), GFP_KERNEL);
+
+   if (!p)
+   return NULL;
+
+   p->x = ecc_alloc_digits_space(ndigits);
+   if (!p->x)
+   goto err_alloc_x;
+
+   p->y = ecc_alloc_digits_space(ndigits);
+   if (!p->y)
+   goto err_alloc_y;
+
+   p->ndigits = ndigits;
+
+   return p;
+
+err_alloc_y:
+   ecc_free_digits_space(p->x);
+err_alloc_x:
+   kfree(p);
+   return NULL;
+}
+
+static void ecc_free_point(struct ecc_point *p)
+{
+   if (!p)
+   return;
+
+   kzfree(p->x);
+   kzfree(p->y);
+   kzfree(p);
+}
+
+static void vli_clear(u64 

[PATCH v5 1/3] crypto: Key-agreement Protocol Primitives API (KPP)

2016-05-09 Thread Salvatore Benedetto
Add key-agreement protocol primitives (kpp) API which allows to
implement primitives required by protocols such as DH and ECDH.
The API is composed mainly by the following functions
 * set_params() - It allows the user to set the parameters known to
   both parties involved in the key-agreement session
 * set_secret() - It allows the user to set his secret, also
   referred to as his private key
 * generate_public_key() - It generates the public key to be sent to
   the other counterpart involved in the key-agreement session. The
   function has to be called after set_params() and set_secret()
 * generate_secret() - It generates the shared secret for the session

Other functions such as init() and exit() are provided for allowing
cryptographic hardware to be inizialized properly before use

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |  10 ++
 crypto/Makefile |   1 +
 crypto/crypto_user.c|  20 +++
 crypto/kpp.c| 123 +++
 include/crypto/internal/kpp.h   |  64 
 include/crypto/kpp.h| 333 
 include/linux/crypto.h  |   1 +
 include/uapi/linux/cryptouser.h |   5 +
 8 files changed, 557 insertions(+)
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 93a1fdc..31bf962 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -93,6 +93,15 @@ config CRYPTO_AKCIPHER
select CRYPTO_AKCIPHER2
select CRYPTO_ALGAPI
 
+config CRYPTO_KPP2
+   tristate
+   select CRYPTO_ALGAPI2
+
+config CRYPTO_KPP
+   tristate
+   select CRYPTO_ALGAPI
+   select CRYPTO_KPP2
+
 config CRYPTO_RSA
tristate "RSA algorithm"
select CRYPTO_AKCIPHER
@@ -114,6 +123,7 @@ config CRYPTO_MANAGER2
select CRYPTO_HASH2
select CRYPTO_BLKCIPHER2
select CRYPTO_AKCIPHER2
+   select CRYPTO_KPP2
 
 config CRYPTO_USER
tristate "Userspace cryptographic algorithm configuration"
diff --git a/crypto/Makefile b/crypto/Makefile
index 4f4ef7e..5b60890 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -30,6 +30,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
+obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 43fe85f..d28513fb 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "internal.h"
 
@@ -126,6 +127,21 @@ nla_put_failure:
return -EMSGSIZE;
 }
 
+static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   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)
 {
@@ -176,6 +192,10 @@ static int crypto_report_one(struct crypto_alg *alg,
goto nla_put_failure;
 
break;
+   case CRYPTO_ALG_TYPE_KPP:
+   if (crypto_report_kpp(skb, alg))
+   goto nla_put_failure;
+   break;
}
 
 out:
diff --git a/crypto/kpp.c b/crypto/kpp.c
new file mode 100644
index 000..d36ce05
--- /dev/null
+++ b/crypto/kpp.c
@@ -0,0 +1,123 @@
+/*
+ * Key-agreement Protocol Primitives (KPP)
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "internal.h"
+
+#ifdef CONFIG_NET
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+st

[PATCH v5 2/3] crypto: kpp - Add DH software implementation

2016-05-09 Thread Salvatore Benedetto
 * Implement MPI based Diffie-Hellman under kpp API
 * Test provided uses data generad by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |   8 ++
 crypto/Makefile |   2 +
 crypto/dh.c | 224 
 crypto/testmgr.c| 157 
 crypto/testmgr.h| 208 
 include/crypto/dh.h |  23 ++
 6 files changed, 622 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 include/crypto/dh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 31bf962..89db25c 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -110,6 +110,14 @@ config CRYPTO_RSA
help
  Generic implementation of the RSA public key algorithm.
 
+config CRYPTO_DH
+   tristate "Diffie-Hellman algorithm"
+   select CRYPTO_KPP
+   select MPILIB
+   help
+ Generic implementation of the Diffie-Hellman algorithm.
+
+
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 5b60890..101f8fd 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -32,6 +32,8 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
+obj-$(CONFIG_CRYPTO_DH) += dh.o
+
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
 clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
diff --git a/crypto/dh.c b/crypto/dh.c
new file mode 100644
index 000..06e4805
--- /dev/null
+++ b/crypto/dh.c
@@ -0,0 +1,224 @@
+/*  Diffie-Hellman Key Agreement Method [RFC2631]
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+
+struct dh_ctx {
+   MPI p;
+   MPI g;
+   MPI xa;
+};
+
+static void dh_free_ctx(struct dh_ctx *ctx)
+{
+   mpi_free(ctx->p);
+   mpi_free(ctx->g);
+   mpi_free(ctx->xa);
+   ctx->p = NULL;
+   ctx->g = NULL;
+   ctx->xa = NULL;
+}
+
+/*
+ * Public key generation function [RFC2631 sec 2.1.1]
+ * ya = g^xa mod p;
+ */
+static int _generate_public_key(const struct dh_ctx *ctx, MPI ya)
+{
+   /* ya = g^xa mod p */
+   return mpi_powm(ya, ctx->g, ctx->xa, ctx->p);
+}
+
+/*
+ * ZZ generation function [RFC2631 sec 2.1.1]
+ * ZZ = yb^xa mod p;
+ */
+static int _compute_shared_secret(const struct dh_ctx *ctx, MPI yb,
+ MPI zz)
+{
+   /* ZZ = yb^xa mod p */
+   return mpi_powm(zz, yb, ctx->xa, ctx->p);
+}
+
+static inline struct dh_ctx *dh_get_ctx(struct crypto_kpp *tfm)
+{
+   return kpp_tfm_ctx(tfm);
+}
+
+static int dh_check_params_length(unsigned int p_len)
+{
+   return (p_len < 1536) ? -EINVAL : 0;
+}
+
+static int dh_set_params(struct crypto_kpp *tfm, void *buffer,
+unsigned int len)
+{
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+   struct dh_params *params = (struct dh_params *)buffer;
+
+   if (unlikely(!buffer || !len))
+   return -EINVAL;
+
+   if (unlikely(!params->p || !params->g))
+   return -EINVAL;
+
+   if (dh_check_params_length(params->p_size << 3))
+   return -EINVAL;
+
+   ctx->p = mpi_read_raw_data(params->p, params->p_size);
+   if (!ctx->p)
+   return -EINVAL;
+
+   ctx->g = mpi_read_raw_data(params->g, params->g_size);
+   if (!ctx->g) {
+   mpi_free(ctx->p);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int dh_set_secret(struct crypto_kpp *tfm, void *buffer,
+unsigned int len)
+{
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+
+   if (unlikely(!buffer || !len))
+   return -EINVAL;
+
+   ctx->xa = mpi_read_raw_data(buffer, len);
+
+   if (!ctx->xa)
+   return -EINVAL;
+
+   return 0;
+}
+
+static int dh_generate_public_key(struct kpp_request *req)
+{
+   struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+   const struct dh_ctx *ctx = dh_get_ctx(tfm);
+   MPI ya = mpi_alloc(0);
+   int ret = 0;
+   int sign;
+
+   if (!ya)
+   return -ENOMEM;
+
+   if (unlikely(!ctx->p || !ctx->g || !ctx->xa)) {
+   ret = -EINVAL;
+   goto err_free_ya;
+   }
+   ret = _generate_public_key(ctx, ya);
+   if (ret)
+   goto err_free_ya;
+
+   ret = mpi_write_to_s

[PATCH v5 0/3] Key-agreement Protocol Primitives (KPP) API

2016-05-09 Thread Salvatore Benedetto
Hi Herb,

the following patchset introduces a new API for abstracting key-agreement
protocols such as DH and ECDH. It provides the primitives required for 
implementing
the protocol, thus the name KPP (Key-agreement Protocol Primitives).

Regards,
Salvatore

Changes from v4:
* If fips_enabled is set allow only P256 (or higher) as Stephan suggested
* Pass ndigits as argument to ecdh_make_pub_key and ecdh_shared_secret
  so that VLA can be used like in the rest of the module

Changes from v3:
* Move curve ID definition to public header ecdh.h as users need to
  have access to those ids when selecting the curve

Changes from v2:
* Add support for ECDH (curve P192 and P256). I reused the ecc module
  already present in net/bluetooth and extended it in order to select
  different curves at runtime. Code for P192 was taken from tinycrypt.

Changes from v1:
* Change check in dh_check_params_length based on Stephan review

Salvatore Benedetto (3):
  crypto: Key-agreement Protocol Primitives API (KPP)
  crypto: kpp - Add DH software implementation
  crypto: kpp - Add ECDH software support

 crypto/Kconfig  |   23 +
 crypto/Makefile |6 +
 crypto/crypto_user.c|   20 +
 crypto/dh.c |  224 +
 crypto/ecc.c| 1016 +++
 crypto/ecc.h|   70 +++
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  171 +++
 crypto/kpp.c|  123 +
 crypto/testmgr.c|  275 +++
 crypto/testmgr.h|  281 +++
 include/crypto/dh.h |   23 +
 include/crypto/ecdh.h   |   24 +
 include/crypto/internal/kpp.h   |   64 +++
 include/crypto/kpp.h|  333 +
 include/linux/crypto.h  |1 +
 include/uapi/linux/cryptouser.h |5 +
 17 files changed, 2716 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/dh.h
 create mode 100644 include/crypto/ecdh.h
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

-- 
1.9.1

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


[PATCH v2] Bluetooth: convert smp module to crypto kpp API

2016-05-05 Thread Salvatore Benedetto
This patch has *not* been tested as I don't have the hardware.
It's purpose is to show how to use the kpp API.

Based on https://patchwork.kernel.org/patch/9022371/

Signed-off-by: Salvatore Benedetto 
---
v2: Also convert ecc_make_key to kpp API

 net/bluetooth/smp.c | 184 +++-
 1 file changed, 181 insertions(+), 3 deletions(-)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 50976a6..4d28704 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -25,6 +25,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -211,6 +213,182 @@ static int aes_cmac(struct crypto_shash *tfm, const u8 
k[16], const u8 *m,
return 0;
 }
 
+struct ecdh_completion {
+   struct completion completion;
+   int err;
+};
+
+static void ecdh_complete(struct crypto_async_request *req, int err)
+{
+   struct ecdh_completion *res = req->data;
+
+   if (err == -EINPROGRESS)
+   return;
+
+   res->err = err;
+   complete(&res->completion);
+}
+
+static inline void swap_digits(u64 *in, u64 *out, unsigned int ndigits)
+{
+   int i;
+
+   for (i = 0; i < ndigits; i++)
+   out[i] = __swab64(in[ndigits - 1 - i]);
+}
+
+static bool compute_ecdh_shared_secret(const u8 public_key[64],
+  const u8 private_key[32], u8 secret[32])
+{
+   struct crypto_kpp *tfm;
+   struct kpp_request *req;
+   struct ecdh_params p;
+   struct ecdh_completion result;
+   struct scatterlist src, dst;
+   u8 tmp[64];
+   int err = -ENOMEM;
+
+   tfm = crypto_alloc_kpp("ecdh", CRYPTO_ALG_INTERNAL, 0);
+   if (IS_ERR(tfm)) {
+   pr_err("alg: kpp: Failed to load tfm for kpp: %ld\n",
+  PTR_ERR(tfm));
+   return false;
+   }
+
+   req = kpp_request_alloc(tfm, GFP_KERNEL);
+   if (!req)
+   goto free_kpp;
+
+   init_completion(&result.completion);
+
+   /* Set curve_id */
+   p.curve_id = ECC_CURVE_NIST_P256;
+   err = crypto_kpp_set_params(tfm, (void *)&p, sizeof(p));
+   if (err)
+   goto free_req;
+
+   /* Security Manager Protocol holds digits in litte-endian order
+* while ECC API expect big-endian data
+*/
+   swap_digits((u64 *)private_key, (u64 *)tmp, 4);
+
+   /* Set A private Key */
+   err = crypto_kpp_set_secret(tfm, (void *)tmp, 32);
+   if (err)
+   goto free_all;
+
+   swap_digits((u64 *)public_key, (u64 *)tmp, 4); /* x */
+   swap_digits((u64 *)&public_key[32], (u64 *)&tmp[32], 4); /* y */
+
+   sg_init_one(&src, tmp, 64);
+   sg_init_one(&dst, secret, 32);
+   kpp_request_set_input(req, &src, 64);
+   kpp_request_set_output(req, &dst, 32);
+   kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ecdh_complete, &result);
+   err = crypto_kpp_compute_shared_secret(req);
+   if (err == -EINPROGRESS) {
+   wait_for_completion(&result.completion);
+   err = result.err;
+   }
+   if (err < 0) {
+   pr_err("alg: ecdh: compute shard secret test failed. err %d\n",
+  err);
+   goto free_all;
+   }
+
+   swap_digits((u64 *)secret, (u64 *)tmp, 4);
+   memcpy(secret, tmp, 32);
+
+free_all:
+free_req:
+   kpp_request_free(req);
+free_kpp:
+   crypto_free_kpp(tfm);
+   return (err == 0);
+}
+
+bool generate_ecdh_key_pair(u8 public_key[64], u8 private_key[32])
+{
+   struct crypto_kpp *tfm;
+   struct kpp_request *req;
+   struct ecdh_params p;
+   struct ecdh_completion result;
+   struct scatterlist dst;
+   u8 tmp[64];
+   int err = -ENOMEM;
+   const unsigned short max_tries = 16;
+   unsigned short tries = 0;
+
+   tfm = crypto_alloc_kpp("ecdh", CRYPTO_ALG_INTERNAL, 0);
+   if (IS_ERR(tfm)) {
+   pr_err("alg: kpp: Failed to load tfm for kpp: %ld\n",
+  PTR_ERR(tfm));
+   return false;
+   }
+
+   req = kpp_request_alloc(tfm, GFP_KERNEL);
+   if (!req)
+   goto free_kpp;
+
+   init_completion(&result.completion);
+
+   /* Set curve_id */
+   p.curve_id = ECC_CURVE_NIST_P256;
+   err = crypto_kpp_set_params(tfm, (void *)&p, sizeof(p));
+   if (err)
+   goto free_req;
+
+   do {
+   if (tries++ >= max_tries)
+   goto free_all;
+
+   get_random_bytes(private_key, 32);
+
+   /* Set private Key */
+   err = crypto_kpp_set_secret(tfm, (void *)private_key, 32);
+   if (err)
+   goto free_all;
+
+   sg_init_one(&dst, tmp

[PATCH] Bluetooth: convert smp module to crypto kpp API

2016-05-05 Thread Salvatore Benedetto
This patch has *not* been tested as I don't have the hardware.
It's purpose is to show how to use the kpp API.

Based on https://patchwork.kernel.org/patch/9022371/

Signed-off-by: Salvatore Benedetto 
---
 net/bluetooth/smp.c | 99 -
 1 file changed, 98 insertions(+), 1 deletion(-)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 50976a6..25844a2 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -25,6 +25,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -2591,6 +2593,101 @@ static u8 sc_select_method(struct smp_chan *smp)
return method;
 }
 
+struct ecdh_completion {
+   struct completion completion;
+   int err;
+};
+
+static void ecdh_complete(struct crypto_async_request *req, int err)
+{
+   struct ecdh_completion *res = req->data;
+
+   if (err == -EINPROGRESS)
+   return;
+
+   res->err = err;
+   complete(&res->completion);
+}
+
+static inline void swap_digits(u64 *in, u64 *out, unsigned int ndigits)
+{
+   int i;
+
+   for (i = 0; i < ndigits; i++)
+   out[i] = __swab64(in[ndigits - 1 - i]);
+}
+
+static bool compute_ecdh_shared_secret(const u8 public_key[64],
+  const u8 private_key[32], u8 secret[32])
+{
+   struct crypto_kpp *tfm;
+   struct kpp_request *req;
+   struct ecdh_params p;
+   struct ecdh_completion result;
+   struct scatterlist src, dst;
+   u8 tmp[64];
+   int err = -ENOMEM;
+
+   tfm = crypto_alloc_kpp("ecdh", CRYPTO_ALG_INTERNAL, 0);
+   if (IS_ERR(tfm)) {
+   pr_err("alg: kpp: Failed to load tfm for kpp: %ld\n",
+  PTR_ERR(tfm));
+   return false;
+   }
+
+   req = kpp_request_alloc(tfm, GFP_KERNEL);
+   if (!req)
+   goto free_kpp;
+
+   init_completion(&result.completion);
+
+   /* Set curve_id */
+   p.curve_id = ECC_CURVE_NIST_P256;
+   err = crypto_kpp_set_params(tfm, (void *)&p, sizeof(p));
+   if (err)
+   goto free_req;
+
+   /* Security Manager Protocol holds digits in litte-endian order
+* while ECC API expect big-endian data
+*/
+   swap_digits((u64 *)private_key, (u64 *)tmp, 4);
+
+   /* Set A private Key */
+   err = crypto_kpp_set_secret(tfm, (void *)tmp, 32);
+   if (err)
+   goto free_all;
+
+   swap_digits((u64 *)public_key, (u64 *)tmp, 4); /* x */
+   swap_digits((u64 *)&public_key[32], (u64 *)&tmp[32], 4); /* y */
+
+   sg_init_one(&src, tmp, 64);
+   sg_init_one(&dst, secret, 32);
+   kpp_request_set_input(req, &src, 64);
+   kpp_request_set_output(req, &dst, 32);
+   kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ecdh_complete, &result);
+   err = crypto_kpp_compute_shared_secret(req);
+   if (err == -EINPROGRESS) {
+   wait_for_completion(&result.completion);
+   err = result.err;
+   }
+   if (err < 0) {
+   pr_err("alg: ecdh: compute shard secret test failed. err %d\n",
+  err);
+   goto free_all;
+   }
+
+   swap_digits((u64 *)secret, (u64 *)tmp, 4);
+   memcpy(secret, tmp, 32);
+
+free_all:
+free_req:
+   kpp_request_free(req);
+free_kpp:
+   crypto_free_kpp(tfm);
+   return (err == 0);
+}
+
 static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb)
 {
struct smp_cmd_public_key *key = (void *) skb->data;
@@ -2630,7 +2727,7 @@ static int smp_cmd_public_key(struct l2cap_conn *conn, 
struct sk_buff *skb)
SMP_DBG("Remote Public Key X: %32phN", smp->remote_pk);
SMP_DBG("Remote Public Key Y: %32phN", smp->remote_pk + 32);
 
-   if (!ecdh_shared_secret(smp->remote_pk, smp->local_sk, smp->dhkey))
+   if (!compute_ecdh_shared_secret(smp->remote_pk, smp->local_sk, 
smp->dhkey))
return SMP_UNSPECIFIED;
 
SMP_DBG("DHKey %32phN", smp->dhkey);
-- 
1.9.1

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


[PATCH 3/3 v4] crypto: kpp - Add ECDH software support

2016-05-05 Thread Salvatore Benedetto
 * Implement ECDH under kpp API
 * Provide ECC software support for curve P-192 and
   P-256.
 * Add kpp test for ECDH with data generated by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |5 +
 crypto/Makefile |3 +
 crypto/ecc.c| 1038 +++
 crypto/ecc.h|   70 
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  171 
 crypto/testmgr.c|  136 ++-
 crypto/testmgr.h|   73 
 include/crypto/ecdh.h   |   24 ++
 9 files changed, 1568 insertions(+), 9 deletions(-)
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 include/crypto/ecdh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 89db25c..08a1a3b 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -117,6 +117,11 @@ config CRYPTO_DH
help
  Generic implementation of the Diffie-Hellman algorithm.
 
+config CRYPTO_ECDH
+   tristate "ECDH algorithm"
+   select CRYTPO_KPP
+   help
+ Generic implementation of the ECDH algorithm
 
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
diff --git a/crypto/Makefile b/crypto/Makefile
index 101f8fd..ba03079 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -33,6 +33,9 @@ obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
 obj-$(CONFIG_CRYPTO_DH) += dh.o
+ecdh_generic-y := ecc.o
+ecdh_generic-y += ecdh.o
+obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/ecc.c b/crypto/ecc.c
new file mode 100644
index 000..c50f9c8
--- /dev/null
+++ b/crypto/ecc.c
@@ -0,0 +1,1038 @@
+/*
+ * Copyright (c) 2013, Kenneth MacKay
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * 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
+ * HOLDER 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 
+#include 
+#include 
+#include 
+
+#include "ecc.h"
+#include "ecc_curve_defs.h"
+
+#define MAX_TRIES 16
+
+typedef struct {
+   u64 m_low;
+   u64 m_high;
+} uint128_t;
+
+static inline const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
+{
+   switch (curve_id) {
+   case ECC_CURVE_NIST_P192: return &nist_p192;
+   case ECC_CURVE_NIST_P256: return &nist_p256;
+   default: return NULL;
+   }
+}
+
+static u64 *ecc_alloc_digits_space(unsigned int ndigits)
+{
+   size_t len = ndigits * sizeof(u64);
+
+   if (!len)
+   return NULL;
+
+   return kmalloc(len, GFP_KERNEL);
+}
+
+static void ecc_free_digits_space(u64 *space)
+{
+   kzfree(space);
+}
+
+static struct ecc_point *ecc_alloc_point(unsigned int ndigits)
+{
+   struct ecc_point *p = kmalloc(sizeof(*p), GFP_KERNEL);
+
+   if (!p)
+   return NULL;
+
+   p->x = ecc_alloc_digits_space(ndigits);
+   if (!p->x)
+   goto err_alloc_x;
+
+   p->y = ecc_alloc_digits_space(ndigits);
+   if (!p->y)
+   goto err_alloc_y;
+
+   p->ndigits = ndigits;
+
+   return p;
+
+err_alloc_y:
+   ecc_free_digits_space(p->x);
+err_alloc_x:
+   kfree(p);
+   return NULL;
+}
+
+static void ecc_free_point(struct ecc_point *p)
+{
+   if (!p)
+   return;
+
+   kzfree(p->x);
+   kzfree(p->y);
+   kzfree(p);
+}
+
+static void vli_clear(u64 *vli, unsigned int ndigits)
+{
+   int i;
+
+   for (i = 0; i < ndigits; i++)
+   vli[i] = 0;
+}
+
+/* Returns true i

[PATCH 2/3 v4] crypto: kpp - Add DH software implementation

2016-05-05 Thread Salvatore Benedetto
 * Implement MPI based Diffie-Hellman under kpp API
 * Test provided uses data generad by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |   8 ++
 crypto/Makefile |   2 +
 crypto/dh.c | 224 
 crypto/testmgr.c| 157 
 crypto/testmgr.h| 208 
 include/crypto/dh.h |  23 ++
 6 files changed, 622 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 include/crypto/dh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 31bf962..89db25c 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -110,6 +110,14 @@ config CRYPTO_RSA
help
  Generic implementation of the RSA public key algorithm.
 
+config CRYPTO_DH
+   tristate "Diffie-Hellman algorithm"
+   select CRYPTO_KPP
+   select MPILIB
+   help
+ Generic implementation of the Diffie-Hellman algorithm.
+
+
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 5b60890..101f8fd 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -32,6 +32,8 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
+obj-$(CONFIG_CRYPTO_DH) += dh.o
+
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
 clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
diff --git a/crypto/dh.c b/crypto/dh.c
new file mode 100644
index 000..06e4805
--- /dev/null
+++ b/crypto/dh.c
@@ -0,0 +1,224 @@
+/*  Diffie-Hellman Key Agreement Method [RFC2631]
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+
+struct dh_ctx {
+   MPI p;
+   MPI g;
+   MPI xa;
+};
+
+static void dh_free_ctx(struct dh_ctx *ctx)
+{
+   mpi_free(ctx->p);
+   mpi_free(ctx->g);
+   mpi_free(ctx->xa);
+   ctx->p = NULL;
+   ctx->g = NULL;
+   ctx->xa = NULL;
+}
+
+/*
+ * Public key generation function [RFC2631 sec 2.1.1]
+ * ya = g^xa mod p;
+ */
+static int _generate_public_key(const struct dh_ctx *ctx, MPI ya)
+{
+   /* ya = g^xa mod p */
+   return mpi_powm(ya, ctx->g, ctx->xa, ctx->p);
+}
+
+/*
+ * ZZ generation function [RFC2631 sec 2.1.1]
+ * ZZ = yb^xa mod p;
+ */
+static int _compute_shared_secret(const struct dh_ctx *ctx, MPI yb,
+ MPI zz)
+{
+   /* ZZ = yb^xa mod p */
+   return mpi_powm(zz, yb, ctx->xa, ctx->p);
+}
+
+static inline struct dh_ctx *dh_get_ctx(struct crypto_kpp *tfm)
+{
+   return kpp_tfm_ctx(tfm);
+}
+
+static int dh_check_params_length(unsigned int p_len)
+{
+   return (p_len < 1536) ? -EINVAL : 0;
+}
+
+static int dh_set_params(struct crypto_kpp *tfm, void *buffer,
+unsigned int len)
+{
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+   struct dh_params *params = (struct dh_params *)buffer;
+
+   if (unlikely(!buffer || !len))
+   return -EINVAL;
+
+   if (unlikely(!params->p || !params->g))
+   return -EINVAL;
+
+   if (dh_check_params_length(params->p_size << 3))
+   return -EINVAL;
+
+   ctx->p = mpi_read_raw_data(params->p, params->p_size);
+   if (!ctx->p)
+   return -EINVAL;
+
+   ctx->g = mpi_read_raw_data(params->g, params->g_size);
+   if (!ctx->g) {
+   mpi_free(ctx->p);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int dh_set_secret(struct crypto_kpp *tfm, void *buffer,
+unsigned int len)
+{
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+
+   if (unlikely(!buffer || !len))
+   return -EINVAL;
+
+   ctx->xa = mpi_read_raw_data(buffer, len);
+
+   if (!ctx->xa)
+   return -EINVAL;
+
+   return 0;
+}
+
+static int dh_generate_public_key(struct kpp_request *req)
+{
+   struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+   const struct dh_ctx *ctx = dh_get_ctx(tfm);
+   MPI ya = mpi_alloc(0);
+   int ret = 0;
+   int sign;
+
+   if (!ya)
+   return -ENOMEM;
+
+   if (unlikely(!ctx->p || !ctx->g || !ctx->xa)) {
+   ret = -EINVAL;
+   goto err_free_ya;
+   }
+   ret = _generate_public_key(ctx, ya);
+   if (ret)
+   goto err_free_ya;
+
+   ret = mpi_write_to_s

[PATCH 1/3 v4] crypto: Key-agreement Protocol Primitives API (KPP)

2016-05-05 Thread Salvatore Benedetto
Add key-agreement protocol primitives (kpp) API which allows to
implement primitives required by protocols such as DH and ECDH.
The API is composed mainly by the following functions
 * set_params() - It allows the user to set the parameters known to
   both parties involved in the key-agreement session
 * set_secret() - It allows the user to set his secret, also
   referred to as his private key
 * generate_public_key() - It generates the public key to be sent to
   the other counterpart involved in the key-agreement session. The
   function has to be called after set_params() and set_secret()
 * generate_secret() - It generates the shared secret for the session

Other functions such as init() and exit() are provided for allowing
cryptographic hardware to be inizialized properly before use

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |  10 ++
 crypto/Makefile |   1 +
 crypto/crypto_user.c|  20 +++
 crypto/kpp.c| 123 +++
 include/crypto/internal/kpp.h   |  64 
 include/crypto/kpp.h| 333 
 include/linux/crypto.h  |   1 +
 include/uapi/linux/cryptouser.h |   5 +
 8 files changed, 557 insertions(+)
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 93a1fdc..31bf962 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -93,6 +93,15 @@ config CRYPTO_AKCIPHER
select CRYPTO_AKCIPHER2
select CRYPTO_ALGAPI
 
+config CRYPTO_KPP2
+   tristate
+   select CRYPTO_ALGAPI2
+
+config CRYPTO_KPP
+   tristate
+   select CRYPTO_ALGAPI
+   select CRYPTO_KPP2
+
 config CRYPTO_RSA
tristate "RSA algorithm"
select CRYPTO_AKCIPHER
@@ -114,6 +123,7 @@ config CRYPTO_MANAGER2
select CRYPTO_HASH2
select CRYPTO_BLKCIPHER2
select CRYPTO_AKCIPHER2
+   select CRYPTO_KPP2
 
 config CRYPTO_USER
tristate "Userspace cryptographic algorithm configuration"
diff --git a/crypto/Makefile b/crypto/Makefile
index 4f4ef7e..5b60890 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -30,6 +30,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
+obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 43fe85f..d28513fb 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "internal.h"
 
@@ -126,6 +127,21 @@ nla_put_failure:
return -EMSGSIZE;
 }
 
+static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   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)
 {
@@ -176,6 +192,10 @@ static int crypto_report_one(struct crypto_alg *alg,
goto nla_put_failure;
 
break;
+   case CRYPTO_ALG_TYPE_KPP:
+   if (crypto_report_kpp(skb, alg))
+   goto nla_put_failure;
+   break;
}
 
 out:
diff --git a/crypto/kpp.c b/crypto/kpp.c
new file mode 100644
index 000..d36ce05
--- /dev/null
+++ b/crypto/kpp.c
@@ -0,0 +1,123 @@
+/*
+ * Key-agreement Protocol Primitives (KPP)
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "internal.h"
+
+#ifdef CONFIG_NET
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+st

[PATCH 0/3 v4] Key-agreement Protocol Primitives (KPP) API

2016-05-05 Thread Salvatore Benedetto
Hi Herb,

the following patchset introduces a new API for abstracting key-agreement
protocols such as DH and ECDH. It provides the primitives required for 
implementing
the protocol, thus the name KPP (Key-agreement Protocol Primitives).

Regards,
Salvatore

Changes from v1:
 * Change check in dh_check_params_length based on Stephan review

Changed from v2:
 * Add support for ECDH (curve P192 and P256). I reused the ecc module
   already present in net/bluetooth and extended it in order to select
   different curves at runtime. Code for P192 was taken from tinycrypt.

Changed from v3:
 * Move curve ID definition to public header ecdh.h as users need to
   have access to those ids when selecting the curve

Salvatore Benedetto (3):
  crypto: Key-agreement Protocol Primitives API (KPP)
  crypto: kpp - Add DH software implementation
  crypto: kpp - Add ECDH software support

 crypto/Kconfig  |   23 +
 crypto/Makefile |6 +
 crypto/crypto_user.c|   20 +
 crypto/dh.c |  224 +
 crypto/ecc.c| 1037 +++
 crypto/ecc.h|   74 +++
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  171 +++
 crypto/kpp.c|  123 +
 crypto/testmgr.c|  275 +++
 crypto/testmgr.h|  281 +++
 include/crypto/dh.h |   23 +
 include/crypto/ecdh.h   |   20 +
 include/crypto/internal/kpp.h   |   64 +++
 include/crypto/kpp.h|  333 +
 include/linux/crypto.h  |1 +
 include/uapi/linux/cryptouser.h |5 +
 17 files changed, 2737 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/dh.h
 create mode 100644 include/crypto/ecdh.h
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

-- 
1.9.1

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


[PATCH 1/3] crypto: Key-agreement Protocol Primitives API (KPP)

2016-05-03 Thread Salvatore Benedetto
Add key-agreement protocol primitives (kpp) API which allows to
implement primitives required by protocols such as DH and ECDH.
The API is composed mainly by the following functions
 * set_params() - It allows the user to set the parameters known to
   both parties involved in the key-agreement session
 * set_secret() - It allows the user to set his secret, also
   referred to as his private key
 * generate_public_key() - It generates the public key to be sent to
   the other counterpart involved in the key-agreement session. The
   function has to be called after set_params() and set_secret()
 * generate_secret() - It generates the shared secret for the session

Other functions such as init() and exit() are provided for allowing
cryptographic hardware to be inizialized properly before use

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |  10 ++
 crypto/Makefile |   1 +
 crypto/crypto_user.c|  20 +++
 crypto/kpp.c| 123 +++
 include/crypto/internal/kpp.h   |  64 
 include/crypto/kpp.h| 333 
 include/linux/crypto.h  |   1 +
 include/uapi/linux/cryptouser.h |   5 +
 8 files changed, 557 insertions(+)
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 93a1fdc..31bf962 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -93,6 +93,15 @@ config CRYPTO_AKCIPHER
select CRYPTO_AKCIPHER2
select CRYPTO_ALGAPI
 
+config CRYPTO_KPP2
+   tristate
+   select CRYPTO_ALGAPI2
+
+config CRYPTO_KPP
+   tristate
+   select CRYPTO_ALGAPI
+   select CRYPTO_KPP2
+
 config CRYPTO_RSA
tristate "RSA algorithm"
select CRYPTO_AKCIPHER
@@ -114,6 +123,7 @@ config CRYPTO_MANAGER2
select CRYPTO_HASH2
select CRYPTO_BLKCIPHER2
select CRYPTO_AKCIPHER2
+   select CRYPTO_KPP2
 
 config CRYPTO_USER
tristate "Userspace cryptographic algorithm configuration"
diff --git a/crypto/Makefile b/crypto/Makefile
index 4f4ef7e..5b60890 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -30,6 +30,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
+obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 43fe85f..d28513fb 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "internal.h"
 
@@ -126,6 +127,21 @@ nla_put_failure:
return -EMSGSIZE;
 }
 
+static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   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)
 {
@@ -176,6 +192,10 @@ static int crypto_report_one(struct crypto_alg *alg,
goto nla_put_failure;
 
break;
+   case CRYPTO_ALG_TYPE_KPP:
+   if (crypto_report_kpp(skb, alg))
+   goto nla_put_failure;
+   break;
}
 
 out:
diff --git a/crypto/kpp.c b/crypto/kpp.c
new file mode 100644
index 000..d36ce05
--- /dev/null
+++ b/crypto/kpp.c
@@ -0,0 +1,123 @@
+/*
+ * Key-agreement Protocol Primitives (KPP)
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "internal.h"
+
+#ifdef CONFIG_NET
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+st

[PATCH 2/3] crypto: kpp - Add DH software implementation

2016-05-03 Thread Salvatore Benedetto
 * Implement MPI based Diffie-Hellman under kpp API
 * Test provided uses data generad by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |   8 ++
 crypto/Makefile |   2 +
 crypto/dh.c | 224 
 crypto/testmgr.c| 157 
 crypto/testmgr.h| 208 
 include/crypto/dh.h |  23 ++
 6 files changed, 622 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 include/crypto/dh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 31bf962..89db25c 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -110,6 +110,14 @@ config CRYPTO_RSA
help
  Generic implementation of the RSA public key algorithm.
 
+config CRYPTO_DH
+   tristate "Diffie-Hellman algorithm"
+   select CRYPTO_KPP
+   select MPILIB
+   help
+ Generic implementation of the Diffie-Hellman algorithm.
+
+
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 5b60890..101f8fd 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -32,6 +32,8 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
+obj-$(CONFIG_CRYPTO_DH) += dh.o
+
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
 clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
diff --git a/crypto/dh.c b/crypto/dh.c
new file mode 100644
index 000..06e4805
--- /dev/null
+++ b/crypto/dh.c
@@ -0,0 +1,224 @@
+/*  Diffie-Hellman Key Agreement Method [RFC2631]
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+
+struct dh_ctx {
+   MPI p;
+   MPI g;
+   MPI xa;
+};
+
+static void dh_free_ctx(struct dh_ctx *ctx)
+{
+   mpi_free(ctx->p);
+   mpi_free(ctx->g);
+   mpi_free(ctx->xa);
+   ctx->p = NULL;
+   ctx->g = NULL;
+   ctx->xa = NULL;
+}
+
+/*
+ * Public key generation function [RFC2631 sec 2.1.1]
+ * ya = g^xa mod p;
+ */
+static int _generate_public_key(const struct dh_ctx *ctx, MPI ya)
+{
+   /* ya = g^xa mod p */
+   return mpi_powm(ya, ctx->g, ctx->xa, ctx->p);
+}
+
+/*
+ * ZZ generation function [RFC2631 sec 2.1.1]
+ * ZZ = yb^xa mod p;
+ */
+static int _compute_shared_secret(const struct dh_ctx *ctx, MPI yb,
+ MPI zz)
+{
+   /* ZZ = yb^xa mod p */
+   return mpi_powm(zz, yb, ctx->xa, ctx->p);
+}
+
+static inline struct dh_ctx *dh_get_ctx(struct crypto_kpp *tfm)
+{
+   return kpp_tfm_ctx(tfm);
+}
+
+static int dh_check_params_length(unsigned int p_len)
+{
+   return (p_len < 1536) ? -EINVAL : 0;
+}
+
+static int dh_set_params(struct crypto_kpp *tfm, void *buffer,
+unsigned int len)
+{
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+   struct dh_params *params = (struct dh_params *)buffer;
+
+   if (unlikely(!buffer || !len))
+   return -EINVAL;
+
+   if (unlikely(!params->p || !params->g))
+   return -EINVAL;
+
+   if (dh_check_params_length(params->p_size << 3))
+   return -EINVAL;
+
+   ctx->p = mpi_read_raw_data(params->p, params->p_size);
+   if (!ctx->p)
+   return -EINVAL;
+
+   ctx->g = mpi_read_raw_data(params->g, params->g_size);
+   if (!ctx->g) {
+   mpi_free(ctx->p);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int dh_set_secret(struct crypto_kpp *tfm, void *buffer,
+unsigned int len)
+{
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+
+   if (unlikely(!buffer || !len))
+   return -EINVAL;
+
+   ctx->xa = mpi_read_raw_data(buffer, len);
+
+   if (!ctx->xa)
+   return -EINVAL;
+
+   return 0;
+}
+
+static int dh_generate_public_key(struct kpp_request *req)
+{
+   struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+   const struct dh_ctx *ctx = dh_get_ctx(tfm);
+   MPI ya = mpi_alloc(0);
+   int ret = 0;
+   int sign;
+
+   if (!ya)
+   return -ENOMEM;
+
+   if (unlikely(!ctx->p || !ctx->g || !ctx->xa)) {
+   ret = -EINVAL;
+   goto err_free_ya;
+   }
+   ret = _generate_public_key(ctx, ya);
+   if (ret)
+   goto err_free_ya;
+
+   ret = mpi_write_to_s

[PATCH 3/3] crypto: kpp - Add ECDH software support

2016-05-03 Thread Salvatore Benedetto
 * Implement ECDH under kpp API
 * Provide ECC software support for curve P-192 and
   P-256.
 * Add kpp test for ECDH with data generated by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |5 +
 crypto/Makefile |3 +
 crypto/ecc.c| 1037 +++
 crypto/ecc.h|   74 
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  171 
 crypto/testmgr.c|  136 ++-
 crypto/testmgr.h|   73 
 include/crypto/ecdh.h   |   20 +
 9 files changed, 1567 insertions(+), 9 deletions(-)
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 include/crypto/ecdh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 89db25c..08a1a3b 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -117,6 +117,11 @@ config CRYPTO_DH
help
  Generic implementation of the Diffie-Hellman algorithm.
 
+config CRYPTO_ECDH
+   tristate "ECDH algorithm"
+   select CRYTPO_KPP
+   help
+ Generic implementation of the ECDH algorithm
 
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
diff --git a/crypto/Makefile b/crypto/Makefile
index 101f8fd..ba03079 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -33,6 +33,9 @@ obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
 obj-$(CONFIG_CRYPTO_DH) += dh.o
+ecdh_generic-y := ecc.o
+ecdh_generic-y += ecdh.o
+obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/ecc.c b/crypto/ecc.c
new file mode 100644
index 000..ec5b378
--- /dev/null
+++ b/crypto/ecc.c
@@ -0,0 +1,1037 @@
+/*
+ * Copyright (c) 2013, Kenneth MacKay
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * 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
+ * HOLDER 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 
+#include 
+#include 
+
+#include "ecc.h"
+#include "ecc_curve_defs.h"
+
+#define MAX_TRIES 16
+
+typedef struct {
+   u64 m_low;
+   u64 m_high;
+} uint128_t;
+
+static inline const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
+{
+   switch (curve_id) {
+   case ECC_CURVE_NIST_P192: return &nist_p192;
+   case ECC_CURVE_NIST_P256: return &nist_p256;
+   default: return NULL;
+   }
+}
+
+static u64 *ecc_alloc_digits_space(unsigned int ndigits)
+{
+   size_t len = ndigits * sizeof(u64);
+
+   if (!len)
+   return NULL;
+
+   return kmalloc(len, GFP_KERNEL);
+}
+
+static void ecc_free_digits_space(u64 *space)
+{
+   kzfree(space);
+}
+
+static struct ecc_point *ecc_alloc_point(unsigned int ndigits)
+{
+   struct ecc_point *p = kmalloc(sizeof(*p), GFP_KERNEL);
+
+   if (!p)
+   return NULL;
+
+   p->x = ecc_alloc_digits_space(ndigits);
+   if (!p->x)
+   goto err_alloc_x;
+
+   p->y = ecc_alloc_digits_space(ndigits);
+   if (!p->y)
+   goto err_alloc_y;
+
+   p->ndigits = ndigits;
+
+   return p;
+
+err_alloc_y:
+   ecc_free_digits_space(p->x);
+err_alloc_x:
+   kfree(p);
+   return NULL;
+}
+
+static void ecc_free_point(struct ecc_point *p)
+{
+   if (!p)
+   return;
+
+   kzfree(p->x);
+   kzfree(p->y);
+   kzfree(p);
+}
+
+static void vli_clear(u64 *vli, unsigned int ndigits)
+{
+   int i;
+
+   for (i = 0; i < ndigits; i++)
+   vli[i] = 0;
+}
+
+/* Returns true if vli ==

[PATCH 0/3 v3] Key-agreement Protocol Primitives (KPP) API

2016-05-03 Thread Salvatore Benedetto
Hi Herb,

the following patchset introduces a new API for abstracting key-agreement
protocols such as DH and ECDH. It provides the primitives required for 
implementing
the protocol, thus the name KPP (Key-agreement Protocol Primitives).

Regards,
Salvatore

Changes from v1:
 * Change check in dh_check_params_length based on Stephan review

Changed from v2:
 * Add support for ECDH (curve P192 and P256). I reused the ecc module
   already present in net/bluetooth and extended it in order to select
   different curves at runtime. Code for P192 was taken from tinycrypt.

Salvatore Benedetto (3):
  crypto: Key-agreement Protocol Primitives API (KPP)
  crypto: kpp - Add DH software implementation
  crypto: kpp - Add ECDH software support

 crypto/Kconfig  |   23 +
 crypto/Makefile |6 +
 crypto/crypto_user.c|   20 +
 crypto/dh.c |  224 +
 crypto/ecc.c| 1037 +++
 crypto/ecc.h|   74 +++
 crypto/ecc_curve_defs.h |   57 +++
 crypto/ecdh.c   |  171 +++
 crypto/kpp.c|  123 +
 crypto/testmgr.c|  275 +++
 crypto/testmgr.h|  281 +++
 include/crypto/dh.h |   23 +
 include/crypto/ecdh.h   |   20 +
 include/crypto/internal/kpp.h   |   64 +++
 include/crypto/kpp.h|  333 +
 include/linux/crypto.h  |1 +
 include/uapi/linux/cryptouser.h |5 +
 17 files changed, 2737 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 crypto/ecc.c
 create mode 100644 crypto/ecc.h
 create mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 crypto/ecdh.c
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/dh.h
 create mode 100644 include/crypto/ecdh.h
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

-- 
1.9.1

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


[PATCH 2/2 v2] crypto: kpp - Add DH software implementation

2016-04-15 Thread Salvatore Benedetto
 * Implement MPI based Diffie-Hellman under kpp API
 * Test provided uses data generad by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |   8 ++
 crypto/Makefile |   2 +
 crypto/dh.c | 224 
 crypto/testmgr.c| 157 
 crypto/testmgr.h| 208 
 include/crypto/dh.h |  23 ++
 6 files changed, 622 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 include/crypto/dh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 31bf962..89db25c 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -110,6 +110,14 @@ config CRYPTO_RSA
help
  Generic implementation of the RSA public key algorithm.
 
+config CRYPTO_DH
+   tristate "Diffie-Hellman algorithm"
+   select CRYPTO_KPP
+   select MPILIB
+   help
+ Generic implementation of the Diffie-Hellman algorithm.
+
+
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 5b60890..101f8fd 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -32,6 +32,8 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
+obj-$(CONFIG_CRYPTO_DH) += dh.o
+
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
 clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
diff --git a/crypto/dh.c b/crypto/dh.c
new file mode 100644
index 000..06e4805
--- /dev/null
+++ b/crypto/dh.c
@@ -0,0 +1,224 @@
+/*  Diffie-Hellman Key Agreement Method [RFC2631]
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+
+struct dh_ctx {
+   MPI p;
+   MPI g;
+   MPI xa;
+};
+
+static void dh_free_ctx(struct dh_ctx *ctx)
+{
+   mpi_free(ctx->p);
+   mpi_free(ctx->g);
+   mpi_free(ctx->xa);
+   ctx->p = NULL;
+   ctx->g = NULL;
+   ctx->xa = NULL;
+}
+
+/*
+ * Public key generation function [RFC2631 sec 2.1.1]
+ * ya = g^xa mod p;
+ */
+static int _generate_public_key(const struct dh_ctx *ctx, MPI ya)
+{
+   /* ya = g^xa mod p */
+   return mpi_powm(ya, ctx->g, ctx->xa, ctx->p);
+}
+
+/*
+ * ZZ generation function [RFC2631 sec 2.1.1]
+ * ZZ = yb^xa mod p;
+ */
+static int _compute_shared_secret(const struct dh_ctx *ctx, MPI yb,
+ MPI zz)
+{
+   /* ZZ = yb^xa mod p */
+   return mpi_powm(zz, yb, ctx->xa, ctx->p);
+}
+
+static inline struct dh_ctx *dh_get_ctx(struct crypto_kpp *tfm)
+{
+   return kpp_tfm_ctx(tfm);
+}
+
+static int dh_check_params_length(unsigned int p_len)
+{
+   return (p_len < 1536) ? -EINVAL : 0;
+}
+
+static int dh_set_params(struct crypto_kpp *tfm, void *buffer,
+unsigned int len)
+{
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+   struct dh_params *params = (struct dh_params *)buffer;
+
+   if (unlikely(!buffer || !len))
+   return -EINVAL;
+
+   if (unlikely(!params->p || !params->g))
+   return -EINVAL;
+
+   if (dh_check_params_length(params->p_size << 3))
+   return -EINVAL;
+
+   ctx->p = mpi_read_raw_data(params->p, params->p_size);
+   if (!ctx->p)
+   return -EINVAL;
+
+   ctx->g = mpi_read_raw_data(params->g, params->g_size);
+   if (!ctx->g) {
+   mpi_free(ctx->p);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int dh_set_secret(struct crypto_kpp *tfm, void *buffer,
+unsigned int len)
+{
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+
+   if (unlikely(!buffer || !len))
+   return -EINVAL;
+
+   ctx->xa = mpi_read_raw_data(buffer, len);
+
+   if (!ctx->xa)
+   return -EINVAL;
+
+   return 0;
+}
+
+static int dh_generate_public_key(struct kpp_request *req)
+{
+   struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+   const struct dh_ctx *ctx = dh_get_ctx(tfm);
+   MPI ya = mpi_alloc(0);
+   int ret = 0;
+   int sign;
+
+   if (!ya)
+   return -ENOMEM;
+
+   if (unlikely(!ctx->p || !ctx->g || !ctx->xa)) {
+   ret = -EINVAL;
+   goto err_free_ya;
+   }
+   ret = _generate_public_key(ctx, ya);
+   if (ret)
+   goto err_free_ya;
+
+   ret = mpi_write_to_s

[PATCH 1/2 v2] crypto: Key-agreement Protocol Primitives API (KPP)

2016-04-15 Thread Salvatore Benedetto
Add key-agreement protocol primitives (kpp) API which allows to
implement primitives required by protocols such as DH and ECDH.
The API is composed mainly by the following functions
 * set_params() - It allows the user to set the parameters known to
   both parties involved in the key-agreement session
 * set_secret() - It allows the user to set his secret, also
   referred to as his private key
 * generate_public_key() - It generates the public key to be sent to
   the other counterpart involved in the key-agreement session. The
   function has to be called after set_params() and set_secret()
 * generate_secret() - It generates the shared secret for the session

Other functions such as init() and exit() are provided for allowing
cryptographic hardware to be inizialized properly before use

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |  10 ++
 crypto/Makefile |   1 +
 crypto/crypto_user.c|  20 +++
 crypto/kpp.c| 123 +++
 include/crypto/internal/kpp.h   |  64 
 include/crypto/kpp.h| 333 
 include/linux/crypto.h  |   1 +
 include/uapi/linux/cryptouser.h |   5 +
 8 files changed, 557 insertions(+)
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 93a1fdc..31bf962 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -93,6 +93,15 @@ config CRYPTO_AKCIPHER
select CRYPTO_AKCIPHER2
select CRYPTO_ALGAPI
 
+config CRYPTO_KPP2
+   tristate
+   select CRYPTO_ALGAPI2
+
+config CRYPTO_KPP
+   tristate
+   select CRYPTO_ALGAPI
+   select CRYPTO_KPP2
+
 config CRYPTO_RSA
tristate "RSA algorithm"
select CRYPTO_AKCIPHER
@@ -114,6 +123,7 @@ config CRYPTO_MANAGER2
select CRYPTO_HASH2
select CRYPTO_BLKCIPHER2
select CRYPTO_AKCIPHER2
+   select CRYPTO_KPP2
 
 config CRYPTO_USER
tristate "Userspace cryptographic algorithm configuration"
diff --git a/crypto/Makefile b/crypto/Makefile
index 4f4ef7e..5b60890 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -30,6 +30,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
+obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 43fe85f..d28513fb 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "internal.h"
 
@@ -126,6 +127,21 @@ nla_put_failure:
return -EMSGSIZE;
 }
 
+static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   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)
 {
@@ -176,6 +192,10 @@ static int crypto_report_one(struct crypto_alg *alg,
goto nla_put_failure;
 
break;
+   case CRYPTO_ALG_TYPE_KPP:
+   if (crypto_report_kpp(skb, alg))
+   goto nla_put_failure;
+   break;
}
 
 out:
diff --git a/crypto/kpp.c b/crypto/kpp.c
new file mode 100644
index 000..d36ce05
--- /dev/null
+++ b/crypto/kpp.c
@@ -0,0 +1,123 @@
+/*
+ * Key-agreement Protocol Primitives (KPP)
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "internal.h"
+
+#ifdef CONFIG_NET
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+st

[PATCH 0/2 v2] Key-agreement Protocol Primitives (KPP) API

2016-04-15 Thread Salvatore Benedetto
Hi Herb,

the following patchset introduces a new API for abstracting
key-agreement protocols such as DH and ECDH. It provides the primitives
required for implementing the protocol, thus the name KPP (Key-agreement
Protocol Primitives).

Regards,
Salvatore

Changes from v1:
 * Change check in dh_check_params_length based on Stephan review

Salvatore Benedetto (2):
  crypto: Key-agreement Protocol Primitives API (KPP)
  crypto: kpp - Add DH software implementation

 crypto/Kconfig  |  18 +++
 crypto/Makefile |   3 +
 crypto/crypto_user.c|  20 +++
 crypto/dh.c | 224 +++
 crypto/kpp.c| 123 +++
 crypto/testmgr.c| 157 +++
 crypto/testmgr.h| 208 +
 include/crypto/dh.h |  23 +++
 include/crypto/internal/kpp.h   |  64 
 include/crypto/kpp.h| 333 
 include/linux/crypto.h  |   1 +
 include/uapi/linux/cryptouser.h |   5 +
 12 files changed, 1179 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/dh.h
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

-- 
1.9.1

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


[PATCH 0/2] Key-agreement Protocol Primitives (KPP) API

2016-04-12 Thread Salvatore Benedetto
Hi Herb,

the following patchset introduces a new API for abstracting
key-agreement protocols such as DH and ECDH. It provides the primitives
required for implementing the protocol, thus the name KPP (Key-agreement
Protocol Primitives).

Regards,
Salvatore

Salvatore Benedetto (2):
  crypto: Key-agreement Protocol Primitives API (KPP)
  crypto: kpp - Add DH software implementation

 crypto/Kconfig  |  18 +++
 crypto/Makefile |   3 +
 crypto/crypto_user.c|  20 +++
 crypto/dh.c | 233 
 crypto/kpp.c| 123 +++
 crypto/testmgr.c| 157 +++
 crypto/testmgr.h| 208 +
 include/crypto/dh.h |  23 +++
 include/crypto/internal/kpp.h   |  64 
 include/crypto/kpp.h| 333 
 include/linux/crypto.h  |   1 +
 include/uapi/linux/cryptouser.h |   5 +
 12 files changed, 1188 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/dh.h
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

-- 
1.9.1

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


[PATCH 2/2] crypto: kpp - Add DH software implementation

2016-04-12 Thread Salvatore Benedetto
 * Implement MPI based Diffie-Hellman under kpp API
 * Add test with data generad by OpenSSL

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |   8 ++
 crypto/Makefile |   2 +
 crypto/dh.c | 233 
 crypto/testmgr.c| 157 +++
 crypto/testmgr.h| 208 ++
 include/crypto/dh.h |  23 ++
 6 files changed, 631 insertions(+)
 create mode 100644 crypto/dh.c
 create mode 100644 include/crypto/dh.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 31bf962..89db25c 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -110,6 +110,14 @@ config CRYPTO_RSA
help
  Generic implementation of the RSA public key algorithm.
 
+config CRYPTO_DH
+   tristate "Diffie-Hellman algorithm"
+   select CRYPTO_KPP
+   select MPILIB
+   help
+ Generic implementation of the Diffie-Hellman algorithm.
+
+
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 5b60890..101f8fd 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -32,6 +32,8 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
+obj-$(CONFIG_CRYPTO_DH) += dh.o
+
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
 clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
diff --git a/crypto/dh.c b/crypto/dh.c
new file mode 100644
index 000..b701848
--- /dev/null
+++ b/crypto/dh.c
@@ -0,0 +1,233 @@
+/*  Diffie-Hellman Key Agreement Method [RFC2631]
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+
+struct dh_ctx {
+   MPI p;
+   MPI g;
+   MPI xa;
+};
+
+static void dh_free_ctx(struct dh_ctx *ctx)
+{
+   mpi_free(ctx->p);
+   mpi_free(ctx->g);
+   mpi_free(ctx->xa);
+   ctx->p = NULL;
+   ctx->g = NULL;
+   ctx->xa = NULL;
+}
+
+/*
+ * Public key generation function [RFC2631 sec 2.1.1]
+ * ya = g^xa mod p;
+ */
+static int _generate_public_key(const struct dh_ctx *ctx, MPI ya)
+{
+   /* ya = g^xa mod p */
+   return mpi_powm(ya, ctx->g, ctx->xa, ctx->p);
+}
+
+/*
+ * ZZ generation function [RFC2631 sec 2.1.1]
+ * ZZ = yb^xa mod p;
+ */
+static int _compute_shared_secret(const struct dh_ctx *ctx, MPI yb,
+ MPI zz)
+{
+   /* ZZ = yb^xa mod p */
+   return mpi_powm(zz, yb, ctx->xa, ctx->p);
+}
+
+static inline struct dh_ctx *dh_get_ctx(struct crypto_kpp *tfm)
+{
+   return kpp_tfm_ctx(tfm);
+}
+
+static int dh_check_params_length(unsigned int p_len)
+{
+   switch (p_len) {
+   case 1536:
+   case 2048:
+   case 3072:
+   case 4096:
+   case 6144:
+   case 8192:
+   return 0;
+   }
+   return -EINVAL;
+}
+
+static int dh_set_params(struct crypto_kpp *tfm, void *buffer,
+unsigned int len)
+{
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+   struct dh_params *params = (struct dh_params *)buffer;
+
+   if (unlikely(!buffer || !len))
+   return -EINVAL;
+
+   if (unlikely(!params->p || !params->g))
+   return -EINVAL;
+
+   if (dh_check_params_length(params->p_size << 3))
+   return -EINVAL;
+
+   ctx->p = mpi_read_raw_data(params->p, params->p_size);
+   if (!ctx->p)
+   return -EINVAL;
+
+   ctx->g = mpi_read_raw_data(params->g, params->g_size);
+   if (!ctx->g) {
+   mpi_free(ctx->p);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int dh_set_secret(struct crypto_kpp *tfm, void *buffer,
+unsigned int len)
+{
+   struct dh_ctx *ctx = dh_get_ctx(tfm);
+
+   if (unlikely(!buffer || !len))
+   return -EINVAL;
+
+   ctx->xa = mpi_read_raw_data(buffer, len);
+
+   if (!ctx->xa)
+   return -EINVAL;
+
+   return 0;
+}
+
+static int dh_generate_public_key(struct kpp_request *req)
+{
+   struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+   const struct dh_ctx *ctx = dh_get_ctx(tfm);
+   MPI ya = mpi_alloc(0);
+   int ret = 0;
+   int sign;
+
+   if (!ya)
+   return -ENOMEM;
+
+   if (unlikely(!ctx->p || !ctx->g || !ctx->xa)) {
+   ret = -EINVAL;
+   goto err_fre

[PATCH 1/2] crypto: Key-agreement Protocol Primitives API (KPP)

2016-04-12 Thread Salvatore Benedetto
Add key-agreement protocol primitives (kpp) API which allows to
implement primitives required by protocols such as DH and ECDH.
The API is composed mainly by the following functions
 * set_params() - It allows the user to set the parameters known to
   both parties involved in the key-agreement session
 * set_secret() - It allows the user to set his secret, also
   referred to as his private key
 * generate_public_key() - It generates the public key to be sent to
   the other counterpart involved in the key-agreement session. The
   function has to be called after set_params() and set_secret()
 * generate_secret() - It generates the shared secret for the session

Other functions such as init() and exit() are provided for allowing
cryptographic hardware to be inizialized properly before use

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig  |  10 ++
 crypto/Makefile |   1 +
 crypto/crypto_user.c|  20 +++
 crypto/kpp.c| 123 +++
 include/crypto/internal/kpp.h   |  64 
 include/crypto/kpp.h| 333 
 include/linux/crypto.h  |   1 +
 include/uapi/linux/cryptouser.h |   5 +
 8 files changed, 557 insertions(+)
 create mode 100644 crypto/kpp.c
 create mode 100644 include/crypto/internal/kpp.h
 create mode 100644 include/crypto/kpp.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 93a1fdc..31bf962 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -93,6 +93,15 @@ config CRYPTO_AKCIPHER
select CRYPTO_AKCIPHER2
select CRYPTO_ALGAPI
 
+config CRYPTO_KPP2
+   tristate
+   select CRYPTO_ALGAPI2
+
+config CRYPTO_KPP
+   tristate
+   select CRYPTO_ALGAPI
+   select CRYPTO_KPP2
+
 config CRYPTO_RSA
tristate "RSA algorithm"
select CRYPTO_AKCIPHER
@@ -114,6 +123,7 @@ config CRYPTO_MANAGER2
select CRYPTO_HASH2
select CRYPTO_BLKCIPHER2
select CRYPTO_AKCIPHER2
+   select CRYPTO_KPP2
 
 config CRYPTO_USER
tristate "Userspace cryptographic algorithm configuration"
diff --git a/crypto/Makefile b/crypto/Makefile
index 4f4ef7e..5b60890 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -30,6 +30,7 @@ crypto_hash-y += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
+obj-$(CONFIG_CRYPTO_KPP2) += kpp.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 43fe85f..d28513fb 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "internal.h"
 
@@ -126,6 +127,21 @@ nla_put_failure:
return -EMSGSIZE;
 }
 
+static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   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)
 {
@@ -176,6 +192,10 @@ static int crypto_report_one(struct crypto_alg *alg,
goto nla_put_failure;
 
break;
+   case CRYPTO_ALG_TYPE_KPP:
+   if (crypto_report_kpp(skb, alg))
+   goto nla_put_failure;
+   break;
}
 
 out:
diff --git a/crypto/kpp.c b/crypto/kpp.c
new file mode 100644
index 000..d36ce05
--- /dev/null
+++ b/crypto/kpp.c
@@ -0,0 +1,123 @@
+/*
+ * Key-agreement Protocol Primitives (KPP)
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "internal.h"
+
+#ifdef CONFIG_NET
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   struct crypto_report_kpp rkpp;
+
+   strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
+
+   if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
+   sizeof(struct crypto_report_kpp), &rkpp))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -EMSGSIZE;
+}
+#else
+static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+   return -ENOSYS;
+}
+#endif
+
+st

[PATCH V2] crypto: implement DH primitives under akcipher API

2016-03-03 Thread Salvatore Benedetto
Implement Diffie-Hellman primitives required by the scheme under the
akcipher API. Here is how it works.
1) Call set_pub_key() by passing DH parameters (p,g) in PKCS3 format
2) Call set_priv_key() to set your own private key (xa) in raw format
3) Call decrypt() without passing any data as input to get back the
   public part which will be computed as g^xa mod p
4) Call encrypt() by passing the counter part public key (yb) in raw format
   as input to get back the shared secret calculated as zz = yb^xa mod p

A test is included in the patch. Test vector has been generated with
openssl

Signed-off-by: Salvatore Benedetto 
---

Changes in V2:
 * Use dh_get_params where required
 * Use key lengths defined in RFC3526
 * Set fips_allowed=1 for the test

 crypto/Kconfig|   8 ++
 crypto/Makefile   |   7 ++
 crypto/dh.c   | 264 ++
 crypto/pkcs3.asn1 |   5 ++
 crypto/tcrypt.c   |   4 +
 crypto/testmgr.c  | 141 +++--
 crypto/testmgr.h  | 208 +-
 7 files changed, 628 insertions(+), 9 deletions(-)
 create mode 100644 crypto/dh.c
 create mode 100644 crypto/pkcs3.asn1

diff --git a/crypto/Kconfig b/crypto/Kconfig
index f6bfdda..fd5b78d 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -101,6 +101,14 @@ config CRYPTO_RSA
help
  Generic implementation of the RSA public key algorithm.
 
+config CRYPTO_DH
+   tristate "Diffie-Hellman algorithm"
+   select CRYPTO_AKCIPHER
+   select MPILIB
+   select ASN1
+   help
+ Generic implementation of the Diffie-Hellman algorithm.
+
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 4f4ef7e..ee73489 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -31,6 +31,13 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 
+$(obj)/pkcs3-asn1.o: $(obj)/pkcs3-asn1.c $(obj)/pkcs3-asn1.h
+clean-files += pkcs3-asn1.c pkcs3-asn1.h
+
+dh_generic-y := pkcs3-asn1.o
+dh_generic-y += dh.o
+obj-$(CONFIG_CRYPTO_DH) += dh_generic.o
+
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
 clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
diff --git a/crypto/dh.c b/crypto/dh.c
new file mode 100644
index 000..29243ee
--- /dev/null
+++ b/crypto/dh.c
@@ -0,0 +1,264 @@
+/*  Diffie-Hellman Key Agreement Method [RFC2631]
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include "pkcs3-asn1.h"
+
+struct dh_params {
+   MPI p;
+   MPI g;
+   MPI xa;
+};
+
+int dh_get_g(void *context, size_t hdrlen, unsigned char tag, const void 
*value,
+size_t vlen)
+{
+   struct dh_params *params = context;
+
+   params->g = mpi_read_raw_data(value, vlen);
+
+   if (!params->g)
+   return -ENOMEM;
+
+   return 0;
+}
+
+int dh_get_p(void *context, size_t hdrlen, unsigned char tag, const void 
*value,
+size_t vlen)
+{
+   struct dh_params *params = context;
+
+   params->p = mpi_read_raw_data(value, vlen);
+
+   if (!params->p)
+   return -ENOMEM;
+
+   return 0;
+}
+
+static int dh_parse_params(struct dh_params *params, const void *key,
+  unsigned int keylen)
+{
+   int ret;
+
+   mpi_free(params->p);
+   mpi_free(params->g);
+
+   ret = asn1_ber_decoder(&pkcs3_decoder, params, key, keylen);
+
+   return ret;
+}
+
+static void dh_free_params(struct dh_params *params)
+{
+   mpi_free(params->p);
+   mpi_free(params->g);
+   mpi_free(params->xa);
+   params->p = NULL;
+   params->g = NULL;
+   params->xa = NULL;
+}
+
+/*
+ * Public key generation function [RFC2631 sec 2.1.1]
+ * ya = g^xa mod p;
+ */
+static int _generate_public_key(const struct dh_params *params, MPI ya)
+{
+   /* ya = g^xa mod p */
+   return mpi_powm(ya, params->g, params->xa, params->p);
+}
+
+/*
+ * ZZ generation function [RFC2631 sec 2.1.1]
+ * ZZ = yb^xa mod p;
+ */
+static int _compute_shared_secret(const struct dh_params *params, MPI yb,
+ MPI zz)
+{
+   /* ZZ = yb^xa mod p */
+   return mpi_powm(zz, yb, params->xa, params->p);
+}
+
+static inline struct dh_params *dh_get_params(struct crypto_akcipher *tfm)
+{
+   return akcipher_tfm_ctx(tfm);
+}
+
+static int dh_generate_public_key(struct akcip

Re: [PATCH] crypto: implement DH primitives under akcipher API

2016-03-02 Thread Salvatore Benedetto
On Tue, Mar 01, 2016 at 12:17:15PM +0100, Stephan Mueller wrote:

Hi Stephan,

> Am Dienstag, 1. März 2016, 11:08:34 schrieb Salvatore Benedetto:
> 
> Hi Salvatore,
> 
> > > > +static int dh_check_params_length(unsigned int p_len)
> > > > +{
> > > > +   switch (p_len) {
> > > > +   case 768:
> > > > +   case 1024:
> > > > +   case 1536:
> > > > +   case 2048:
> > > > +   case 3072:
> > > > +   case 4096:
> > > > +   return 0;
> > > > +   }
> > > > +   return -EINVAL;
> > > > +}
> > > 
> > > What is the reason for restricting the size to 4096?
> > 
> > Honestly no reason.
> > Could not find restrictions in the spec about the params length.
> 
> I am just wondering because other DH impls allow longer sizes.
> 
> And besides, I would like to disallow all < 2048 right from the start.
>

Hmm.. What range would you suggest?

I just thought that having the same range we support with RSA would be OK for 
now.

> > > > +
> > > > +static int dh_no_op(struct akcipher_request *req)
> > > > +{
> > > > +   return -ENOPROTOOPT;
> > > > +}
> > > > +
> > > > +static int dh_set_priv_key(struct crypto_akcipher *tfm, const void
> > > > *key,
> > > > +  unsigned int keylen)
> > > > +{
> > > > +   struct dh_params *params = akcipher_tfm_ctx(tfm);
> > > 
> > > dh_get_params?
> > 
> > You mean adding a helper function? OK.
> 
> Not adding, but using your helper function -- why do you have it there in the 
> first place? :-)
>

True. I actually use it in dh_generate_public_key and
dh_compute_shared_secret. I'll fix that, thanks.

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


Re: [PATCH] crypto: implement DH primitives under akcipher API

2016-03-02 Thread Salvatore Benedetto
On Tue, Mar 01, 2016 at 12:25:33PM -0800, Marcel Holtmann wrote:

Hi Marcel,

> Hi Salvatore,
> 
> > Implement Diffie-Hellman primitives required by the scheme under the
> > akcipher API. Here is how it works.
> > 1) Call set_pub_key() by passing DH parameters (p,g) in PKCS3 format
> > 2) Call set_priv_key() to set your own private key (xa) in raw format
> 
> this combination seems odd since it is normally the remote public key and the 
> local private key. Generally the public key and private key are both remote 
> ones.

I'm not sure I understand what you mean here. Usually the public key is
remote and the private key is local. How can the private key be remote?

> 
> For using PKCS3 format is this standardized somewhere? I don't think it is a 
> good idea to invent new ones here.

PKCS3 is the format used by openssl for genating DH params, that's why I
used it.

> 
> In addition, how would this work for ECDH?

Don't know. There is not even ECC support right now.

> 
> > 3) Call decrypt() without passing any data as input to get back the
> >   public part which will be computed as g^xa mod p
> > 4) Call encrypt() by passing the counter part public key (yb) in raw format
> >   as input to get back the shared secret calculated as zz = yb^xa mod p
> > 
> > A test is included in the patch. Test vector has been generated with
> > openssl
> > 
> > Signed-off-by: Salvatore Benedetto 
> > ---
> > crypto/Kconfig|   8 ++
> > crypto/Makefile   |   7 ++
> > crypto/dh.c   | 264 
> > ++
> > crypto/pkcs3.asn1 |   5 ++
> > crypto/tcrypt.c   |   4 +
> > crypto/testmgr.c  | 140 +++--
> > crypto/testmgr.h  | 208 +-
> > 7 files changed, 627 insertions(+), 9 deletions(-)
> > create mode 100644 crypto/dh.c
> > create mode 100644 crypto/pkcs3.asn1
> > 
> > diff --git a/crypto/Kconfig b/crypto/Kconfig
> > index f6bfdda..fd5b78d 100644
> > --- a/crypto/Kconfig
> > +++ b/crypto/Kconfig
> > @@ -101,6 +101,14 @@ config CRYPTO_RSA
> > help
> >   Generic implementation of the RSA public key algorithm.
> > 
> > +config CRYPTO_DH
> > +   tristate "Diffie-Hellman algorithm"
> > +   select CRYPTO_AKCIPHER
> > +   select MPILIB
> > +   select ASN1
> 
> I really wonder that depending on ASN1 is a good idea here. As mentioned 
> above ECDH would make sense to actually have supported from the beginning. 
> The Bluetooth subsystem could be then converted to utilize in kernel ECC key 
> generation and ECDH shared secret computation. It would be good to show this 
> is truly generic DH.
> 

This is an RFC. I understand it is not the best approach, but
the idea behind was to try to reuse the akcipher for DH.

Thanks for your comments.

Regards,
Salvatore

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


Re: [PATCH] crypto: implement DH primitives under akcipher API

2016-03-01 Thread Salvatore Benedetto

Hi Stephan,

thanks for reviewing.

On Mon, Feb 15, 2016 at 02:57:08PM +0100, Stephan Mueller wrote:
> Am Montag, 15. Februar 2016, 09:01:55 schrieb Salvatore Benedetto:
> 
> Hi Salvatore, Herbert,
> 
> > Implement Diffie-Hellman primitives required by the scheme under the
> > akcipher API. Here is how it works.
> > 1) Call set_pub_key() by passing DH parameters (p,g) in PKCS3 format
> > 2) Call set_priv_key() to set your own private key (xa) in raw format
> > 3) Call decrypt() without passing any data as input to get back the
> >public part which will be computed as g^xa mod p
> > 4) Call encrypt() by passing the counter part public key (yb) in raw format
> >as input to get back the shared secret calculated as zz = yb^xa mod p
> > 
> > A test is included in the patch. Test vector has been generated with
> > openssl
> 
> Herbert, as this is a raw DH operation where the shared secret must be 
> subjected to a KDF, I guess the KDF patch I provided some time ago may become 
> of interest again?
> > 
> > Signed-off-by: Salvatore Benedetto 
> > ---
> >  crypto/Kconfig|   8 ++
> >  crypto/Makefile   |   7 ++
> >  crypto/dh.c   | 264
> > ++ crypto/pkcs3.asn1 | 
> >  5 ++
> >  crypto/tcrypt.c   |   4 +
> >  crypto/testmgr.c  | 140 +++--
> >  crypto/testmgr.h  | 208 +-
> >  7 files changed, 627 insertions(+), 9 deletions(-)
> >  create mode 100644 crypto/dh.c
> >  create mode 100644 crypto/pkcs3.asn1
> > 
> > diff --git a/crypto/Kconfig b/crypto/Kconfig
> > index f6bfdda..fd5b78d 100644
> > --- a/crypto/Kconfig
> > +++ b/crypto/Kconfig
> > @@ -101,6 +101,14 @@ config CRYPTO_RSA
> > help
> >   Generic implementation of the RSA public key algorithm.
> > 
> > +config CRYPTO_DH
> > +   tristate "Diffie-Hellman algorithm"
> > +   select CRYPTO_AKCIPHER
> > +   select MPILIB
> > +   select ASN1
> > +   help
> > + Generic implementation of the Diffie-Hellman algorithm.
> > +
> >  config CRYPTO_MANAGER
> > tristate "Cryptographic algorithm manager"
> > select CRYPTO_MANAGER2
> > diff --git a/crypto/Makefile b/crypto/Makefile
> > index 4f4ef7e..ee73489 100644
> > --- a/crypto/Makefile
> > +++ b/crypto/Makefile
> > @@ -31,6 +31,13 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
> > 
> >  obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
> > 
> > +$(obj)/pkcs3-asn1.o: $(obj)/pkcs3-asn1.c $(obj)/pkcs3-asn1.h
> > +clean-files += pkcs3-asn1.c pkcs3-asn1.h
> > +
> > +dh_generic-y := pkcs3-asn1.o
> > +dh_generic-y += dh.o
> > +obj-$(CONFIG_CRYPTO_DH) += dh_generic.o
> > +
> >  $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
> >  $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
> > clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
> > diff --git a/crypto/dh.c b/crypto/dh.c
> > new file mode 100644
> > index 000..614c4f1
> > --- /dev/null
> > +++ b/crypto/dh.c
> > @@ -0,0 +1,264 @@
> > +/*  Diffie-Hellman Key Agreement Method [RFC2631]
> > + *
> > + * Copyright (c) 2016, Intel Corporation
> > + * Authors: Salvatore Benedetto 
> > + *
> > + * 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 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include "pkcs3-asn1.h"
> > +
> > +struct dh_params {
> > +   MPI p;
> > +   MPI g;
> > +   MPI xa;
> > +};
> > +
> > +int dh_get_g(void *context, size_t hdrlen, unsigned char tag, const void
> > *value, +size_t vlen)
> > +{
> > +   struct dh_params *params = context;
> > +
> > +   params->g = mpi_read_raw_data(value, vlen);
> > +
> > +   if (!params->g)
> > +   return -ENOMEM;
> > +
> > +   return 0;
> > +}
> > +
> > +int dh_get_p(void *context, size_t hdrlen, unsigned char tag, const void
> > *value, +size_t vlen)
> > +{
> > +   struct dh_params *params = context;
> > +
> > +   params->p = mpi_read_raw_data(value, vlen);
> > +
> > +   if (!params->p)
> > +   return -EN

[PATCH] crypto: implement DH primitives under akcipher API

2016-02-15 Thread Salvatore Benedetto
Implement Diffie-Hellman primitives required by the scheme under the
akcipher API. Here is how it works.
1) Call set_pub_key() by passing DH parameters (p,g) in PKCS3 format
2) Call set_priv_key() to set your own private key (xa) in raw format
3) Call decrypt() without passing any data as input to get back the
   public part which will be computed as g^xa mod p
4) Call encrypt() by passing the counter part public key (yb) in raw format
   as input to get back the shared secret calculated as zz = yb^xa mod p

A test is included in the patch. Test vector has been generated with
openssl

Signed-off-by: Salvatore Benedetto 
---
 crypto/Kconfig|   8 ++
 crypto/Makefile   |   7 ++
 crypto/dh.c   | 264 ++
 crypto/pkcs3.asn1 |   5 ++
 crypto/tcrypt.c   |   4 +
 crypto/testmgr.c  | 140 +++--
 crypto/testmgr.h  | 208 +-
 7 files changed, 627 insertions(+), 9 deletions(-)
 create mode 100644 crypto/dh.c
 create mode 100644 crypto/pkcs3.asn1

diff --git a/crypto/Kconfig b/crypto/Kconfig
index f6bfdda..fd5b78d 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -101,6 +101,14 @@ config CRYPTO_RSA
help
  Generic implementation of the RSA public key algorithm.
 
+config CRYPTO_DH
+   tristate "Diffie-Hellman algorithm"
+   select CRYPTO_AKCIPHER
+   select MPILIB
+   select ASN1
+   help
+ Generic implementation of the Diffie-Hellman algorithm.
+
 config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 4f4ef7e..ee73489 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -31,6 +31,13 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
 
+$(obj)/pkcs3-asn1.o: $(obj)/pkcs3-asn1.c $(obj)/pkcs3-asn1.h
+clean-files += pkcs3-asn1.c pkcs3-asn1.h
+
+dh_generic-y := pkcs3-asn1.o
+dh_generic-y += dh.o
+obj-$(CONFIG_CRYPTO_DH) += dh_generic.o
+
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
 clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
diff --git a/crypto/dh.c b/crypto/dh.c
new file mode 100644
index 000..614c4f1
--- /dev/null
+++ b/crypto/dh.c
@@ -0,0 +1,264 @@
+/*  Diffie-Hellman Key Agreement Method [RFC2631]
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include "pkcs3-asn1.h"
+
+struct dh_params {
+   MPI p;
+   MPI g;
+   MPI xa;
+};
+
+int dh_get_g(void *context, size_t hdrlen, unsigned char tag, const void 
*value,
+size_t vlen)
+{
+   struct dh_params *params = context;
+
+   params->g = mpi_read_raw_data(value, vlen);
+
+   if (!params->g)
+   return -ENOMEM;
+
+   return 0;
+}
+
+int dh_get_p(void *context, size_t hdrlen, unsigned char tag, const void 
*value,
+size_t vlen)
+{
+   struct dh_params *params = context;
+
+   params->p = mpi_read_raw_data(value, vlen);
+
+   if (!params->p)
+   return -ENOMEM;
+
+   return 0;
+}
+
+static int dh_parse_params(struct dh_params *params, const void *key,
+  unsigned int keylen)
+{
+   int ret;
+
+   mpi_free(params->p);
+   mpi_free(params->g);
+
+   ret = asn1_ber_decoder(&pkcs3_decoder, params, key, keylen);
+
+   return ret;
+}
+
+static void dh_free_params(struct dh_params *params)
+{
+   mpi_free(params->p);
+   mpi_free(params->g);
+   mpi_free(params->xa);
+   params->p = NULL;
+   params->g = NULL;
+   params->xa = NULL;
+}
+
+/*
+ * Public key generation function [RFC2631 sec 2.1.1]
+ * ya = g^xa mod p;
+ */
+static int _generate_public_key(const struct dh_params *params, MPI ya)
+{
+   /* ya = g^xa mod p */
+   return mpi_powm(ya, params->g, params->xa, params->p);
+}
+
+/*
+ * ZZ generation function [RFC2631 sec 2.1.1]
+ * ZZ = yb^xa mod p;
+ */
+static int _compute_shared_secret(const struct dh_params *params, MPI yb,
+ MPI zz)
+{
+   /* ZZ = yb^xa mod p */
+   return mpi_powm(zz, yb, params->xa, params->p);
+}
+
+static inline struct dh_params *dh_get_params(struct crypto_akcipher *tfm)
+{
+   return akcipher_tfm_ctx(tfm);
+}
+
+static int dh_generate_public_key(struct akcipher_request *req)
+{
+   struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+   const struct dh_params *params = dh_

[PATCH] crypto: qat - Set ctx->e to NULL in qat_rsa_exit_tfm

2016-02-09 Thread Salvatore Benedetto
Signed-off-by: Salvatore Benedetto 
---
 drivers/crypto/qat/qat_common/qat_asym_algs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c 
b/drivers/crypto/qat/qat_common/qat_asym_algs.c
index 51c594f..54e386e 100644
--- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
+++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
@@ -709,7 +709,7 @@ static void qat_rsa_exit_tfm(struct crypto_akcipher *tfm)
}
qat_crypto_put_instance(ctx->inst);
ctx->n = NULL;
-   ctx->d = NULL;
+   ctx->e = NULL;
ctx->d = NULL;
 }
 
-- 
1.9.1

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


[PATCH] crypto: qat - remove superfluous check from adf_probe

2015-10-22 Thread Salvatore Benedetto
 - ent->device is already checked at the beginning of the function
   against the same value. This check is a duplicate.

Signed-off-by: Salvatore Benedetto 
---
 drivers/crypto/qat/qat_dh895xcc/adf_drv.c   | 8 +---
 drivers/crypto/qat/qat_dh895xccvf/adf_drv.c | 9 +
 2 files changed, 2 insertions(+), 15 deletions(-)

diff --git a/drivers/crypto/qat/qat_dh895xcc/adf_drv.c 
b/drivers/crypto/qat/qat_dh895xcc/adf_drv.c
index f8dd14f..f933f7d 100644
--- a/drivers/crypto/qat/qat_dh895xcc/adf_drv.c
+++ b/drivers/crypto/qat/qat_dh895xcc/adf_drv.c
@@ -253,13 +253,7 @@ static int adf_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
}
 
accel_dev->hw_device = hw_data;
-   switch (ent->device) {
-   case ADF_DH895XCC_PCI_DEVICE_ID:
-   adf_init_hw_data_dh895xcc(accel_dev->hw_device);
-   break;
-   default:
-   return -ENODEV;
-   }
+   adf_init_hw_data_dh895xcc(accel_dev->hw_device);
pci_read_config_byte(pdev, PCI_REVISION_ID, &accel_pci_dev->revid);
pci_read_config_dword(pdev, ADF_DH895XCC_FUSECTL_OFFSET,
  &hw_data->fuses);
diff --git a/drivers/crypto/qat/qat_dh895xccvf/adf_drv.c 
b/drivers/crypto/qat/qat_dh895xccvf/adf_drv.c
index 789426f..7bec249 100644
--- a/drivers/crypto/qat/qat_dh895xccvf/adf_drv.c
+++ b/drivers/crypto/qat/qat_dh895xccvf/adf_drv.c
@@ -243,14 +243,7 @@ static int adf_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
goto out_err;
}
accel_dev->hw_device = hw_data;
-   switch (ent->device) {
-   case ADF_DH895XCCIOV_PCI_DEVICE_ID:
-   adf_init_hw_data_dh895xcciov(accel_dev->hw_device);
-   break;
-   default:
-   ret = -ENODEV;
-   goto out_err;
-   }
+   adf_init_hw_data_dh895xcciov(accel_dev->hw_device);
 
/* Get Accelerators and Accelerators Engines masks */
hw_data->accel_mask = hw_data->get_accel_mask(hw_data->fuses);
-- 
1.9.1

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