[crypto v8 12/12] Makefile Kconfig

2018-02-28 Thread Atul Gupta
Entry for Inline TLS as another driver dependent on cxgb4 and chcr

Signed-off-by: Atul Gupta 
---
 drivers/crypto/chelsio/Kconfig| 11 +++
 drivers/crypto/chelsio/Makefile   |  1 +
 drivers/crypto/chelsio/chtls/Makefile |  4 
 3 files changed, 16 insertions(+)
 create mode 100644 drivers/crypto/chelsio/chtls/Makefile

diff --git a/drivers/crypto/chelsio/Kconfig b/drivers/crypto/chelsio/Kconfig
index 5ae9f87..930d82d 100644
--- a/drivers/crypto/chelsio/Kconfig
+++ b/drivers/crypto/chelsio/Kconfig
@@ -29,3 +29,14 @@ config CHELSIO_IPSEC_INLINE
 default n
 ---help---
   Enable support for IPSec Tx Inline.
+
+config CRYPTO_DEV_CHELSIO_TLS
+tristate "Chelsio Crypto Inline TLS Driver"
+depends on CHELSIO_T4
+depends on TLS
+select CRYPTO_DEV_CHELSIO
+---help---
+  Support Chelsio Inline TLS with Chelsio crypto accelerator.
+
+  To compile this driver as a module, choose M here: the module
+  will be called chtls.
diff --git a/drivers/crypto/chelsio/Makefile b/drivers/crypto/chelsio/Makefile
index eaecaf1..639e571 100644
--- a/drivers/crypto/chelsio/Makefile
+++ b/drivers/crypto/chelsio/Makefile
@@ -3,3 +3,4 @@ ccflags-y := -Idrivers/net/ethernet/chelsio/cxgb4
 obj-$(CONFIG_CRYPTO_DEV_CHELSIO) += chcr.o
 chcr-objs :=  chcr_core.o chcr_algo.o
 chcr-$(CONFIG_CHELSIO_IPSEC_INLINE) += chcr_ipsec.o
+obj-$(CONFIG_CRYPTO_DEV_CHELSIO_TLS) += chtls/
diff --git a/drivers/crypto/chelsio/chtls/Makefile 
b/drivers/crypto/chelsio/chtls/Makefile
new file mode 100644
index 000..df13795
--- /dev/null
+++ b/drivers/crypto/chelsio/chtls/Makefile
@@ -0,0 +1,4 @@
+ccflags-y := -Idrivers/net/ethernet/chelsio/cxgb4 -Idrivers/crypto/chelsio/
+
+obj-$(CONFIG_CRYPTO_DEV_CHELSIO_TLS) += chtls.o
+chtls-objs := chtls_main.o chtls_cm.o chtls_io.o chtls_hw.o
-- 
1.8.3.1



[crypto v8 08/12] chtls: Key program

2018-02-28 Thread Atul Gupta
Program the tx and rx key on chip.

Signed-off-by: Atul Gupta 
---
 drivers/crypto/chelsio/chtls/chtls_hw.c | 394 
 1 file changed, 394 insertions(+)
 create mode 100644 drivers/crypto/chelsio/chtls/chtls_hw.c

diff --git a/drivers/crypto/chelsio/chtls/chtls_hw.c 
b/drivers/crypto/chelsio/chtls/chtls_hw.c
new file mode 100644
index 000..c3e17159
--- /dev/null
+++ b/drivers/crypto/chelsio/chtls/chtls_hw.c
@@ -0,0 +1,394 @@
+/*
+ * Copyright (c) 2017 Chelsio Communications, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Written by: Atul Gupta (atul.gu...@chelsio.com)
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "chtls.h"
+#include "chtls_cm.h"
+
+static void __set_tcb_field_direct(struct chtls_sock *csk,
+  struct cpl_set_tcb_field *req, u16 word,
+  u64 mask, u64 val, u8 cookie, int no_reply)
+{
+   struct ulptx_idata *sc;
+
+   INIT_TP_WR_CPL(req, CPL_SET_TCB_FIELD, csk->tid);
+   req->wr.wr_mid |= htonl(FW_WR_FLOWID_V(csk->tid));
+   req->reply_ctrl = htons(NO_REPLY_V(no_reply) |
+   QUEUENO_V(csk->rss_qid));
+   req->word_cookie = htons(TCB_WORD_V(word) | TCB_COOKIE_V(cookie));
+   req->mask = cpu_to_be64(mask);
+   req->val = cpu_to_be64(val);
+   sc = (struct ulptx_idata *)(req + 1);
+   sc->cmd_more = htonl(ULPTX_CMD_V(ULP_TX_SC_NOOP));
+   sc->len = htonl(0);
+}
+
+static void __set_tcb_field(struct sock *sk, struct sk_buff *skb, u16 word,
+   u64 mask, u64 val, u8 cookie, int no_reply)
+{
+   struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
+   struct cpl_set_tcb_field *req;
+   struct ulptx_idata *sc;
+   unsigned int wrlen = roundup(sizeof(*req) + sizeof(*sc), 16);
+
+   req = (struct cpl_set_tcb_field *)__skb_put(skb, wrlen);
+   __set_tcb_field_direct(csk, req, word, mask, val, cookie, no_reply);
+   set_wr_txq(skb, CPL_PRIORITY_CONTROL, csk->port_id);
+}
+
+static int chtls_set_tcb_field(struct sock *sk, u16 word, u64 mask, u64 val)
+{
+   struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
+   struct sk_buff *skb;
+   struct cpl_set_tcb_field *req;
+   struct ulptx_idata *sc;
+   unsigned int wrlen = roundup(sizeof(*req) + sizeof(*sc), 16);
+   unsigned int credits_needed = DIV_ROUND_UP(wrlen, 16);
+
+   skb = alloc_skb(wrlen, GFP_ATOMIC);
+   if (!skb)
+   return -ENOMEM;
+
+   __set_tcb_field(sk, skb, word, mask, val, 0, 1);
+   set_queue(skb, (csk->txq_idx << 1) | CPL_PRIORITY_DATA, sk);
+   csk->wr_credits -= credits_needed;
+   csk->wr_unacked += credits_needed;
+   enqueue_wr(csk, skb);
+   cxgb4_ofld_send(csk->egress_dev, skb);
+   return 0;
+}
+
+/*
+ * Set one of the t_flags bits in the TCB.
+ */
+int chtls_set_tcb_tflag(struct sock *sk, unsigned int bit_pos, int val)
+{
+   return chtls_set_tcb_field(sk, 1, 1ULL << bit_pos,
+   val << bit_pos);
+}
+
+static int chtls_set_tcb_keyid(struct sock *sk, int keyid)
+{
+   return chtls_set_tcb_field(sk, 31, 0xULL, keyid);
+}
+
+static int chtls_set_tcb_seqno(struct sock *sk)
+{
+   return chtls_set_tcb_field(sk, 28, ~0ULL, 0);
+}
+
+static int chtls_set_tcb_quiesce(struct sock *sk, int val)
+{
+   return chtls_set_tcb_field(sk, 1, (1ULL << TF_RX_QUIESCE_S),
+  TF_RX_QUIESCE_V(val));
+}
+
+static void *chtls_alloc_mem(unsigned long size)
+{
+   void *p = kmalloc(size, GFP_KERNEL);
+
+   if (!p)
+   p = vmalloc(size);
+   if (p)
+   memset(p, 0, size);
+   return p;
+}
+
+static void chtls_free_mem(void *addr)
+{
+   unsigned long p = (unsigned long)addr;
+
+   if (p >= VMALLOC_START && p < VMALLOC_END)
+   vfree(addr);
+   else
+   kfree(addr);
+}
+
+/* TLS Key bitmap processing */
+int chtls_init_kmap(struct chtls_dev *cdev, struct cxgb4_lld_info *lldi)
+{
+   unsigned int num_key_ctx, bsize;
+
+   num_key_ctx = (lldi->vr->key.size / TLS_KEY_CONTEXT_SZ);
+   bsize = BITS_TO_LONGS(num_key_ctx);
+
+   cdev->kmap.size = num_key_ctx;
+   cdev->kmap.available = bsize;
+   cdev->kmap.addr = chtls_alloc_mem(sizeof(*cdev->kmap.addr) *
+ bsize);
+   if (!cdev->kmap.addr)
+   return -1;
+
+   cdev->kmap.start = lldi->vr->key.start;
+   spin_lock_init(>kmap.lock);
+   return 0;
+}
+
+void chtls_free_kmap(struct chtls_dev *cdev)
+{
+   if (cdev->kmap.addr)
+   chtls_free_mem(cdev->kmap.addr);
+}
+
+static int 

[crypto v8 11/12] chtls: Register chtls Inline TLS with net tls

2018-02-28 Thread Atul Gupta
Register chtls as Inline TLS driver, chtls is ULD to cxgb4.
Setsockopt to program (tx/rx) keys on chip. Support AES GCM
of key size 128. Support both Inline Rx and Tx.

Signed-off-by: Atul Gupta 
---
 drivers/crypto/chelsio/chtls/chtls_main.c | 600 ++
 include/uapi/linux/tls.h  |   1 +
 2 files changed, 601 insertions(+)
 create mode 100644 drivers/crypto/chelsio/chtls/chtls_main.c

diff --git a/drivers/crypto/chelsio/chtls/chtls_main.c 
b/drivers/crypto/chelsio/chtls/chtls_main.c
new file mode 100644
index 000..657c515
--- /dev/null
+++ b/drivers/crypto/chelsio/chtls/chtls_main.c
@@ -0,0 +1,600 @@
+/*
+ * Copyright (c) 2017 Chelsio Communications, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Written by: Atul Gupta (atul.gu...@chelsio.com)
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "chtls.h"
+#include "chtls_cm.h"
+
+#define DRV_NAME "chtls"
+
+/*
+ * chtls device management
+ * maintains a list of the chtls devices
+ */
+static LIST_HEAD(cdev_list);
+static DEFINE_MUTEX(cdev_mutex);
+static DEFINE_MUTEX(cdev_list_lock);
+
+static struct proto chtls_cpl_prot;
+static struct proto chtls_base_prot;
+static DEFINE_MUTEX(notify_mutex);
+static RAW_NOTIFIER_HEAD(listen_notify_list);
+struct request_sock_ops chtls_rsk_ops;
+static uint send_page_order = (14 - PAGE_SHIFT < 0) ? 0 : 14 - PAGE_SHIFT;
+
+static int register_listen_notifier(struct notifier_block *nb)
+{
+   int err;
+
+   mutex_lock(_mutex);
+   err = raw_notifier_chain_register(_notify_list, nb);
+   mutex_unlock(_mutex);
+   return err;
+}
+
+static int unregister_listen_notifier(struct notifier_block *nb)
+{
+   int err;
+
+   mutex_lock(_mutex);
+   err = raw_notifier_chain_unregister(_notify_list, nb);
+   mutex_unlock(_mutex);
+   return err;
+}
+
+static int listen_notify_handler(struct notifier_block *this,
+unsigned long event, void *data)
+{
+   struct sock *sk = data;
+   struct chtls_dev *cdev;
+   int ret =  NOTIFY_DONE;
+
+   switch (event) {
+   case CHTLS_LISTEN_START:
+   case CHTLS_LISTEN_STOP:
+   mutex_lock(_list_lock);
+   list_for_each_entry(cdev, _list, list) {
+   if (event == CHTLS_LISTEN_START)
+   ret = chtls_listen_start(cdev, sk);
+   else
+   chtls_listen_stop(cdev, sk);
+   }
+   mutex_unlock(_list_lock);
+   break;
+   }
+   return ret;
+}
+
+static struct notifier_block listen_notifier = {
+   .notifier_call = listen_notify_handler
+};
+
+static int listen_backlog_rcv(struct sock *sk, struct sk_buff *skb)
+{
+   if (likely(skb_transport_header(skb) != skb_network_header(skb)))
+   return tcp_v4_do_rcv(sk, skb);
+   BLOG_SKB_CB(skb)->backlog_rcv(sk, skb);
+   return 0;
+}
+
+static int chtls_start_listen(struct sock *sk)
+{
+   int err;
+
+   if (sk->sk_protocol != IPPROTO_TCP)
+   return -EPROTONOSUPPORT;
+
+   if (sk->sk_family == PF_INET &&
+   LOOPBACK(inet_sk(sk)->inet_rcv_saddr))
+   return -EADDRNOTAVAIL;
+
+   sk->sk_backlog_rcv = listen_backlog_rcv;
+   mutex_lock(_mutex);
+   err = raw_notifier_call_chain(_notify_list,
+ CHTLS_LISTEN_START, sk);
+   mutex_unlock(_mutex);
+   return err;
+}
+
+static int chtls_hash(struct sock *sk)
+{
+   int err;
+
+   err = tcp_prot.hash(sk);
+   if (sk->sk_state == TCP_LISTEN)
+   err |= chtls_start_listen(sk);
+
+   if (err)
+   tcp_prot.unhash(sk);
+   return err;
+}
+
+static int chtls_stop_listen(struct sock *sk)
+{
+   if (sk->sk_protocol != IPPROTO_TCP)
+   return -EPROTONOSUPPORT;
+
+   mutex_lock(_mutex);
+   raw_notifier_call_chain(_notify_list,
+   CHTLS_LISTEN_STOP, sk);
+   mutex_unlock(_mutex);
+   return 0;
+}
+
+static void chtls_unhash(struct sock *sk)
+{
+   if (sk->sk_state == TCP_LISTEN)
+   chtls_stop_listen(sk);
+   tcp_prot.unhash(sk);
+}
+
+static int chtls_netdev(struct tls_device *dev,
+   struct net_device *netdev)
+{
+   struct chtls_dev *cdev = to_chtls_dev(dev);
+   int i;
+
+   for (i = 0; i < cdev->lldi->nports; i++)
+   if (cdev->ports[i] == netdev)
+   return 1;
+
+   return 0;
+}
+
+static int chtls_inline_feature(struct tls_device *dev)
+{
+   struct chtls_dev *cdev = to_chtls_dev(dev);
+   struct net_device *netdev;
+   int i;
+
+ 

[crypto v8 10/12] chtls: Inline crypto request Tx/Rx

2018-02-28 Thread Atul Gupta
TLS handler for record transmit and receive.
Create Inline TLS work request and post to FW.

Signed-off-by: Atul Gupta 
---
 drivers/crypto/chelsio/chtls/chtls_io.c | 1867 +++
 1 file changed, 1867 insertions(+)
 create mode 100644 drivers/crypto/chelsio/chtls/chtls_io.c

diff --git a/drivers/crypto/chelsio/chtls/chtls_io.c 
b/drivers/crypto/chelsio/chtls/chtls_io.c
new file mode 100644
index 000..0c5d6c1
--- /dev/null
+++ b/drivers/crypto/chelsio/chtls/chtls_io.c
@@ -0,0 +1,1867 @@
+/*
+ * Copyright (c) 2017 Chelsio Communications, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Written by: Atul Gupta (atul.gu...@chelsio.com)
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "chtls.h"
+#include "chtls_cm.h"
+
+static bool is_tls_hw(struct chtls_sock *csk)
+{
+   return csk->tlshws.ofld;
+}
+
+static bool is_tls_rx(struct chtls_sock *csk)
+{
+   return (csk->tlshws.rxkey >= 0);
+}
+
+static bool is_tls_tx(struct chtls_sock *csk)
+{
+   return (csk->tlshws.txkey >= 0);
+}
+
+static bool is_tls_skb(struct chtls_sock *csk, const struct sk_buff *skb)
+{
+   return (is_tls_hw(csk) && skb_ulp_tls_skb_flags(skb));
+}
+
+static int key_size(void *sk)
+{
+   return 16; /* Key on DDR */
+}
+
+#define ceil(x, y) \
+   ({ unsigned long __x = (x), __y = (y); (__x + __y - 1) / __y; })
+
+static int data_sgl_len(const struct sk_buff *skb)
+{
+   unsigned int cnt;
+
+   cnt = skb_shinfo(skb)->nr_frags;
+   return (sgl_len(cnt) * 8);
+}
+
+static int nos_ivs(struct sock *sk, unsigned int size)
+{
+   struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
+
+   return ceil(size, csk->tlshws.mfs);
+}
+
+#define TLS_WR_CPL_LEN \
+   (sizeof(struct fw_tlstx_data_wr) + \
+   sizeof(struct cpl_tx_tls_sfo))
+
+static int is_ivs_imm(struct sock *sk, const struct sk_buff *skb)
+{
+   int ivs_size = nos_ivs(sk, skb->len) * CIPHER_BLOCK_SIZE;
+   int hlen = TLS_WR_CPL_LEN + data_sgl_len(skb);
+
+   if ((hlen + key_size(sk) + ivs_size) <
+   MAX_IMM_OFLD_TX_DATA_WR_LEN) {
+   ULP_SKB_CB(skb)->ulp.tls.iv = 1;
+   return 1;
+   }
+   ULP_SKB_CB(skb)->ulp.tls.iv = 0;
+   return 0;
+}
+
+static int max_ivs_size(struct sock *sk, int size)
+{
+   return (nos_ivs(sk, size) * CIPHER_BLOCK_SIZE);
+}
+
+static int ivs_size(struct sock *sk, const struct sk_buff *skb)
+{
+   return (is_ivs_imm(sk, skb) ? (nos_ivs(sk, skb->len) *
+CIPHER_BLOCK_SIZE) : 0);
+}
+
+static int flowc_wr_credits(int nparams, int *flowclenp)
+{
+   int flowclen16, flowclen;
+
+   flowclen = offsetof(struct fw_flowc_wr, mnemval[nparams]);
+   flowclen16 = DIV_ROUND_UP(flowclen, 16);
+   flowclen = flowclen16 * 16;
+
+   if (flowclenp)
+   *flowclenp = flowclen;
+
+   return flowclen16;
+}
+
+static struct sk_buff *create_flowc_wr_skb(struct sock *sk,
+  struct fw_flowc_wr *flowc,
+  int flowclen)
+{
+   struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
+   struct sk_buff *skb;
+
+   skb = alloc_skb(flowclen, GFP_ATOMIC);
+   if (!skb)
+   return NULL;
+
+   memcpy(__skb_put(skb, flowclen), flowc, flowclen);
+   set_queue(skb, (csk->txq_idx << 1) | CPL_PRIORITY_DATA, sk);
+
+   return skb;
+}
+
+static int send_flowc_wr(struct sock *sk, struct fw_flowc_wr *flowc,
+int flowclen)
+{
+   struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
+   bool syn_sent = (sk->sk_state == TCP_SYN_SENT);
+   struct tcp_sock *tp = tcp_sk(sk);
+   int flowclen16 = flowclen / 16;
+   struct sk_buff *skb;
+
+   if (csk_flag(sk, CSK_TX_DATA_SENT)) {
+   skb = create_flowc_wr_skb(sk, flowc, flowclen);
+   if (!skb)
+   return -ENOMEM;
+
+   if (syn_sent)
+   __skb_queue_tail(>ooo_queue, skb);
+   else
+   skb_entail(sk, skb,
+  ULPCB_FLAG_NO_HDR | ULPCB_FLAG_NO_APPEND);
+   return 0;
+   }
+
+   if (!syn_sent) {
+   int ret;
+
+   ret = cxgb4_immdata_send(csk->egress_dev,
+csk->txq_idx,
+flowc, flowclen);
+   if (!ret)
+   return flowclen16;
+   }
+   skb = create_flowc_wr_skb(sk, flowc, flowclen);
+   if (!skb)
+   return -ENOMEM;
+   send_or_defer(sk, tp, skb, 0);
+   return flowclen16;
+}
+
+static u8 

[crypto v8 09/12] chtls: CPL handler definition

2018-02-28 Thread Atul Gupta
CPL handlers for TLS session, record transmit and receive.

Signed-off-by: Atul Gupta 
---
 drivers/crypto/chelsio/chtls/chtls_cm.c | 2041 +++
 net/ipv4/tcp_minisocks.c|1 +
 2 files changed, 2042 insertions(+)
 create mode 100644 drivers/crypto/chelsio/chtls/chtls_cm.c

diff --git a/drivers/crypto/chelsio/chtls/chtls_cm.c 
b/drivers/crypto/chelsio/chtls/chtls_cm.c
new file mode 100644
index 000..1c95e87
--- /dev/null
+++ b/drivers/crypto/chelsio/chtls/chtls_cm.c
@@ -0,0 +1,2041 @@
+/*
+ * Copyright (c) 2017 Chelsio Communications, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Written by: Atul Gupta (atul.gu...@chelsio.com)
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "chtls.h"
+#include "chtls_cm.h"
+
+extern struct request_sock_ops chtls_rsk_ops;
+
+/*
+ * State transitions and actions for close.  Note that if we are in SYN_SENT
+ * we remain in that state as we cannot control a connection while it's in
+ * SYN_SENT; such connections are allowed to establish and are then aborted.
+ */
+static unsigned char new_state[16] = {
+   /* current state: new state:  action: */
+   /* (Invalid)   */ TCP_CLOSE,
+   /* TCP_ESTABLISHED */ TCP_FIN_WAIT1 | TCP_ACTION_FIN,
+   /* TCP_SYN_SENT*/ TCP_SYN_SENT,
+   /* TCP_SYN_RECV*/ TCP_FIN_WAIT1 | TCP_ACTION_FIN,
+   /* TCP_FIN_WAIT1   */ TCP_FIN_WAIT1,
+   /* TCP_FIN_WAIT2   */ TCP_FIN_WAIT2,
+   /* TCP_TIME_WAIT   */ TCP_CLOSE,
+   /* TCP_CLOSE   */ TCP_CLOSE,
+   /* TCP_CLOSE_WAIT  */ TCP_LAST_ACK | TCP_ACTION_FIN,
+   /* TCP_LAST_ACK*/ TCP_LAST_ACK,
+   /* TCP_LISTEN  */ TCP_CLOSE,
+   /* TCP_CLOSING */ TCP_CLOSING,
+};
+
+static struct chtls_sock *chtls_sock_create(struct chtls_dev *cdev)
+{
+   struct chtls_sock *csk = kzalloc(sizeof(*csk), GFP_ATOMIC);
+
+   if (!csk)
+   return NULL;
+
+   csk->txdata_skb_cache = alloc_skb(TXDATA_SKB_LEN, GFP_ATOMIC);
+   if (!csk->txdata_skb_cache) {
+   kfree(csk);
+   return NULL;
+   }
+
+   kref_init(>kref);
+   csk->cdev = cdev;
+   skb_queue_head_init(>txq);
+   csk->wr_skb_head = NULL;
+   csk->wr_skb_tail = NULL;
+   csk->mss = MAX_MSS;
+   csk->tlshws.ofld = 1;
+   csk->tlshws.txkey = -1;
+   csk->tlshws.rxkey = -1;
+   csk->tlshws.mfs = TLS_MFS;
+   skb_queue_head_init(>tlshws.sk_recv_queue);
+   return csk;
+}
+
+static void chtls_sock_release(struct kref *ref)
+{
+   struct chtls_sock *csk =
+   container_of(ref, struct chtls_sock, kref);
+
+   kfree(csk);
+}
+
+static struct net_device *chtls_ipv4_netdev(struct chtls_dev *cdev,
+   struct sock *sk)
+{
+   struct net_device *ndev = cdev->ports[0];
+
+   if (likely(!inet_sk(sk)->inet_rcv_saddr))
+   return ndev;
+
+   ndev = ip_dev_find(_net, inet_sk(sk)->inet_rcv_saddr);
+   if (!ndev)
+   return NULL;
+
+   if (is_vlan_dev(ndev))
+   return vlan_dev_real_dev(ndev);
+   return ndev;
+}
+
+static void assign_rxopt(struct sock *sk, unsigned int opt)
+{
+   struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
+   struct tcp_sock *tp = tcp_sk(sk);
+   const struct chtls_dev *cdev;
+
+   cdev = csk->cdev;
+   tp->tcp_header_len   = sizeof(struct tcphdr);
+   tp->rx_opt.mss_clamp = cdev->mtus[TCPOPT_MSS_G(opt)] - 40;
+   tp->mss_cache= tp->rx_opt.mss_clamp;
+   tp->rx_opt.tstamp_ok = TCPOPT_TSTAMP_G(opt);
+   tp->rx_opt.snd_wscale= TCPOPT_SACK_G(opt);
+   tp->rx_opt.wscale_ok = TCPOPT_WSCALE_OK_G(opt);
+   SND_WSCALE(tp)   = TCPOPT_SND_WSCALE_G(opt);
+   if (!tp->rx_opt.wscale_ok)
+   tp->rx_opt.rcv_wscale = 0;
+   if (tp->rx_opt.tstamp_ok) {
+   tp->tcp_header_len += TCPOLEN_TSTAMP_ALIGNED;
+   tp->rx_opt.mss_clamp -= TCPOLEN_TSTAMP_ALIGNED;
+   } else if (csk->opt2 & TSTAMPS_EN_F) {
+   csk->opt2 &= ~TSTAMPS_EN_F;
+   csk->mtu_idx = TCPOPT_MSS_G(opt);
+   }
+}
+
+static void chtls_purge_rcv_queue(struct sock *sk)
+{
+   struct sk_buff *skb;
+
+   while ((skb = __skb_dequeue(>sk_receive_queue)) != NULL) {
+   skb_dst_set(skb, (void *)NULL);
+   kfree_skb(skb);
+   }
+}
+
+static void chtls_purge_write_queue(struct sock *sk)
+{
+   struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
+   struct sk_buff *skb;
+
+   while ((skb = __skb_dequeue(>txq))) {
+

[crypto v8 06/12] cxgb4: LLD driver changes to enable TLS

2018-02-28 Thread Atul Gupta
Read FW capability. Read key area size. Dump the TLS record count.

Signed-off-by: Atul Gupta 
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 32 +---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h  |  7 ++
 drivers/net/ethernet/chelsio/cxgb4/sge.c| 98 -
 3 files changed, 126 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 56bc626..ab5937e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -4284,18 +4284,32 @@ static int adap_init0(struct adapter *adap)
adap->num_ofld_uld += 2;
}
if (caps_cmd.cryptocaps) {
-   /* Should query params here...TODO */
-   params[0] = FW_PARAM_PFVF(NCRYPTO_LOOKASIDE);
-   ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 2,
- params, val);
-   if (ret < 0) {
-   if (ret != -EINVAL)
+   if (ntohs(caps_cmd.cryptocaps) &
+   FW_CAPS_CONFIG_CRYPTO_LOOKASIDE) {
+   params[0] = FW_PARAM_PFVF(NCRYPTO_LOOKASIDE);
+   ret = t4_query_params(adap, adap->mbox, adap->pf, 0,
+ 2, params, val);
+   if (ret < 0) {
+   if (ret != -EINVAL)
+   goto bye;
+   } else {
+   adap->vres.ncrypto_fc = val[0];
+   }
+   adap->num_ofld_uld += 1;
+   }
+   if (ntohs(caps_cmd.cryptocaps) &
+   FW_CAPS_CONFIG_TLS_INLINE) {
+   params[0] = FW_PARAM_PFVF(TLS_START);
+   params[1] = FW_PARAM_PFVF(TLS_END);
+   ret = t4_query_params(adap, adap->mbox, adap->pf, 0,
+ 2, params, val);
+   if (ret < 0)
goto bye;
-   } else {
-   adap->vres.ncrypto_fc = val[0];
+   adap->vres.key.start = val[0];
+   adap->vres.key.size = val[1] - val[0] + 1;
+   adap->num_uld += 1;
}
adap->params.crypto = ntohs(caps_cmd.cryptocaps);
-   adap->num_uld += 1;
}
 #undef FW_PARAM_PFVF
 #undef FW_PARAM_DEV
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
index a14e8db..3d3ef3f 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
@@ -237,6 +237,7 @@ enum cxgb4_uld {
CXGB4_ULD_ISCSI,
CXGB4_ULD_ISCSIT,
CXGB4_ULD_CRYPTO,
+   CXGB4_ULD_TLS,
CXGB4_ULD_MAX
 };
 
@@ -287,6 +288,7 @@ struct cxgb4_virt_res {  /* virtualized 
HW resources */
struct cxgb4_range qp;
struct cxgb4_range cq;
struct cxgb4_range ocq;
+   struct cxgb4_range key;
unsigned int ncrypto_fc;
 };
 
@@ -298,6 +300,9 @@ struct chcr_stats_debug {
atomic_t error;
atomic_t fallback;
atomic_t ipsec_cnt;
+   atomic_t tls_pdu_tx;
+   atomic_t tls_pdu_rx;
+   atomic_t tls_key;
 };
 
 #define OCQ_WIN_OFFSET(pdev, vres) \
@@ -378,6 +383,8 @@ struct cxgb4_uld_info {
 int cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p);
 int cxgb4_unregister_uld(enum cxgb4_uld type);
 int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb);
+int cxgb4_immdata_send(struct net_device *dev, unsigned int idx,
+  const void *src, unsigned int len);
 int cxgb4_crypto_send(struct net_device *dev, struct sk_buff *skb);
 unsigned int cxgb4_dbfifo_count(const struct net_device *dev, int lpfifo);
 unsigned int cxgb4_port_chan(const struct net_device *dev);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c 
b/drivers/net/ethernet/chelsio/cxgb4/sge.c
index 6e310a0..32e3779 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c
@@ -1740,9 +1740,9 @@ static void txq_stop_maperr(struct sge_uld_txq *q)
  * Stops an offload Tx queue that has become full and modifies the packet
  * being written to request a wakeup.
  */
-static void ofldtxq_stop(struct sge_uld_txq *q, struct sk_buff *skb)
+static void ofldtxq_stop(struct sge_uld_txq *q, void *src)
 {
-   struct fw_wr_hdr *wr = (struct fw_wr_hdr *)skb->data;
+   struct fw_wr_hdr *wr = (struct fw_wr_hdr *)src;
 
wr->lo |= htonl(FW_WR_EQUEQ_F | FW_WR_EQUIQ_F);
q->q.stops++;
@@ -2005,6 +2005,100 @@ int cxgb4_ofld_send(struct net_device *dev, struct 
sk_buff *skb)
 }
 EXPORT_SYMBOL(cxgb4_ofld_send);
 
+static void 

[crypto v8 04/12] chtls: structure and macro definiton

2018-02-28 Thread Atul Gupta
Inline TLS state, connection management. Supporting macros definition.

Signed-off-by: Atul Gupta 
---
 drivers/crypto/chelsio/chtls/chtls.h| 487 
 drivers/crypto/chelsio/chtls/chtls_cm.h | 202 +
 2 files changed, 689 insertions(+)
 create mode 100644 drivers/crypto/chelsio/chtls/chtls.h
 create mode 100644 drivers/crypto/chelsio/chtls/chtls_cm.h

diff --git a/drivers/crypto/chelsio/chtls/chtls.h 
b/drivers/crypto/chelsio/chtls/chtls.h
new file mode 100644
index 000..3ae7145
--- /dev/null
+++ b/drivers/crypto/chelsio/chtls/chtls.h
@@ -0,0 +1,487 @@
+/*
+ * Copyright (c) 2016 Chelsio Communications, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __CHTLS_H__
+#define __CHTLS_H__
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "t4fw_api.h"
+#include "t4_msg.h"
+#include "cxgb4.h"
+#include "cxgb4_uld.h"
+#include "l2t.h"
+#include "chcr_algo.h"
+#include "chcr_core.h"
+#include "chcr_crypto.h"
+
+#define CIPHER_BLOCK_SIZE   16
+#define MAX_IVS_PAGE256
+#define TLS_KEY_CONTEXT_SZ 64
+#define TLS_HEADER_LENGTH  5
+#define SCMD_CIPH_MODE_AES_GCM  2
+#define GCM_TAG_SIZE16
+#define AEAD_EXPLICIT_DATA_SIZE 8
+/* Any MFS size should work and come from openssl */
+#define TLS_MFS16384
+
+#define SOCK_INLINE (31)
+#define RSS_HDR sizeof(struct rss_header)
+
+enum {
+   CHTLS_KEY_CONTEXT_DSGL,
+   CHTLS_KEY_CONTEXT_IMM,
+   CHTLS_KEY_CONTEXT_DDR,
+};
+
+enum {
+   CHTLS_LISTEN_START,
+   CHTLS_LISTEN_STOP,
+};
+
+/* Flags for return value of CPL message handlers */
+enum {
+   CPL_RET_BUF_DONE = 1,   /* buffer processing done */
+   CPL_RET_BAD_MSG = 2,/* bad CPL message */
+   CPL_RET_UNKNOWN_TID = 4 /* unexpected unknown TID */
+};
+
+#define TLS_RCV_ST_READ_HEADER  0xF0
+#define TLS_RCV_ST_READ_BODY0xF1
+#define TLS_RCV_ST_READ_DONE0xF2
+#define TLS_RCV_ST_READ_NB  0xF3
+
+#define RSPQ_HASH_BITS 5
+#define LISTEN_INFO_HASH_SIZE 32
+struct listen_info {
+   struct listen_info *next;  /* Link to next entry */
+   struct sock *sk;   /* The listening socket */
+   unsigned int stid; /* The server TID */
+};
+
+enum {
+   T4_LISTEN_START_PENDING,
+   T4_LISTEN_STARTED
+};
+
+enum csk_flags {
+   CSK_CALLBACKS_CHKD, /* socket callbacks have been sanitized */
+   CSK_ABORT_REQ_RCVD, /* received one ABORT_REQ_RSS message */
+   CSK_TX_MORE_DATA,   /* sending ULP data; don't set SHOVE bit */
+   CSK_TX_WAIT_IDLE,   /* suspend Tx until in-flight data is ACKed */
+   CSK_ABORT_SHUTDOWN, /* shouldn't send more abort requests */
+   CSK_ABORT_RPL_PENDING,  /* expecting an abort reply */
+   CSK_CLOSE_CON_REQUESTED,/* we've sent a close_conn_req */
+   CSK_TX_DATA_SENT,   /* sent a TX_DATA WR on this connection */
+   CSK_TX_FAILOVER,/* Tx traffic failing over */
+   CSK_UPDATE_RCV_WND, /* Need to update rcv window */
+   CSK_RST_ABORTED,/* outgoing RST was aborted */
+   CSK_TLS_HANDSHK,/* TLS Handshake */
+};
+
+struct listen_ctx {
+   struct sock *lsk;
+   struct chtls_dev *cdev;
+   u32 state;
+};
+
+struct key_map {
+   unsigned long *addr;
+   unsigned int start;
+   unsigned int available;
+   unsigned int size;
+   spinlock_t lock; /* lock for key id request from map */
+} __packed;
+
+struct tls_scmd {
+   u32 seqno_numivs;
+   u32 ivgen_hdrlen;
+};
+
+struct chtls_dev {
+   struct tls_device tlsdev;
+   struct list_head list;
+   struct cxgb4_lld_info *lldi;
+   struct pci_dev *pdev;
+   struct listen_info *listen_hash_tab[LISTEN_INFO_HASH_SIZE];
+   spinlock_t listen_lock; /* lock for listen list */
+   struct net_device **ports;
+   struct tid_info *tids;
+   unsigned int pfvf;
+   const unsigned short *mtus;
+
+   spinlock_t aidr_lock cacheline_aligned_in_smp;
+   struct idr aidr; /* ATID id space */
+   struct idr hwtid_idr;
+   struct idr stid_idr;
+
+   spinlock_t idr_lock cacheline_aligned_in_smp;
+
+   struct net_device *egr_dev[NCHAN * 2];
+   struct sk_buff *rspq_skb_cache[1 << RSPQ_HASH_BITS];
+   struct sk_buff *askb;
+
+   struct sk_buff_head deferq;
+   struct work_struct deferq_task;
+
+   struct list_head list_node;
+   struct list_head rcu_node;
+   struct list_head na_node;
+   unsigned int send_page_order;
+   struct key_map kmap;
+};
+
+struct 

[crypto v8 07/12] chcr: Key Macro

2018-02-28 Thread Atul Gupta
Define macro for TLS Key context

Signed-off-by: Atul Gupta 
---
 drivers/crypto/chelsio/chcr_algo.h | 42 +
 drivers/crypto/chelsio/chcr_core.h | 55 +-
 2 files changed, 96 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/chelsio/chcr_algo.h 
b/drivers/crypto/chelsio/chcr_algo.h
index d1673a5..f263cd4 100644
--- a/drivers/crypto/chelsio/chcr_algo.h
+++ b/drivers/crypto/chelsio/chcr_algo.h
@@ -86,6 +86,39 @@
 KEY_CONTEXT_OPAD_PRESENT_M)
 #define KEY_CONTEXT_OPAD_PRESENT_F  KEY_CONTEXT_OPAD_PRESENT_V(1U)
 
+#define TLS_KEYCTX_RXFLIT_CNT_S 24
+#define TLS_KEYCTX_RXFLIT_CNT_V(x) ((x) << TLS_KEYCTX_RXFLIT_CNT_S)
+
+#define TLS_KEYCTX_RXPROT_VER_S 20
+#define TLS_KEYCTX_RXPROT_VER_M 0xf
+#define TLS_KEYCTX_RXPROT_VER_V(x) ((x) << TLS_KEYCTX_RXPROT_VER_S)
+
+#define TLS_KEYCTX_RXCIPH_MODE_S 16
+#define TLS_KEYCTX_RXCIPH_MODE_M 0xf
+#define TLS_KEYCTX_RXCIPH_MODE_V(x) ((x) << TLS_KEYCTX_RXCIPH_MODE_S)
+
+#define TLS_KEYCTX_RXAUTH_MODE_S 12
+#define TLS_KEYCTX_RXAUTH_MODE_M 0xf
+#define TLS_KEYCTX_RXAUTH_MODE_V(x) ((x) << TLS_KEYCTX_RXAUTH_MODE_S)
+
+#define TLS_KEYCTX_RXCIAU_CTRL_S 11
+#define TLS_KEYCTX_RXCIAU_CTRL_V(x) ((x) << TLS_KEYCTX_RXCIAU_CTRL_S)
+
+#define TLS_KEYCTX_RX_SEQCTR_S 9
+#define TLS_KEYCTX_RX_SEQCTR_M 0x3
+#define TLS_KEYCTX_RX_SEQCTR_V(x) ((x) << TLS_KEYCTX_RX_SEQCTR_S)
+
+#define TLS_KEYCTX_RX_VALID_S 8
+#define TLS_KEYCTX_RX_VALID_V(x) ((x) << TLS_KEYCTX_RX_VALID_S)
+
+#define TLS_KEYCTX_RXCK_SIZE_S 3
+#define TLS_KEYCTX_RXCK_SIZE_M 0x7
+#define TLS_KEYCTX_RXCK_SIZE_V(x) ((x) << TLS_KEYCTX_RXCK_SIZE_S)
+
+#define TLS_KEYCTX_RXMK_SIZE_S 0
+#define TLS_KEYCTX_RXMK_SIZE_M 0x7
+#define TLS_KEYCTX_RXMK_SIZE_V(x) ((x) << TLS_KEYCTX_RXMK_SIZE_S)
+
 #define CHCR_HASH_MAX_DIGEST_SIZE 64
 #define CHCR_MAX_SHA_DIGEST_SIZE 64
 
@@ -176,6 +209,15 @@
  KEY_CONTEXT_SALT_PRESENT_V(1) | \
  KEY_CONTEXT_CTX_LEN_V((ctx_len)))
 
+#define  FILL_KEY_CRX_HDR(ck_size, mk_size, d_ck, opad, ctx_len) \
+   htonl(TLS_KEYCTX_RXMK_SIZE_V(mk_size) | \
+ TLS_KEYCTX_RXCK_SIZE_V(ck_size) | \
+ TLS_KEYCTX_RX_VALID_V(1) | \
+ TLS_KEYCTX_RX_SEQCTR_V(3) | \
+ TLS_KEYCTX_RXAUTH_MODE_V(4) | \
+ TLS_KEYCTX_RXCIPH_MODE_V(2) | \
+ TLS_KEYCTX_RXFLIT_CNT_V((ctx_len)))
+
 #define FILL_WR_OP_CCTX_SIZE \
htonl( \
FW_CRYPTO_LOOKASIDE_WR_OPCODE_V( \
diff --git a/drivers/crypto/chelsio/chcr_core.h 
b/drivers/crypto/chelsio/chcr_core.h
index 3c29ee0..77056a9 100644
--- a/drivers/crypto/chelsio/chcr_core.h
+++ b/drivers/crypto/chelsio/chcr_core.h
@@ -65,10 +65,58 @@
 struct _key_ctx {
__be32 ctx_hdr;
u8 salt[MAX_SALT];
-   __be64 reserverd;
+   __be64 iv_to_auth;
unsigned char key[0];
 };
 
+#define KEYCTX_TX_WR_IV_S  55
+#define KEYCTX_TX_WR_IV_M  0x1ffULL
+#define KEYCTX_TX_WR_IV_V(x) ((x) << KEYCTX_TX_WR_IV_S)
+#define KEYCTX_TX_WR_IV_G(x) \
+   (((x) >> KEYCTX_TX_WR_IV_S) & KEYCTX_TX_WR_IV_M)
+
+#define KEYCTX_TX_WR_AAD_S 47
+#define KEYCTX_TX_WR_AAD_M 0xffULL
+#define KEYCTX_TX_WR_AAD_V(x) ((x) << KEYCTX_TX_WR_AAD_S)
+#define KEYCTX_TX_WR_AAD_G(x) (((x) >> KEYCTX_TX_WR_AAD_S) & \
+   KEYCTX_TX_WR_AAD_M)
+
+#define KEYCTX_TX_WR_AADST_S 39
+#define KEYCTX_TX_WR_AADST_M 0xffULL
+#define KEYCTX_TX_WR_AADST_V(x) ((x) << KEYCTX_TX_WR_AADST_S)
+#define KEYCTX_TX_WR_AADST_G(x) \
+   (((x) >> KEYCTX_TX_WR_AADST_S) & KEYCTX_TX_WR_AADST_M)
+
+#define KEYCTX_TX_WR_CIPHER_S 30
+#define KEYCTX_TX_WR_CIPHER_M 0x1ffULL
+#define KEYCTX_TX_WR_CIPHER_V(x) ((x) << KEYCTX_TX_WR_CIPHER_S)
+#define KEYCTX_TX_WR_CIPHER_G(x) \
+   (((x) >> KEYCTX_TX_WR_CIPHER_S) & KEYCTX_TX_WR_CIPHER_M)
+
+#define KEYCTX_TX_WR_CIPHERST_S 23
+#define KEYCTX_TX_WR_CIPHERST_M 0x7f
+#define KEYCTX_TX_WR_CIPHERST_V(x) ((x) << KEYCTX_TX_WR_CIPHERST_S)
+#define KEYCTX_TX_WR_CIPHERST_G(x) \
+   (((x) >> KEYCTX_TX_WR_CIPHERST_S) & KEYCTX_TX_WR_CIPHERST_M)
+
+#define KEYCTX_TX_WR_AUTH_S 14
+#define KEYCTX_TX_WR_AUTH_M 0x1ff
+#define KEYCTX_TX_WR_AUTH_V(x) ((x) << KEYCTX_TX_WR_AUTH_S)
+#define KEYCTX_TX_WR_AUTH_G(x) \
+   (((x) >> KEYCTX_TX_WR_AUTH_S) & KEYCTX_TX_WR_AUTH_M)
+
+#define KEYCTX_TX_WR_AUTHST_S 7
+#define KEYCTX_TX_WR_AUTHST_M 0x7f
+#define KEYCTX_TX_WR_AUTHST_V(x) ((x) << KEYCTX_TX_WR_AUTHST_S)
+#define KEYCTX_TX_WR_AUTHST_G(x) \
+   (((x) >> KEYCTX_TX_WR_AUTHST_S) & KEYCTX_TX_WR_AUTHST_M)
+
+#define KEYCTX_TX_WR_AUTHIN_S 0
+#define KEYCTX_TX_WR_AUTHIN_M 0x7f
+#define KEYCTX_TX_WR_AUTHIN_V(x) ((x) << KEYCTX_TX_WR_AUTHIN_S)
+#define KEYCTX_TX_WR_AUTHIN_G(x) \
+   (((x) >> KEYCTX_TX_WR_AUTHIN_S) & KEYCTX_TX_WR_AUTHIN_M)
+
 struct chcr_wr {
struct fw_crypto_lookaside_wr wreq;
struct ulp_txpkt ulptx;
@@ -90,6 +138,11 @@ struct uld_ctx {
struct chcr_dev 

[crypto v8 05/12] cxgb4: Inline TLS FW Interface

2018-02-28 Thread Atul Gupta
Key area size in hw-config file. CPL struct for TLS request
and response. Work request for Inline TLS.

Signed-off-by: Atul Gupta 
---
 drivers/net/ethernet/chelsio/cxgb4/t4_msg.h   | 121 ++-
 drivers/net/ethernet/chelsio/cxgb4/t4_regs.h  |   2 +
 drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 165 +-
 3 files changed, 283 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h 
b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
index d0db442..507cb5a 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
@@ -81,6 +81,7 @@ enum {
CPL_RX_ISCSI_CMP  = 0x45,
CPL_TRACE_PKT_T5  = 0x48,
CPL_RX_ISCSI_DDP  = 0x49,
+   CPL_RX_TLS_CMP= 0x4E,
 
CPL_RDMA_READ_REQ = 0x60,
 
@@ -88,6 +89,7 @@ enum {
CPL_ACT_OPEN_REQ6 = 0x83,
 
CPL_TX_TLS_PDU =0x88,
+   CPL_TX_TLS_SFO= 0x89,
CPL_TX_SEC_PDU= 0x8A,
CPL_TX_TLS_ACK= 0x8B,
 
@@ -97,6 +99,7 @@ enum {
CPL_RX_MPS_PKT= 0xAF,
 
CPL_TRACE_PKT = 0xB0,
+   CPL_TLS_DATA  = 0xB1,
CPL_ISCSI_DATA= 0xB2,
 
CPL_FW4_MSG   = 0xC0,
@@ -151,6 +154,7 @@ enum {
ULP_MODE_RDMA  = 4,
ULP_MODE_TCPDDP= 5,
ULP_MODE_FCOE  = 6,
+   ULP_MODE_TLS   = 8,
 };
 
 enum {
@@ -1415,6 +1419,14 @@ struct cpl_tx_data {
 #define TX_FORCE_S 13
 #define TX_FORCE_V(x)  ((x) << TX_FORCE_S)
 
+#define TX_SHOVE_S14
+#define TX_SHOVE_V(x) ((x) << TX_SHOVE_S)
+
+#define TX_ULP_MODE_S10
+#define TX_ULP_MODE_M0x7
+#define TX_ULP_MODE_V(x) ((x) << TX_ULP_MODE_S)
+#define TX_ULP_MODE_G(x) (((x) >> TX_ULP_MODE_S) & TX_ULP_MODE_M)
+
 #define T6_TX_FORCE_S  20
 #define T6_TX_FORCE_V(x)   ((x) << T6_TX_FORCE_S)
 #define T6_TX_FORCE_F  T6_TX_FORCE_V(1U)
@@ -1429,12 +1441,21 @@ enum {
ULP_TX_SC_NOOP = 0x80,
ULP_TX_SC_IMM  = 0x81,
ULP_TX_SC_DSGL = 0x82,
-   ULP_TX_SC_ISGL = 0x83
+   ULP_TX_SC_ISGL = 0x83,
+   ULP_TX_SC_MEMRD = 0x86
 };
 
 #define ULPTX_CMD_S24
 #define ULPTX_CMD_V(x) ((x) << ULPTX_CMD_S)
 
+#define ULPTX_LEN16_S0
+#define ULPTX_LEN16_M0xFF
+#define ULPTX_LEN16_V(x) ((x) << ULPTX_LEN16_S)
+
+#define ULP_TX_SC_MORE_S 23
+#define ULP_TX_SC_MORE_V(x) ((x) << ULP_TX_SC_MORE_S)
+#define ULP_TX_SC_MORE_F  ULP_TX_SC_MORE_V(1U)
+
 struct ulptx_sge_pair {
__be32 len[2];
__be64 addr[2];
@@ -2112,4 +2133,102 @@ enum {
X_CPL_RX_MPS_PKT_TYPE_QFC   = 1 << 2,
X_CPL_RX_MPS_PKT_TYPE_PTP   = 1 << 3
 };
+
+struct cpl_tx_tls_sfo {
+   __be32 op_to_seg_len;
+   __be32 pld_len;
+   __be32 type_protover;
+   __be32 r1_lo;
+   __be32 seqno_numivs;
+   __be32 ivgen_hdrlen;
+   __be64 scmd1;
+};
+
+/* cpl_tx_tls_sfo macros */
+#define CPL_TX_TLS_SFO_OPCODE_S 24
+#define CPL_TX_TLS_SFO_OPCODE_V(x)  ((x) << CPL_TX_TLS_SFO_OPCODE_S)
+
+#define CPL_TX_TLS_SFO_DATA_TYPE_S  20
+#define CPL_TX_TLS_SFO_DATA_TYPE_V(x)   ((x) << CPL_TX_TLS_SFO_DATA_TYPE_S)
+
+#define CPL_TX_TLS_SFO_CPL_LEN_S16
+#define CPL_TX_TLS_SFO_CPL_LEN_V(x) ((x) << CPL_TX_TLS_SFO_CPL_LEN_S)
+
+#define CPL_TX_TLS_SFO_SEG_LEN_S0
+#define CPL_TX_TLS_SFO_SEG_LEN_M0x
+#define CPL_TX_TLS_SFO_SEG_LEN_V(x) ((x) << CPL_TX_TLS_SFO_SEG_LEN_S)
+#define CPL_TX_TLS_SFO_SEG_LEN_G(x) \
+   (((x) >> CPL_TX_TLS_SFO_SEG_LEN_S) & CPL_TX_TLS_SFO_SEG_LEN_M)
+
+#define CPL_TX_TLS_SFO_TYPE_S   24
+#define CPL_TX_TLS_SFO_TYPE_M   0xff
+#define CPL_TX_TLS_SFO_TYPE_V(x)((x) << CPL_TX_TLS_SFO_TYPE_S)
+#define CPL_TX_TLS_SFO_TYPE_G(x)\
+   (((x) >> CPL_TX_TLS_SFO_TYPE_S) & CPL_TX_TLS_SFO_TYPE_M)
+
+#define CPL_TX_TLS_SFO_PROTOVER_S   8
+#define CPL_TX_TLS_SFO_PROTOVER_M   0x
+#define CPL_TX_TLS_SFO_PROTOVER_V(x)((x) << CPL_TX_TLS_SFO_PROTOVER_S)
+#define CPL_TX_TLS_SFO_PROTOVER_G(x)\
+   (((x) >> CPL_TX_TLS_SFO_PROTOVER_S) & CPL_TX_TLS_SFO_PROTOVER_M)
+
+struct cpl_tls_data {
+   struct rss_header rsshdr;
+   union opcode_tid ot;
+   __be32 length_pkd;
+   __be32 seq;
+   __be32 r1;
+};
+
+#define CPL_TLS_DATA_OPCODE_S   24
+#define CPL_TLS_DATA_OPCODE_M   0xff
+#define CPL_TLS_DATA_OPCODE_V(x)((x) << CPL_TLS_DATA_OPCODE_S)
+#define CPL_TLS_DATA_OPCODE_G(x)\
+   (((x) >> CPL_TLS_DATA_OPCODE_S) & CPL_TLS_DATA_OPCODE_M)
+
+#define CPL_TLS_DATA_TID_S  0
+#define CPL_TLS_DATA_TID_M  0xff
+#define CPL_TLS_DATA_TID_V(x)   ((x) << CPL_TLS_DATA_TID_S)
+#define CPL_TLS_DATA_TID_G(x)   \
+   (((x) >> CPL_TLS_DATA_TID_S) & CPL_TLS_DATA_TID_M)
+
+#define CPL_TLS_DATA_LENGTH_S   0
+#define CPL_TLS_DATA_LENGTH_M   0x
+#define 

[crypto v8 03/12] tls: support for inline tls

2018-02-28 Thread Atul Gupta
Facility to register Inline TLS drivers to net/tls. Setup
TLS_FULL_HW prot to listen on offload device.

Cases handled
1. Inline TLS device exists, setup prot for TLS_FULL_HW
2. Atleast one Inline TLS exists, sets TLS_FULL_HW. If
non-inline capable device establish connection move to TLS_SW_TX

Signed-off-by: Atul Gupta 
---
 net/tls/tls_main.c | 87 +-
 1 file changed, 80 insertions(+), 7 deletions(-)

diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
index b0d5fce..2ac9510 100644
--- a/net/tls/tls_main.c
+++ b/net/tls/tls_main.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -45,13 +46,9 @@
 MODULE_DESCRIPTION("Transport Layer Security Support");
 MODULE_LICENSE("Dual BSD/GPL");
 
-enum {
-   TLS_BASE_TX,
-   TLS_SW_TX,
-   TLS_NUM_CONFIG,
-};
-
-static struct proto tls_prots[TLS_NUM_CONFIG];
+static LIST_HEAD(device_list);
+static DEFINE_MUTEX(device_mutex);
+struct proto tls_prots[TLS_NUM_CONFIG];
 
 static inline void update_sk_prot(struct sock *sk, struct tls_context *ctx)
 {
@@ -450,6 +447,58 @@ static int tls_setsockopt(struct sock *sk, int level, int 
optname,
return do_tls_setsockopt(sk, optname, optval, optlen);
 }
 
+static int tls_hw_prot(struct sock *sk)
+{
+   struct tls_context *ctx = tls_get_ctx(sk);
+   struct tls_device *dev;
+
+   mutex_lock(_mutex);
+   list_for_each_entry(dev, _list, dev_list) {
+   if (dev->feature && dev->feature(dev)) {
+   ctx->hash = sk->sk_prot->hash;
+   ctx->unhash = sk->sk_prot->unhash;
+   ctx->tx_conf = TLS_FULL_HW;
+   update_sk_prot(sk, ctx);
+   break;
+   }
+   }
+   mutex_unlock(_mutex);
+   return ctx->tx_conf;
+}
+
+static void tls_hw_unhash(struct sock *sk)
+{
+   struct tls_context *ctx = tls_get_ctx(sk);
+   struct tls_device *dev;
+
+   mutex_lock(_mutex);
+   list_for_each_entry(dev, _list, dev_list) {
+   if (dev->unhash)
+   dev->unhash(dev, sk);
+   }
+   mutex_unlock(_mutex);
+   ctx->unhash(sk);
+}
+
+static int tls_hw_hash(struct sock *sk)
+{
+   struct tls_context *ctx = tls_get_ctx(sk);
+   struct tls_device *dev;
+   int err;
+
+   err = ctx->hash(sk);
+   mutex_lock(_mutex);
+   list_for_each_entry(dev, _list, dev_list) {
+   if (dev->hash)
+   err |= dev->hash(dev, sk);
+   }
+   mutex_unlock(_mutex);
+
+   if (err)
+   tls_hw_unhash(sk);
+   return err;
+}
+
 static int tls_init(struct sock *sk)
 {
struct inet_connection_sock *icsk = inet_csk(sk);
@@ -477,6 +526,9 @@ static int tls_init(struct sock *sk)
ctx->sk_proto_close = sk->sk_prot->close;
 
ctx->tx_conf = TLS_BASE_TX;
+   if (tls_hw_prot(sk) == TLS_FULL_HW)
+   goto out;
+
update_sk_prot(sk, ctx);
 out:
return rc;
@@ -500,7 +552,27 @@ static void build_protos(struct proto *prot, struct proto 
*base)
prot[TLS_SW_TX] = prot[TLS_BASE_TX];
prot[TLS_SW_TX].sendmsg = tls_sw_sendmsg;
prot[TLS_SW_TX].sendpage= tls_sw_sendpage;
+
+   prot[TLS_FULL_HW] = prot[TLS_BASE_TX];
+   prot[TLS_FULL_HW].hash  = tls_hw_hash;
+   prot[TLS_FULL_HW].unhash= tls_hw_unhash;
+}
+
+void tls_register_device(struct tls_device *device)
+{
+   mutex_lock(_mutex);
+   list_add_tail(>dev_list, _list);
+   mutex_unlock(_mutex);
+}
+EXPORT_SYMBOL(tls_register_device);
+
+void tls_unregister_device(struct tls_device *device)
+{
+   mutex_lock(_mutex);
+   list_del(>dev_list);
+   mutex_unlock(_mutex);
 }
+EXPORT_SYMBOL(tls_unregister_device);
 
 static int __init tls_register(void)
 {
@@ -510,6 +582,7 @@ static int __init tls_register(void)
 
return 0;
 }
+EXPORT_SYMBOL(tls_prots);
 
 static void __exit tls_unregister(void)
 {
-- 
1.8.3.1



[crypto v8 01/12] tls: tls_device struct to register TLS drivers

2018-02-28 Thread Atul Gupta
tls_device structure to register Inline TLS drivers
with net/tls

Signed-off-by: Atul Gupta 
---
 include/net/tls.h | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/include/net/tls.h b/include/net/tls.h
index 4913430..9bfb91f 100644
--- a/include/net/tls.h
+++ b/include/net/tls.h
@@ -55,6 +55,28 @@
 #define TLS_RECORD_TYPE_DATA   0x17
 
 #define TLS_AAD_SPACE_SIZE 13
+#define TLS_DEVICE_NAME_MAX32
+
+enum {
+   TLS_BASE_TX,
+   TLS_SW_TX,
+   TLS_FULL_HW, /* TLS record processed Inline */
+   TLS_NUM_CONFIG,
+};
+
+extern struct proto tls_prots[TLS_NUM_CONFIG];
+
+struct tls_device {
+   char name[TLS_DEVICE_NAME_MAX];
+   struct list_head dev_list;
+
+   /* netdev present in registered inline tls driver */
+   int (*netdev)(struct tls_device *device,
+ struct net_device *netdev);
+   int (*feature)(struct tls_device *device);
+   int (*hash)(struct tls_device *device, struct sock *sk);
+   void (*unhash)(struct tls_device *device, struct sock *sk);
+};
 
 struct tls_sw_context {
struct crypto_aead *aead_send;
@@ -115,6 +137,8 @@ struct tls_context {
int  (*getsockopt)(struct sock *sk, int level,
   int optname, char __user *optval,
   int __user *optlen);
+   int (*hash)(struct sock *sk);
+   void (*unhash)(struct sock *sk);
 };
 
 int wait_on_pending_writer(struct sock *sk, long *timeo);
@@ -256,5 +280,7 @@ static inline struct tls_offload_context *tls_offload_ctx(
 
 int tls_proccess_cmsg(struct sock *sk, struct msghdr *msg,
  unsigned char *record_type);
+void tls_register_device(struct tls_device *device);
+void tls_unregister_device(struct tls_device *device);
 
 #endif /* _TLS_OFFLOAD_H */
-- 
1.8.3.1



[crypto v8 02/12] ethtool: enable Inline TLS in HW

2018-02-28 Thread Atul Gupta
Signed-off-by: Atul Gupta 
---
 include/linux/netdev_features.h | 2 ++
 net/core/ethtool.c  | 1 +
 2 files changed, 3 insertions(+)

diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index db84c51..aacabe2 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -79,6 +79,7 @@ enum {
NETIF_F_RX_UDP_TUNNEL_PORT_BIT, /* Offload of RX port for UDP tunnels */
 
NETIF_F_GRO_HW_BIT, /* Hardware Generic receive offload */
+   NETIF_F_HW_TLS_INLINE_BIT,  /* Offload TLS record */
 
/*
 * Add your fresh new feature above and remember to update
@@ -145,6 +146,7 @@ enum {
 #define NETIF_F_HW_ESP __NETIF_F(HW_ESP)
 #define NETIF_F_HW_ESP_TX_CSUM __NETIF_F(HW_ESP_TX_CSUM)
 #defineNETIF_F_RX_UDP_TUNNEL_PORT  __NETIF_F(RX_UDP_TUNNEL_PORT)
+#define NETIF_F_HW_TLS_INLINE  __NETIF_F(HW_TLS_INLINE)
 
 #define for_each_netdev_feature(mask_addr, bit)\
for_each_set_bit(bit, (unsigned long *)mask_addr, NETDEV_FEATURE_COUNT)
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 494e6a5..ab16781 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -107,6 +107,7 @@ int ethtool_op_get_ts_info(struct net_device *dev, struct 
ethtool_ts_info *info)
[NETIF_F_HW_ESP_BIT] =   "esp-hw-offload",
[NETIF_F_HW_ESP_TX_CSUM_BIT] =   "esp-tx-csum-hw-offload",
[NETIF_F_RX_UDP_TUNNEL_PORT_BIT] =   "rx-udp_tunnel-port-offload",
+   [NETIF_F_HW_TLS_INLINE_BIT] =   "tls-inline",
 };
 
 static const char
-- 
1.8.3.1



[crypto v8 00/12] Chelsio Inline TLS

2018-02-28 Thread Atul Gupta
Series for Chelsio Inline TLS driver (chtls.ko)

Use tls ULP infrastructure to register chtls as Inline TLS driver.
Chtls use TCP Sockets to transmit and receive TLS record. TCP proto_ops is 
extended to offload TLS record.

T6 adapter provides the following features:
-TLS record offload, TLS header, encrypt, digest and transmit
-TLS record receive and decrypt
-TLS keys store
-TCP/IP engine
-TLS engine
-GCM crypto engine [support CBC also]

TLS provides security at the transport layer. It uses TCP to provide reliable 
end-to-end transport of application data. It relies on TCP for any 
retransmission. TLS session comprises of three parts:
a. TCP/IP connection
b. TLS handshake
c. Record layer processing

TLS handshake state machine is executed in host (refer standard implementation 
eg. OpenSSL).  Setsockopt [SOL_TCP, TCP_ULP] initialize TCP proto-ops for 
Chelsio inline tls support. setsockopt(sock, SOL_TCP, TCP_ULP, "tls", 
sizeof("tls"));

Tx and Rx Keys are decided during handshake and programmed onto the chip after 
CCS is exchanged.
struct tls12_crypto_info_aes_gcm_128 crypto_info setsockopt(sock, SOL_TLS, 
TLS_TX, _info, sizeof(crypto_info)) Finish is the first 
encrypted/decrypted message tx/rx inline.

On the Tx path TLS engine receive plain text from openssl, insert IV, fetches 
the tx key, create cipher text records and generate MAC. TLS header is added to 
cipher text and forward to TCP/IP engine for transport layer processing and 
transmission on wire.
TX:
Application--openssl--chtls---TLS engine---encrypt/auth---TCP/IP engine---wire.

On the Rx side, data received is PDU aligned at record boundaries. TLS 
processes only the complete record. If rx key is programmed on CCS receive, 
data is decrypted and plain text is posted to host.
RX:
Wire--cipher-text--TCP/IP engine [PDU align]---TLS engine--- 
decrypt/auth---plain-text--chtls--openssl--application

v8: tls_main.c cleanup comment [Dave Watson]

v7: func name change, use sk->sk_prot where required

v6: modify prot only for FULL_HW
   -corrected commit message for patch 11

v5: set TLS_FULL_HW for registered inline tls drivers
   -set TLS_FULL_HW prot for offload connection else move
to TLS_SW_TX
   -Case handled for interface with same IP [Dave Miller]
   -Removed Specific IP and INADDR_ANY handling [v4]

v4: removed chtls ULP type, retained tls ULP
   -registered chtls with net tls
   -defined struct tls_device to register the Inline drivers
   -ethtool interface tls-inline to enable Inline TLS for interface
   -prot update to support inline TLS

v3: fixed the kbuild test issues
   -made few funtions static
   -initialized few variables

v2: fixed the following based on the review comments of Stephan Mueller,
Stefano Brivio and Hannes Frederic
-Added more details in cover letter
-Fixed indentation and formating issues
-Using aes instead of aes-generic
-memset key info after programing the key on chip
-reordered the patch sequence
Atul Gupta (12):
  tls: tls_device struct to register TLS drivers
  ethtool: enable Inline TLS in HW
  tls: support for inline tls
  chtls: structure and macro definiton
  cxgb4: Inline TLS FW Interface
  cxgb4: LLD driver changes to enable TLS
  chcr: Key Macro
  chtls: Key program
  chtls: CPL handler definition
  chtls: Inline crypto request Tx/Rx
  chtls: Register chtls Inline TLS with net tls
  Makefile Kconfig

 drivers/crypto/chelsio/Kconfig  |   11 +
 drivers/crypto/chelsio/Makefile |1 +
 drivers/crypto/chelsio/chcr_algo.h  |   42 +
 drivers/crypto/chelsio/chcr_core.h  |   55 +-
 drivers/crypto/chelsio/chtls/Makefile   |4 +
 drivers/crypto/chelsio/chtls/chtls.h|  487 ++
 drivers/crypto/chelsio/chtls/chtls_cm.c | 2041 +++
 drivers/crypto/chelsio/chtls/chtls_cm.h |  202 +++
 drivers/crypto/chelsio/chtls/chtls_hw.c |  394 +
 drivers/crypto/chelsio/chtls/chtls_io.c | 1867 +
 drivers/crypto/chelsio/chtls/chtls_main.c   |  600 +++
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c |   32 +-
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h  |7 +
 drivers/net/ethernet/chelsio/cxgb4/sge.c|   98 +-
 drivers/net/ethernet/chelsio/cxgb4/t4_msg.h |  121 +-
 drivers/net/ethernet/chelsio/cxgb4/t4_regs.h|2 +
 drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h   |  165 +-
 include/linux/netdev_features.h |2 +
 include/net/tls.h   |   26 +
 include/uapi/linux/tls.h|1 +
 net/core/ethtool.c  |1 +
 net/ipv4/tcp_minisocks.c|1 +
 net/tls/tls_main.c  |   87 +-
 23 files changed, 6223 insertions(+), 24 deletions(-)
 create mode 100644 drivers/crypto/chelsio/chtls/Makefile
 create mode 100644 

Re: [PATCH 3/3] crypto: ccp - protect RSA implementation from too large input data

2018-02-28 Thread Gary R Hook

On 02/24/2018 10:03 AM, Maciej S. Szmigiero wrote:

CCP RSA implementation uses a hardware input buffer which size depends only
on the current RSA key length. Key modulus and a message to be processed
is then copied to this buffer based on their own lengths.

Since the price for providing too long input data is a buffer overflow and
there already has been a case when this has happened let's better reject
such oversized input data and log an error message in this case so we know
what is going on.

Signed-off-by: Maciej S. Szmigiero 
---
  drivers/crypto/ccp/ccp-ops.c | 24 
  1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c
index 406b95329b3d..517aeee30abf 100644
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -1770,10 +1770,6 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, 
struct ccp_cmd *cmd)
if (!rsa->exp || !rsa->mod || !rsa->src || !rsa->dst)
return -EINVAL;
  
-	memset(, 0, sizeof(op));

-   op.cmd_q = cmd_q;
-   op.jobid = CCP_NEW_JOBID(cmd_q->ccp);
-
/* The RSA modulus must precede the message being acted upon, so
 * it must be copied to a DMA area where the message and the
 * modulus can be concatenated.  Therefore the input buffer
@@ -1785,6 +1781,26 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, 
struct ccp_cmd *cmd)
o_len = 32 * ((rsa->key_size + 255) / 256);
i_len = o_len * 2;
  
+	if (rsa->mod_len > o_len) {

+   dev_err(cmd_q->ccp->dev,
+   "RSA modulus of %u bytes too large for key size of %u 
bits\n",
+   (unsigned int)rsa->mod_len,
+   (unsigned int)rsa->key_size);
+   return -EINVAL;
+   }
+
+   if (rsa->src_len > o_len) {
+   dev_err(cmd_q->ccp->dev,
+   "RSA data of %u bytes too large for key size of %u 
bits\n",
+   (unsigned int)rsa->src_len,
+   (unsigned int)rsa->key_size);
+   return -EINVAL;
+   }


We've talked about this, and we believe that a more central fix is 
warranted. I intend to post another patch tomorrow that should address

this problem.


+
+   memset(, 0, sizeof(op));
+   op.cmd_q = cmd_q;
+   op.jobid = CCP_NEW_JOBID(cmd_q->ccp);
+
sb_count = 0;
if (cmd_q->ccp->vdata->version < CCP_VERSION(5, 0)) {
/* sb_count is the number of storage block slots required





Re: [PATCH 2/3] crypto: ccp - return an actual key size from RSA max_size callback

2018-02-28 Thread Gary R Hook

On 02/24/2018 10:03 AM, Maciej S. Szmigiero wrote:

rsa-pkcs1pad uses a value returned from a RSA implementation max_size
callback as a size of an input buffer passed to the RSA implementation for
encrypt and sign operations.

CCP RSA implementation uses a hardware input buffer which size depends only
on the current RSA key length, so it should return this key length in
the max_size callback, too.
This also matches what the kernel software RSA implementation does.

Previously, the value returned from this callback was always the maximum
RSA key size the CCP hardware supports.
This resulted in this huge buffer being passed by rsa-pkcs1pad to CCP even
for smaller key sizes and then in a buffer overflow when ccp_run_rsa_cmd()
tried to copy this large input buffer into a RSA key length-sized hardware
input buffer.

Signed-off-by: Maciej S. Szmigiero 


Acked-by: Gary R Hook 


Fixes: ceeec0afd684 ("crypto: ccp - Add support for RSA on the CCP")
Cc: sta...@vger.kernel.org
---
  drivers/crypto/ccp/ccp-crypto-rsa.c | 7 +++
  1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/crypto/ccp/ccp-crypto-rsa.c 
b/drivers/crypto/ccp/ccp-crypto-rsa.c
index e6db8672d89c..05850dfd7940 100644
--- a/drivers/crypto/ccp/ccp-crypto-rsa.c
+++ b/drivers/crypto/ccp/ccp-crypto-rsa.c
@@ -60,10 +60,9 @@ static int ccp_rsa_complete(struct crypto_async_request 
*async_req, int ret)
  
  static unsigned int ccp_rsa_maxsize(struct crypto_akcipher *tfm)

  {
-   if (ccp_version() > CCP_VERSION(3, 0))
-   return CCP5_RSA_MAXMOD;
-   else
-   return CCP_RSA_MAXMOD;
+   struct ccp_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+   return ctx->u.rsa.n_len;
  }
  
  static int ccp_rsa_crypt(struct akcipher_request *req, bool encrypt)






[PATCH] Crypto:Chelsio: no csum offload for ipsec path

2018-02-28 Thread Atul Gupta
The Inline IPSec driver does not offload csum.

Signed-off-by: Atul Gupta 
---
 drivers/crypto/chelsio/chcr_ipsec.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/crypto/chelsio/chcr_ipsec.c 
b/drivers/crypto/chelsio/chcr_ipsec.c
index db1e241..8e0aa3f 100644
--- a/drivers/crypto/chelsio/chcr_ipsec.c
+++ b/drivers/crypto/chelsio/chcr_ipsec.c
@@ -360,8 +360,7 @@ inline void *copy_cpltx_pktxt(struct sk_buff *skb,
 
cpl = (struct cpl_tx_pkt_core *)pos;
 
-   if (skb->ip_summed == CHECKSUM_PARTIAL)
-   cntrl = TXPKT_L4CSUM_DIS_F | TXPKT_IPCSUM_DIS_F;
+   cntrl = TXPKT_L4CSUM_DIS_F | TXPKT_IPCSUM_DIS_F;
ctrl0 = TXPKT_OPCODE_V(CPL_TX_PKT_XT) | TXPKT_INTF_V(pi->tx_chan) |
   TXPKT_PF_V(adap->pf);
if (skb_vlan_tag_present(skb)) {
@@ -475,7 +474,7 @@ inline void *chcr_crypto_wreq(struct sk_buff *skb,
wr->req.ulptx.len = htonl(DIV_ROUND_UP(flits, 2)  - 1);
 
/* Sub-command */
-   wr->req.sc_imm.cmd_more = FILL_CMD_MORE(immdatalen);
+   wr->req.sc_imm.cmd_more = FILL_CMD_MORE(!immdatalen);
wr->req.sc_imm.len = cpu_to_be32(sizeof(struct cpl_tx_sec_pdu) +
 sizeof(wr->req.key_ctx) +
 kctx_len +
-- 
1.8.3.1



[RFC PATCH 5/5] KEYS: add KPP ecdh parser

2018-02-28 Thread Tudor Ambarus
The ECDH private keys are expected to be encoded with the ecdh
helpers from kernel.

Use the ecdh helpers to check if the key is valid. If valid,
allocate a tfm and set the private key. There is a one-to-one
binding between the private key and the tfm. The tfm is allocated
once and used as many times as needed.

ECDH keys can be loaded like this:
# echo -n 
020028000200200024d121ebe5cf2d83f6621b6e43843aa38be086c32019da92505303e1c0eab882
 \
| xxd -r -p | keyctl padd asymmetric private @s

Signed-off-by: Tudor Ambarus 
---
 crypto/asymmetric_keys/Kconfig  |   8 +++
 crypto/asymmetric_keys/Makefile |   5 ++
 crypto/asymmetric_keys/kpp_parser.c | 124 
 include/crypto/asym_kpp_subtype.h   |   2 +
 4 files changed, 139 insertions(+)
 create mode 100644 crypto/asymmetric_keys/kpp_parser.c

diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
index 1884570..e46a185 100644
--- a/crypto/asymmetric_keys/Kconfig
+++ b/crypto/asymmetric_keys/Kconfig
@@ -57,6 +57,14 @@ config PKCS7_MESSAGE_PARSER
  This option provides support for parsing PKCS#7 format messages for
  signature data and provides the ability to verify the signature.
 
+config KPP_KEY_PARSER
+   tristate "KPP private key parser"
+   depends on ASYMMETRIC_KPP_SUBTYPE
+   help
+ This option provides support for parsing KPP format blobs for
+ private key data and provides the ability to instantiate a crypto key
+ from that data.
+
 config PKCS7_TEST_KEY
tristate "PKCS#7 testing key type"
depends on SYSTEM_DATA_VERIFICATION
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index d884cf1..e709aee 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -62,6 +62,11 @@ $(obj)/pkcs7-asn1.o: $(obj)/pkcs7-asn1.c $(obj)/pkcs7-asn1.h
 clean-files+= pkcs7-asn1.c pkcs7-asn1.h
 
 #
+# KPP private key handling
+#
+obj-$(CONFIG_KPP_KEY_PARSER) += kpp_parser.o
+
+#
 # PKCS#7 parser testing key
 #
 obj-$(CONFIG_PKCS7_TEST_KEY) += pkcs7_test_key.o
diff --git a/crypto/asymmetric_keys/kpp_parser.c 
b/crypto/asymmetric_keys/kpp_parser.c
new file mode 100644
index 000..a38da7b
--- /dev/null
+++ b/crypto/asymmetric_keys/kpp_parser.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0
+#define pr_fmt(fmt) "KPP-PARSER: "fmt
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int decode_kpp_ecdh_key(struct asym_kpp_ctx *ctx,
+  const void *data, size_t datalen)
+{
+   struct ecdh params;
+   int ret;
+
+   /* check if the key is valid */
+   ret = crypto_ecdh_decode_key(data, datalen, );
+   if (ret)
+   return ret;
+
+   ctx->alg_name = "ecdh";
+   return ret;
+}
+
+static int decode_kpp_key(struct asym_kpp_ctx *ctx,
+ const void *data, size_t datalen)
+{
+   if (decode_kpp_ecdh_key(ctx, data, datalen))
+   return -EBADMSG;
+   return 0;
+}
+
+static int kpp_parser_setkey(struct asym_kpp_ctx *ctx,
+const void *data, size_t datalen)
+{
+   struct crypto_kpp *tfm;
+   int ret;
+
+   tfm = crypto_alloc_kpp(ctx->alg_name, 0, 0);
+   if (IS_ERR(tfm))
+   return PTR_ERR(tfm);
+
+   ret = crypto_kpp_set_secret(tfm, data, datalen);
+   if (ret) {
+   crypto_free_kpp(tfm);
+   return ret;
+   }
+
+   ctx->tfm = tfm;
+   return ret;
+}
+
+static struct asym_kpp_ctx *kpp_parse(const void *data, size_t datalen)
+{
+   struct asym_kpp_ctx *ctx;
+   long ret;
+
+   ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
+   if (!ctx)
+   return ERR_PTR(-ENOMEM);
+
+   ret = decode_kpp_key(ctx, data, datalen);
+   if (ret)
+   goto free_ctx;
+
+   ret = kpp_parser_setkey(ctx, data, datalen);
+   if (ret)
+   goto free_ctx;
+
+   return ctx;
+
+free_ctx:
+   kfree(ctx);
+   return ERR_PTR(ret);
+}
+
+/*
+ * Attempt to parse a data blob for a key as a KPP private key.
+ */
+static int kpp_key_preparse(struct key_preparsed_payload *prep)
+{
+   struct asym_kpp_ctx *ctx;
+
+   ctx = kpp_parse(prep->data, prep->datalen);
+   if (IS_ERR(ctx))
+   return PTR_ERR(ctx);
+
+   pr_devel("Algorithm name: %s\n", ctx->alg_name);
+
+   /* We're pinning the module by being linked against it */
+   __module_get(asym_kpp_subtype.owner);
+   prep->payload.data[asym_subtype] = _kpp_subtype;
+   prep->payload.data[asym_key_ids] = NULL;
+   prep->payload.data[asym_crypto] = ctx;
+   prep->payload.data[asym_auth] = NULL;
+   prep->quotalen = 100;
+   return 0;
+}
+
+static struct asymmetric_key_parser kpp_key_parser = {
+   .owner  = THIS_MODULE,
+   .name   = 

[RFC PATCH 3/5] KEYS: Provide missing asym kpp subops for new key type ops

2018-02-28 Thread Tudor Ambarus
Includes kpp_query, kpp_gen_pubkey and kpp_compute_ss.

Signed-off-by: Tudor Ambarus 
---
 crypto/asymmetric_keys/asymmetric_type.c | 77 
 include/keys/asymmetric-subtype.h| 12 +
 2 files changed, 89 insertions(+)

diff --git a/crypto/asymmetric_keys/asymmetric_type.c 
b/crypto/asymmetric_keys/asymmetric_type.c
index 3cd4315..cdc0974e 100644
--- a/crypto/asymmetric_keys/asymmetric_type.c
+++ b/crypto/asymmetric_keys/asymmetric_type.c
@@ -578,6 +578,80 @@ static int asymmetric_key_verify_signature(struct 
kernel_pkey_params *params,
return verify_signature(params->key, );
 }
 
+int query_asym_kpp_key(const struct kernel_kpp_params *params,
+  struct kernel_kpp_query *res)
+{
+   const struct asymmetric_key_subtype *subtype;
+   struct key *key = params->key;
+   int ret;
+
+   pr_devel("==>%s()\n", __func__);
+
+   if (key->type != _type_asymmetric)
+   return -EINVAL;
+
+   subtype = asymmetric_key_subtype(key);
+   if (!subtype || !key->payload.data[0])
+   return -EINVAL;
+
+   if (!subtype->kpp_query)
+   return -ENOTSUPP;
+
+   ret = subtype->kpp_query(params, res);
+
+   pr_devel("<==%s() = %d\n", __func__, ret);
+   return ret;
+}
+
+int asymmetric_key_kpp_gen_pubkey(struct kernel_kpp_params *params, void *out)
+{
+   const struct asymmetric_key_subtype *subtype;
+   struct key *key = params->key;
+   int ret;
+
+   pr_devel("==>%s()\n", __func__);
+
+   if (key->type != _type_asymmetric)
+   return -EINVAL;
+
+   subtype = asymmetric_key_subtype(key);
+   if (!subtype || !key->payload.data[0])
+   return -EINVAL;
+
+   if (!subtype->kpp_gen_pubkey)
+   return -ENOTSUPP;
+
+   ret = subtype->kpp_gen_pubkey(params, out);
+
+   pr_devel("<==%s() = %d\n", __func__, ret);
+   return ret;
+}
+
+int asymmetric_key_kpp_compute_ss(struct kernel_kpp_params *params,
+ const void *in, void *out)
+{
+   const struct asymmetric_key_subtype *subtype;
+   struct key *key = params->key;
+   int ret;
+
+   pr_devel("==>%s()\n", __func__);
+
+   if (key->type != _type_asymmetric)
+   return -EINVAL;
+
+   subtype = asymmetric_key_subtype(key);
+   if (!subtype || !key->payload.data[0])
+   return -EINVAL;
+
+   if (!subtype->kpp_compute_ss)
+   return -ENOTSUPP;
+
+   ret = subtype->kpp_compute_ss(params, in, out);
+
+   pr_devel("<==%s() = %d\n", __func__, ret);
+   return ret;
+}
+
 struct key_type key_type_asymmetric = {
.name   = "asymmetric",
.preparse   = asymmetric_key_preparse,
@@ -591,6 +665,9 @@ struct key_type key_type_asymmetric = {
.asym_query = query_asymmetric_key,
.asym_eds_op= asymmetric_key_eds_op,
.asym_verify_signature  = asymmetric_key_verify_signature,
+   .asym_kpp_query = query_asym_kpp_key,
+   .asym_kpp_gen_pubkey= asymmetric_key_kpp_gen_pubkey,
+   .asym_kpp_compute_ss= asymmetric_key_kpp_compute_ss,
 };
 EXPORT_SYMBOL_GPL(key_type_asymmetric);
 
diff --git a/include/keys/asymmetric-subtype.h 
b/include/keys/asymmetric-subtype.h
index bd12733..5f9bece 100644
--- a/include/keys/asymmetric-subtype.h
+++ b/include/keys/asymmetric-subtype.h
@@ -20,6 +20,8 @@
 struct kernel_pkey_query;
 struct kernel_pkey_params;
 struct public_key_signature;
+struct kernel_kpp_query;
+struct kernel_kpp_params;
 
 /*
  * Keys of this type declare a subtype that indicates the handlers and
@@ -46,6 +48,16 @@ struct asymmetric_key_subtype {
/* Verify the signature on a key of this subtype (optional) */
int (*verify_signature)(const struct key *key,
const struct public_key_signature *sig);
+
+   int (*kpp_query)(const struct kernel_kpp_params *params,
+struct kernel_kpp_query *res);
+
+   /* Generate public key */
+   int (*kpp_gen_pubkey)(struct kernel_kpp_params *params, void *out);
+
+   /* Compute shared secret */
+   int (*kpp_compute_ss)(struct kernel_kpp_params *params,
+ const void *in, void *out);
 };
 
 /**
-- 
2.9.4



[RFC PATCH 4/5] KEYS: add asymmetric kpp subtype

2018-02-28 Thread Tudor Ambarus
Includes generation of public key and computation of shared secret.
This mostly involves offloading the calls to the crypto layer.

The crypto tfm was allocated and the private key was set when parsing
the private key. This permits us to use a single tfm whatever the
number of operation calls.

The private key, the corresponding public key, the pair's public key
and the shared secret are the same as those in crypto/testmgr.h:

# echo -n 
020028000200200024d121ebe5cf2d83f6621b6e43843aa38be086c32019da92505303e1c0eab882
 \
| xxd -r -p | keyctl padd asymmetric private @s
# keyctl kpp_query 266205365
max_size=64
kpp_gen_pubkey=y
kpp_compute_ss=y
# keyctl kpp_gen_pubkey 266205365 | xxd -p
1a7feb5200bd3c317db670c186a6c7c43bc55f6c6f583cf5b66382773324
a15f6aca436ff77eff023708cc405e7afd6a6a026e4187683877faa94443
2def09df
# echo -n 
ccb4da74b1473fea6c709e382dc7aab729b2470319abdd34bda82c93e1a474d96463f770202fa4e69f4a38ccc02c492fb132bbaf2261dacb6fdba9aafc7781f3
 | xxd -r -p > /tmp/bpub
# keyctl kpp_compute_ss 266205365 0 /tmp/bpub | xxd -p
ea176f7e6e5726388bfb41ebbac86da5a872d1ffc9473daa58439f340f8c
f3c9

Signed-off-by: Tudor Ambarus 
---
 crypto/asymmetric_keys/Kconfig|   7 ++
 crypto/asymmetric_keys/Makefile   |   1 +
 crypto/asymmetric_keys/asym_kpp.c | 142 ++
 include/crypto/asym_kpp_subtype.h |  12 
 4 files changed, 162 insertions(+)
 create mode 100644 crypto/asymmetric_keys/asym_kpp.c
 create mode 100644 include/crypto/asym_kpp_subtype.h

diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
index 66a7dad..1884570 100644
--- a/crypto/asymmetric_keys/Kconfig
+++ b/crypto/asymmetric_keys/Kconfig
@@ -21,6 +21,13 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
  appropriate hash algorithms (such as SHA-1) must be available.
  ENOPKG will be reported if the requisite algorithm is unavailable.
 
+config ASYMMETRIC_KPP_SUBTYPE
+   tristate "Asymmetric Key Protocol Primitives (KPP) subtype"
+   select CRYPTO_ECDH
+   help
+ This option provides support for KPP handling.
+ ENOPKG will be reported if the requisite algorithm is unavailable.
+
 config X509_CERTIFICATE_PARSER
tristate "X.509 certificate parser"
depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index a67ad83..d884cf1 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -11,6 +11,7 @@ asymmetric_keys-y := \
signature.o
 
 obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
+obj-$(CONFIG_ASYMMETRIC_KPP_SUBTYPE) += asym_kpp.o
 
 #
 # X.509 Certificate handling
diff --git a/crypto/asymmetric_keys/asym_kpp.c 
b/crypto/asymmetric_keys/asym_kpp.c
new file mode 100644
index 000..77e085f
--- /dev/null
+++ b/crypto/asymmetric_keys/asym_kpp.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0
+#define pr_fmt(fmt) "ASYM-KPP: "fmt
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Provide a part of a description of the key for /proc/keys.
+ */
+static void asym_kpp_describe(const struct key *asymmetric_key,
+ struct seq_file *m)
+{
+   struct asym_kpp_ctx *ctx = asymmetric_key->payload.data[asym_crypto];
+
+   if (ctx)
+   seq_printf(m, "%s", ctx->alg_name);
+}
+
+static void free_kpp_ctx(struct asym_kpp_ctx *ctx)
+{
+   if (ctx) {
+   if (ctx->tfm)
+   crypto_free_kpp(ctx->tfm);
+   kfree(ctx);
+   }
+}
+
+static void asym_kpp_destroy(void *payload0, void *payload3)
+{
+   free_kpp_ctx(payload0);
+}
+
+/*
+ * Query information about a key.
+ */
+static int software_kpp_query(const struct kernel_kpp_params *params,
+ struct kernel_kpp_query *res)
+{
+   struct asym_kpp_ctx *ctx = params->key->payload.data[asym_crypto];
+
+   res->max_size = crypto_kpp_maxsize(ctx->tfm);
+   res->supported_ops = KEYCTL_KPP_GEN_PUBKEY | KEYCTL_KPP_COMPUTE_SS;
+
+   pr_devel("<==%s() = %d\n", __func__, 0);
+   return 0;
+}
+
+/*
+ * Generate public key.
+ */
+static int software_kpp_gen_pubkey(struct kernel_kpp_params *params, void *out)
+{
+   struct crypto_wait cwait;
+   const struct asym_kpp_ctx *ctx = params->key->payload.data[asym_crypto];
+   struct kpp_request *req;
+   struct scatterlist out_sg;
+   int ret;
+
+   pr_devel("==>%s()\n", __func__);
+
+   req = kpp_request_alloc(ctx->tfm, GFP_KERNEL);
+   if (!req)
+   return -ENOMEM;
+
+   kpp_request_set_input(req, NULL, 0);
+   sg_init_one(_sg, out, params->out_len);
+   kpp_request_set_output(req, _sg, params->out_len);
+   crypto_init_wait();
+   kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
+

[RFC PATCH 2/5] KEYS: Provide keyctls to drive the new key type ops for kpp

2018-02-28 Thread Tudor Ambarus
Provide three keyctl functions that permit userspace to make use of the new
key type ops for accessing and driving asymmetric kpp keys.

(*) Query an asymmetric kpp key.

long keyctl(KEYCTL_KPP_QUERY,
key_serial_t key, struct keyctl_kpp_query *res);

Get information about an asymmetric kpp key. The information is
returned in the keyctl_kpp_query struct:

__u32   supported_ops;

A bit mask of flags indicating which ops are supported. This
is constructed from a bitwise-OR of:

KEYCTL_SUPPORTS_{GEN_PUBKEY, COMPUTE_SS}

__u32   max_size;

The maximum size in bytes of the key.

__spare must be set to 0.  This is intended for future use to hand
over one or more passphrases needed to unlock a key.

If successful, 0 is returned.  If the key is not an asymmetric kpp key,
EOPNOTSUPP is returned.

(*) Generate the public key or compute the shared secret using an
asymmetric kpp key.

long keyctl(KEYCTL_KPP_GEN_PUBKEY,
const struct keyctl_kpp_params *params,
void *out);

long keyctl(KEYCTL_KPP_GEN_PUBKEY,
const struct keyctl_kpp_params *params,
const void *in, void *out);

The parameter block pointed by params contains a number of integer
values:
__s32   key_id;
__u32   in_len;
__u32   out_len;

For a given operation, the in and out buffers are used as follows:

Operation IDin,in_lenout,out_len
=== ===  
KEYCTL_KPP_GEN_PUBKEY   -Corresponding public key
KEYCTL_KPP_COMPUTE_SS   Pair's public keyShared Secret

The __spare space in the parameter block must be set to 0.  This is
intended, amongst other things, to allow the passing of passphrases
required to unlock a key.

If successful, the public key generation and the shared secret computation
will return the amount of data written into the output buffer.

Signed-off-by: Tudor Ambarus 
---
 Documentation/security/keys/core.rst |  59 ++
 include/uapi/linux/keyctl.h  |  16 +++
 security/keys/Makefile   |   1 +
 security/keys/compat.c   |  10 ++
 security/keys/internal.h |  28 +
 security/keys/keyctl.c   |  13 +++
 security/keys/keyctl_kpp.c   | 205 +++
 7 files changed, 332 insertions(+)
 create mode 100644 security/keys/keyctl_kpp.c

diff --git a/Documentation/security/keys/core.rst 
b/Documentation/security/keys/core.rst
index 9b69a1f..31b9501 100644
--- a/Documentation/security/keys/core.rst
+++ b/Documentation/security/keys/core.rst
@@ -994,6 +994,65 @@ The keyctl syscall functions are:
  If successful, encrypt, decrypt and sign all return the amount of data
  written into the output buffer.  Verification returns 0 on success.
 
+  *  Query an asymmetric kpp key::
+
+   long keyctl(KEYCTL_KPP_QUERY,
+   key_serial_t key, struct keyctl_kpp_query *res);
+
+ Get information about an asymmetric kpp key. The information is
+ returned in the keyctl_kpp_query struct::
+
+   struct keyctl_kpp_query {
+   __u32   supported_ops;  /* Which ops are supported */
+   __u32   max_size;   /* Maximum size of the output 
buffer in bytes */
+   __u32   __spare[10];
+   };
+
+ ``__u32   supported_ops;`` is a bit mask of flags indicating which ops are
+ supported.  This is constructed from a bitwise-OR of::
+
+KEYCTL_SUPPORTS_{GEN_PUBKEY, COMPUTE_SS}
+
+ ``__spare`` must be set to 0.  This is intended for future use to hand
+ over one or more passphrases needed to unlock a key.
+
+ If successful, 0 is returned.  If the key is not an asymmetric kpp key,
+ EOPNOTSUPP is returned.
+
+  *  Generate the public key or compute the shared secret using an asymmetric
+ kpp key::
+
+   long keyctl(KEYCTL_KPP_GEN_PUBKEY,
+   const struct keyctl_kpp_params *params,
+   void *out);
+
+   long keyctl(KEYCTL_KPP_GEN_PUBKEY,
+   const struct keyctl_kpp_params *params,
+   const void *in, void *out);
+
+ The parameter block pointed by params contains a number of integer
+ values::
+__s32   key_id;
+__u32   in_len;
+__u32   out_len;
+
+ ``key_id`` is the key tp be used and ``in_len`` and ``out_len`` are the
+ lengths in bytes of the input and output buffers.
+
+ For a given operation, the in and out buffers are used as follows::
+
+   Operation IDin,in_lenout,out_len
+   === ===  

[RFC PATCH 1/5] KEYS: Provide key type operations for kpp ops

2018-02-28 Thread Tudor Ambarus
Provide three new operations in the key_type struct that can be used to
provide access to kpp operations. These will be implemented for the
asymmetric key type in a later patch and may refer to a key retained in
RAM by the kernel or a key retained in crypto hardware.

int (*asym_kpp_query)(const struct kernel_kpp_params *params,
  struct kernel_kpp_query *res);
int (*asym_kpp_gen_pubkey)(struct kernel_kpp_params *params,
   void *out);
int (*asym_kpp_compute_ss)(struct kernel_kpp_params *params,
   const void *in, void *out);

Signed-off-by: Tudor Ambarus 
---
 Documentation/security/keys/core.rst | 54 
 include/linux/key-type.h |  7 +
 include/linux/keyctl.h   | 11 
 include/uapi/linux/keyctl.h  |  3 ++
 4 files changed, 75 insertions(+)

diff --git a/Documentation/security/keys/core.rst 
b/Documentation/security/keys/core.rst
index d224fd0..9b69a1f 100644
--- a/Documentation/security/keys/core.rst
+++ b/Documentation/security/keys/core.rst
@@ -1688,6 +1688,60 @@ The structure has a number of fields, some of which are 
mandatory:
  If successful, 0 will be returned.  If the key doesn't support this,
  EOPNOTSUPP will be returned.
 
+  *  ``int (*asym_kpp_gen_pubkey)(struct kernel_kpp_params *params, void 
*out);``
+  *  ``int (*asym_kpp_compute_ss)(struct kernel_kpp_params *params, const void 
*in, void *out);``
+
+ These methods are optional. If provided the first allows to generate the
+ public key pair corresponding to the private key. The second method allows
+ to generate a shared secret by  combining the private key and the other
+ party's public key.
+
+ In all cases, the following information is provided in the params block::
+
+   struct kernel_kpp_query {
+   struct key  *key;
+   __u32   in_len; /* Input data size */
+   __u32   out_len;/* Output buffer size */
+   }
+
+ This includes the key to be used and the sizes in bytes of the input and
+ output buffers.
+
+ For a given operation, the in and out buffers are used as follows::
+
+   Operation IDin,in_lenout,out_len
+   === ===  
+   KEYCTL_KPP_GEN_PUBKEY   -Corresponding public key
+   KEYCTL_KPP_COMPUTE_SS   Pair's public keyShared Secret
+
+ If successful, the public key generation and the shared secret computation
+ will return the amount of data written into the output buffer.
+
+  *  ``int (*asym_kpp_query)(const struct kernel_kpp_params *params, struct 
kernel_kpp_query *res);``
+
+ This method is optional. If provided it allows information about the
+ asymmetric KPP (Key Protocol Primitives) key held in the key to be
+ determined.
+
+ The ``params`` block will contain the key to be queried. ``in_len`` and
+ ``out_len`` are unused.
+
+ If successful, the following information is filled in::
+
+   struct kernel_kpp_query {
+   __u32   supported_ops;  /* Which ops are supported */
+   __u32   max_size;   /* Maximum size of the output 
buffer */
+   };
+
+ The supported_ops field will contain a bitmask indicating what operations
+ are supported by the key, including public key generation and shared
+ secret computation. The following constants are defined for this::
+
+   KEYCTL_SUPPORTS_{GEN_PUBKEY, COMPUTE_SS};
+
+ If successful, 0 is returned.  If the key is not an asymmetric kpp key,
+ EOPNOTSUPP is returned.
+
 
 Request-Key Callback Service
 
diff --git a/include/linux/key-type.h b/include/linux/key-type.h
index bc9af55..d354b6b 100644
--- a/include/linux/key-type.h
+++ b/include/linux/key-type.h
@@ -19,6 +19,8 @@
 
 struct kernel_pkey_query;
 struct kernel_pkey_params;
+struct kernel_kpp_query;
+struct kernel_kpp_params;
 
 /*
  * key under-construction record
@@ -165,6 +167,11 @@ struct key_type {
   const void *in, void *out);
int (*asym_verify_signature)(struct kernel_pkey_params *params,
 const void *in, const void *in2);
+   int (*asym_kpp_query)(const struct kernel_kpp_params *params,
+ struct kernel_kpp_query *res);
+   int (*asym_kpp_gen_pubkey)(struct kernel_kpp_params *params, void *out);
+   int (*asym_kpp_compute_ss)(struct kernel_kpp_params *params,
+  const void *in, void *out);
 
/* internal fields */
struct list_headlink;   /* link in types list */
diff --git a/include/linux/keyctl.h b/include/linux/keyctl.h
index e89b4a4..8f464ea 100644
--- a/include/linux/keyctl.h
+++ 

[RFC PATCH 0/5] KEYS: add kpp keyctl operations

2018-02-28 Thread Tudor Ambarus
This series provides keyctl access for kpp operations, including
a query function, a function to generate the public key that is
associated with the private key and a function to compute the
shared secret.

I've added a KPP ecdh parser so that you can load an ECDH private
key into the kernel. The ECDH private keys are expected to be encoded
with the ecdh helpers from kernel. If the private key is valid, the
parser will allocate a tfm and set the private key. There is a
one-to-one binding between the private key and the tfm. The tfm will be
associated with the key for the entire life of the key. The tfm is
allocated once and used as many times as needed.

The kernel patches can be found here also:

https://github.com/ambarus/linux/commits/keys-kpp

The keyutils changes can be found here:

https://github.com/ambarus/keyutils/commits/keys-kpp

These patches are similar to what David Howells proposed for akcipher:

https://www.mail-archive.com/linux-crypto@vger.kernel.org/msg19915.html

I've ported David's patches on top of keys-next and then I've added my
patches on top of them.

Both proposals, David's and mine, lack support for accessing TPM.
Before getting familiar with TPM, please let me know how you feel
about this series.

Tudor Ambarus (5):
  KEYS: Provide key type operations for kpp ops
  KEYS: Provide keyctls to drive the new key type ops for kpp
  KEYS: Provide missing asym kpp subops for new key type ops
  KEYS: add asymmetric kpp subtype
  KEYS: add KPP ecdh parser

 Documentation/security/keys/core.rst | 113 +
 crypto/asymmetric_keys/Kconfig   |  15 +++
 crypto/asymmetric_keys/Makefile  |   6 +
 crypto/asymmetric_keys/asym_kpp.c| 142 +
 crypto/asymmetric_keys/asymmetric_type.c |  77 
 crypto/asymmetric_keys/kpp_parser.c  | 124 +++
 include/crypto/asym_kpp_subtype.h|  14 +++
 include/keys/asymmetric-subtype.h|  12 ++
 include/linux/key-type.h |   7 ++
 include/linux/keyctl.h   |  11 ++
 include/uapi/linux/keyctl.h  |  19 +++
 security/keys/Makefile   |   1 +
 security/keys/compat.c   |  10 ++
 security/keys/internal.h |  28 +
 security/keys/keyctl.c   |  13 ++
 security/keys/keyctl_kpp.c   | 205 +++
 16 files changed, 797 insertions(+)
 create mode 100644 crypto/asymmetric_keys/asym_kpp.c
 create mode 100644 crypto/asymmetric_keys/kpp_parser.c
 create mode 100644 include/crypto/asym_kpp_subtype.h
 create mode 100644 security/keys/keyctl_kpp.c

-- 
2.9.4



[PATCH 2/2] hwrng: omap - Fix clock resource by adding a register clock

2018-02-28 Thread Gregory CLEMENT
On Armada 7K/8K we need to explicitly enable the register clock. This
clock is optional because not all the SoCs using this IP need it but at
least for Armada 7K/8K it is actually mandatory.

The binding documentation is updating accordingly.

Signed-off-by: Gregory CLEMENT 
---
 Documentation/devicetree/bindings/rng/omap_rng.txt |  7 ++-
 drivers/char/hw_random/omap-rng.c  | 16 
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/rng/omap_rng.txt 
b/Documentation/devicetree/bindings/rng/omap_rng.txt
index 9cf7876ab434..ea434ce50f36 100644
--- a/Documentation/devicetree/bindings/rng/omap_rng.txt
+++ b/Documentation/devicetree/bindings/rng/omap_rng.txt
@@ -13,7 +13,12 @@ Required properties:
 - interrupts : the interrupt number for the RNG module.
Used for "ti,omap4-rng" and "inside-secure,safexcel-eip76"
 - clocks: the trng clock source. Only mandatory for the
-  "inside-secure,safexcel-eip76" compatible.
+  "inside-secure,safexcel-eip76" compatible, the second clock is
+  needed for the Armada 7K/8K SoCs
+- clock-names: mandatory if there is a second clock, in this case the
+  name must be "core" for the first clock and "reg" for the second
+  one
+
 
 Example:
 /* AM335x */
diff --git a/drivers/char/hw_random/omap-rng.c 
b/drivers/char/hw_random/omap-rng.c
index 159d4a1347b8..b65ff6962899 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -150,6 +150,7 @@ struct omap_rng_dev {
const struct omap_rng_pdata *pdata;
struct hwrng rng;
struct clk  *clk;
+   struct clk  *clk_reg;
 };
 
 static inline u32 omap_rng_read(struct omap_rng_dev *priv, u16 reg)
@@ -480,6 +481,19 @@ static int omap_rng_probe(struct platform_device *pdev)
}
}
 
+   priv->clk_reg = devm_clk_get(>dev, "reg");
+   if (IS_ERR(priv->clk_reg) && PTR_ERR(priv->clk_reg) == -EPROBE_DEFER)
+   return -EPROBE_DEFER;
+   if (!IS_ERR(priv->clk_reg)) {
+   ret = clk_prepare_enable(priv->clk_reg);
+   if (ret) {
+   dev_err(>dev,
+   "Unable to enable the register clk: %d\n",
+   ret);
+   goto err_register;
+   }
+   }
+
ret = (dev->of_node) ? of_get_omap_rng_device_details(priv, pdev) :
get_omap_rng_device_details(priv);
if (ret)
@@ -499,6 +513,7 @@ static int omap_rng_probe(struct platform_device *pdev)
pm_runtime_put_sync(>dev);
pm_runtime_disable(>dev);
 
+   clk_disable_unprepare(priv->clk_reg);
clk_disable_unprepare(priv->clk);
 err_ioremap:
dev_err(dev, "initialization failed.\n");
@@ -517,6 +532,7 @@ static int omap_rng_remove(struct platform_device *pdev)
pm_runtime_disable(>dev);
 
clk_disable_unprepare(priv->clk);
+   clk_disable_unprepare(priv->clk_reg);
 
return 0;
 }
-- 
2.16.1



[PATCH 1/2] hwrng: omap - Remove useless test before clk_disable_unprepare

2018-02-28 Thread Gregory CLEMENT
clk_disable_unprepare() already checks that the clock pointer is valid.
No need to test it before calling it.

Signed-off-by: Gregory CLEMENT 
---
 drivers/char/hw_random/omap-rng.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/char/hw_random/omap-rng.c 
b/drivers/char/hw_random/omap-rng.c
index 74d11ae6abe9..159d4a1347b8 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -499,8 +499,7 @@ static int omap_rng_probe(struct platform_device *pdev)
pm_runtime_put_sync(>dev);
pm_runtime_disable(>dev);
 
-   if (!IS_ERR(priv->clk))
-   clk_disable_unprepare(priv->clk);
+   clk_disable_unprepare(priv->clk);
 err_ioremap:
dev_err(dev, "initialization failed.\n");
return ret;
@@ -517,8 +516,7 @@ static int omap_rng_remove(struct platform_device *pdev)
pm_runtime_put_sync(>dev);
pm_runtime_disable(>dev);
 
-   if (!IS_ERR(priv->clk))
-   clk_disable_unprepare(priv->clk);
+   clk_disable_unprepare(priv->clk);
 
return 0;
 }
-- 
2.16.1



[PATCH 0/2] hwrng: omap: Fix clock resource for Armada 7K/8K

2018-02-28 Thread Gregory CLEMENT
Hi,

This short series fixes the way the clocks are used for the SafeXcel
IP-76 controller embedded in the Marvell Armada 7K/8K SoCs. On these
SoCs a second one is needed in order to clock the registers. It was
not noticed until now because we relied on the bootloader and also
because the clock driver was wrong.

Thanks to this fix, it would be possible to fix the clock driver
without introducing a regression.

The first patch is just a small cleanup found when I wrote the main
patch.

Gregory CLEMENT (2):
  hwrng: omap - Remove useless test before clk_disable_unprepare
  hwrng: omap - Fix clock resource by adding a register clock

 Documentation/devicetree/bindings/rng/omap_rng.txt |  7 ++-
 drivers/char/hw_random/omap-rng.c  | 22 ++
 2 files changed, 24 insertions(+), 5 deletions(-)

-- 
2.16.1



Re: error in libkcapi 1.0.3 for aead aio

2018-02-28 Thread Harsh Jain


On 28-02-2018 14:28, Stephan Mueller wrote:
> Am Mittwoch, 28. Februar 2018, 08:34:21 CET schrieb Harsh Jain:
>
> Hi Harsh,
>
>> Try with gdb. AIO(-x 10) works fine with step by step debugging.  Also
>> verified by adding print in "af_alg_async_cb" for received err value. 
>> Driver is sending -74 here.
> I am unable to reproduce the issue. Both commands with sync and async 
> operation work fine with me and using 1.0.3.
Ok. I will try to root cause it or will get some debug info.
>
> Ciao
> Stephan
>
>



Re: error in libkcapi 1.0.3 for aead aio

2018-02-28 Thread Stephan Mueller
Am Mittwoch, 28. Februar 2018, 08:34:21 CET schrieb Harsh Jain:

Hi Harsh,

> Try with gdb. AIO(-x 10) works fine with step by step debugging.  Also
> verified by adding print in "af_alg_async_cb" for received err value. 
> Driver is sending -74 here.

I am unable to reproduce the issue. Both commands with sync and async 
operation work fine with me and using 1.0.3.

Ciao
Stephan