Linux cryptographic layer development
 help / color / mirror / Atom feed
* [PATCH] crypto: CTR DRBG - advance output buffer pointer
From: Stephan Mueller @ 2016-11-18 11:27 UTC (permalink / raw)
  To: herbert; +Cc: linux-crypto

The CTR DRBG segments the number of random bytes to be generated into
128 byte blocks. The current code misses the advancement of the output
buffer pointer when the requestor asks for more than 128 bytes of data.
In this case, the next 128 byte block of random numbers is copied to
the beginning of the output buffer again. This implies that only the
first 128 bytes of the output buffer would ever be filled.

The patch adds the advancement of the buffer pointer to fill the entire
buffer.

Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
 crypto/drbg.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index fb33f7d..9a95b61 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1766,6 +1766,7 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
 		init_completion(&drbg->ctr_completion);
 
 		outlen -= cryptlen;
+		outbuf += cryptlen;
 	}
 
 	return 0;
-- 
2.7.4

^ permalink raw reply related

* bug in blkcipher_walk code
From: Stephan Mueller @ 2016-11-18 11:31 UTC (permalink / raw)
  To: herbert; +Cc: linux-crypto

Hi Herbert,

Once in a while I seem to trigger a bug in the blkcipher_walk code which I 
cannot track down. This bug happens sporadically where I assume that it has 
something to do with the memory management in the slow path of blkcipher_walk.

I am using the CTR DRBG code that in turn uses the ctr-aes-aesni 
implementation. The bug only appears when I want to obtain a random number 
that is less than the CTR AES block size. In my particular case, I want 4 
bytes from the DRBG.

The bug happens in arch/x86/crypto/aesni-intel_glue.c:ctr_crypt_final() at the 
line:

	memcpy(dst, keystream, nbytes);

The bug looks like the following:

[   12.328676] BUG: unable to handle kernel paging request at ffffa17ae418b988
[   12.328680] IP: [<ffffffff82060eea>] ctr_crypt+0x19a/0x1c0
[   12.328681] PGD 66fed067
[   12.328681] PUD 0
[   12.328681]
[   12.328683] Oops: 0002 [#1] SMP
[   12.328692] Modules linked in: bridge(+) stp llc ebtable_nat ip6table_raw 
ip6table_security ip6table_mangle iptable_raw iptable_security iptable_mangle 
ebtable_filter ebtables ip6table_filter ip6_tables crct10dif_pclmul 
crc32_pclmul ghash_clmulni_intel pcspkr i2c_piix4 virtio_net virtio_balloon 
acpi_cpufreq sch_fq_codel virtio_console virtio_blk virtio_pci virtio_ring 
serio_raw crc32c_intel virtio
[   12.328693] CPU: 0 PID: 521 Comm: modprobe Not tainted 4.9.0-rc1+ #253
[   12.328694] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
1.9.1-1.fc24 04/01/2014
[   12.328694] task: ffffa17ab8453fc0 task.stack: ffffbdafc0744000
[   12.328696] RIP: 0010:[<ffffffff82060eea>]  [<ffffffff82060eea>] ctr_crypt
+0x19a/0x1c0
[   12.328696] RSP: 0018:ffffbdafc0747a60  EFLAGS: 00010002
[   12.328697] RAX: 0000000032e455a6 RBX: 0000000000000004 RCX: 
0000000000000002
[   12.328697] RDX: 0000000000000001 RSI: 0000000000000086 RDI: 
0000000000000086
[   12.328698] RBP: ffffbdafc0747b28 R08: ffffa17abc16e900 R09: 
0000000000000019
[   12.328698] R10: ffffa17a764f68b0 R11: 000000000002e918 R12: 
ffffbdafc0747b38
[   12.328698] R13: ffffa17a764f6840 R14: ffffa17ae418b988 R15: 
ffffbdafc0747a70
[   12.328699] FS:  00007f55f57a6700(0000) GS:ffffa17abfc00000(0000) knlGS:
0000000000000000
[   12.328700] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   12.328700] CR2: ffffa17ae418b988 CR3: 0000000079b26000 CR4: 
00000000003406f0
[   12.328703] Stack:
[   12.328705]  ffffa17abc16e900 ffffa17ab845fd80 2ae7e40732e455a6 
3a224612a8f9841d
[   12.328706]  fffffb4e81e117c0 ffffa17ab845fd80 fffffb4e829062c0 
ffffa17ae418b988
[   12.328707]  ffffbdafc0747ba8 ffffffff00000d80 ffffffff00000004 
ffffbdafc0747bc8
[   12.328708] Call Trace:
[   12.328712]  [<ffffffff823e5fd3>] __ablk_encrypt+0x43/0x50
[   12.328714]  [<ffffffff823e6012>] ablk_encrypt+0x32/0xc0
[   12.328716]  [<ffffffff823c4f2e>] skcipher_encrypt_ablkcipher+0x5e/0x60
[   12.328717]  [<ffffffff823dbb80>] drbg_kcapi_sym_ctr+0xb0/0x130
[   12.328719]  [<ffffffff823de153>] drbg_ctr_generate+0x53/0x80


Now, the interesting part is the following: the original memory pointer that 
shall be processed by the DRBG is in my example ffffffffc018b988 -- this 
pointer is used until the DRBG invokes crypto_skcipher_encrypt. However, when 
I print out the buffer pointer that is used as dst in the memcpy of 
ctr_crypt_final, I see ffffa17ae418b988 -- i.e. the buffer that causes paging 
failure.

During tracing the blkcipher_walk code I see that the slow code path is used 
when the request size is smaller than the block size. That slow code path 
allocates new memory that will be used for the dst pointer in ctr_crypt_final.

May I ask you for checking whether the allocation and the memory pointer logic 
has an issue that would cause a paging failure?

Ciao
Stephan

^ permalink raw reply

* [patch] s390/crypto: unlock on error in prng_tdes_read()
From: Dan Carpenter @ 2016-11-18 11:11 UTC (permalink / raw)
  To: Herbert Xu, Harald Freudenberger
  Cc: David S. Miller, Martin Schwidefsky, Heiko Carstens, linux-crypto,
	linux-s390, kernel-janitors

We added some new locking but forgot to unlock on error.

Fixes: 57127645d79d ("s390/zcrypt: Introduce new SHA-512 based Pseudo Random Generator.")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>

diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c
index 9cc050f..1113389 100644
--- a/arch/s390/crypto/prng.c
+++ b/arch/s390/crypto/prng.c
@@ -507,8 +507,10 @@ static ssize_t prng_tdes_read(struct file *file, char __user *ubuf,
 		prng_data->prngws.byte_counter += n;
 		prng_data->prngws.reseed_counter += n;
 
-		if (copy_to_user(ubuf, prng_data->buf, chunk))
-			return -EFAULT;
+		if (copy_to_user(ubuf, prng_data->buf, chunk)) {
+			ret = -EFAULT;
+			break;
+		}
 
 		nbytes -= chunk;
 		ret += chunk;

^ permalink raw reply related

* [PATCH net-next] cxgb4: Allocate Tx queues dynamically
From: Atul Gupta @ 2016-11-18 11:07 UTC (permalink / raw)
  To: netdev, linux-scsi, target-devel, linux-rdma, linux-crypto
  Cc: davem, nab, jejb, martin.petersen, dledford, herbert, leedom,
	nirranjan, varun, swise, hariprasad, Atul Gupta

From: Hariprasad Shenai <hariprasad@chelsio.com>

Allocate resources dynamically for Upper layer driver's (ULD) like
cxgbit, iw_cxgb4, cxgb4i and chcr. The resources allocated include Tx
queues which are allocated when ULD register with cxgb4 driver and freed
while un-registering. The Tx queues which are shared by ULD shall be
allocated by first registering driver and un-allocated by last
unregistering driver.

Signed-off-by: Atul Gupta <atul.gupta@chelsio.com>
---
 drivers/crypto/chelsio/chcr_algo.c                 |  16 +--
 drivers/crypto/chelsio/chcr_core.c                 |   3 +-
 drivers/infiniband/hw/cxgb4/device.c               |   1 +
 drivers/net/ethernet/chelsio/cxgb4/cxgb4.h         |  19 +++-
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c |  12 --
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c    |  64 +++++++----
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c     | 114 +++++++++++++++++++
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h     |  17 +++
 drivers/net/ethernet/chelsio/cxgb4/sge.c           | 121 +++++++++++++++------
 drivers/scsi/cxgbi/cxgb4i/cxgb4i.c                 |   1 +
 drivers/target/iscsi/cxgbit/cxgbit_main.c          |   1 +
 11 files changed, 287 insertions(+), 82 deletions(-)

diff --git a/drivers/crypto/chelsio/chcr_algo.c b/drivers/crypto/chelsio/chcr_algo.c
index e4ddb921d7b3..56b153805462 100644
--- a/drivers/crypto/chelsio/chcr_algo.c
+++ b/drivers/crypto/chelsio/chcr_algo.c
@@ -592,16 +592,18 @@ static int chcr_aes_cbc_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
 
 static int cxgb4_is_crypto_q_full(struct net_device *dev, unsigned int idx)
 {
-	int ret = 0;
-	struct sge_ofld_txq *q;
 	struct adapter *adap = netdev2adap(dev);
+	struct sge_uld_txq_info *txq_info =
+		adap->sge.uld_txq_info[CXGB4_TX_CRYPTO];
+	struct sge_uld_txq *txq;
+	int ret = 0;
 
 	local_bh_disable();
-	q = &adap->sge.ofldtxq[idx];
-	spin_lock(&q->sendq.lock);
-	if (q->full)
+	txq = &txq_info->uldtxq[idx];
+	spin_lock(&txq->sendq.lock);
+	if (txq->full)
 		ret = -1;
-	spin_unlock(&q->sendq.lock);
+	spin_unlock(&txq->sendq.lock);
 	local_bh_enable();
 	return ret;
 }
@@ -674,11 +676,11 @@ static int chcr_device_init(struct chcr_context *ctx)
 		}
 		u_ctx = ULD_CTX(ctx);
 		rxq_perchan = u_ctx->lldi.nrxq / u_ctx->lldi.nchan;
-		ctx->dev->tx_channel_id = 0;
 		rxq_idx = ctx->dev->tx_channel_id * rxq_perchan;
 		rxq_idx += id % rxq_perchan;
 		spin_lock(&ctx->dev->lock_chcr_dev);
 		ctx->tx_channel_id = rxq_idx;
+		ctx->dev->tx_channel_id = !ctx->dev->tx_channel_id;
 		spin_unlock(&ctx->dev->lock_chcr_dev);
 	}
 out:
diff --git a/drivers/crypto/chelsio/chcr_core.c b/drivers/crypto/chelsio/chcr_core.c
index fb5f9bbfa09c..4d7f6700fd7e 100644
--- a/drivers/crypto/chelsio/chcr_core.c
+++ b/drivers/crypto/chelsio/chcr_core.c
@@ -42,6 +42,7 @@ static chcr_handler_func work_handlers[NUM_CPL_CMDS] = {
 static struct cxgb4_uld_info chcr_uld_info = {
 	.name = DRV_MODULE_NAME,
 	.nrxq = MAX_ULD_QSETS,
+	.ntxq = MAX_ULD_QSETS,
 	.rxq_size = 1024,
 	.add = chcr_uld_add,
 	.state_change = chcr_uld_state_change,
@@ -126,7 +127,7 @@ static int cpl_fw6_pld_handler(struct chcr_dev *dev,
 
 int chcr_send_wr(struct sk_buff *skb)
 {
-	return cxgb4_ofld_send(skb->dev, skb);
+	return cxgb4_crypto_send(skb->dev, skb);
 }
 
 static void *chcr_uld_add(const struct cxgb4_lld_info *lld)
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
index 93e3d270a98a..4e5baf4fe15e 100644
--- a/drivers/infiniband/hw/cxgb4/device.c
+++ b/drivers/infiniband/hw/cxgb4/device.c
@@ -1481,6 +1481,7 @@ static int c4iw_uld_control(void *handle, enum cxgb4_control control, ...)
 static struct cxgb4_uld_info c4iw_uld_info = {
 	.name = DRV_NAME,
 	.nrxq = MAX_ULD_QSETS,
+	.ntxq = MAX_ULD_QSETS,
 	.rxq_size = 511,
 	.ciq = true,
 	.lro = false,
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 2125903043fb..0bce1bf9ca0f 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -635,6 +635,7 @@ struct tx_sw_desc;
 
 struct sge_txq {
 	unsigned int  in_use;       /* # of in-use Tx descriptors */
+	unsigned int  q_type;	    /* Q type Eth/Ctrl/Ofld */
 	unsigned int  size;         /* # of descriptors */
 	unsigned int  cidx;         /* SW consumer index */
 	unsigned int  pidx;         /* producer index */
@@ -665,7 +666,7 @@ struct sge_eth_txq {                /* state for an SGE Ethernet Tx queue */
 	unsigned long mapping_err;  /* # of I/O MMU packet mapping errors */
 } ____cacheline_aligned_in_smp;
 
-struct sge_ofld_txq {               /* state for an SGE offload Tx queue */
+struct sge_uld_txq {               /* state for an SGE offload Tx queue */
 	struct sge_txq q;
 	struct adapter *adap;
 	struct sk_buff_head sendq;  /* list of backpressured packets */
@@ -693,14 +694,20 @@ struct sge_uld_rxq_info {
 	u8 uld;			/* uld type */
 };
 
+struct sge_uld_txq_info {
+	struct sge_uld_txq *uldtxq; /* Txq's for ULD */
+	atomic_t users;		/* num users */
+	u16 ntxq;		/* # of egress uld queues */
+};
+
 struct sge {
 	struct sge_eth_txq ethtxq[MAX_ETH_QSETS];
-	struct sge_ofld_txq ofldtxq[MAX_OFLD_QSETS];
 	struct sge_ctrl_txq ctrlq[MAX_CTRL_QUEUES];
 
 	struct sge_eth_rxq ethrxq[MAX_ETH_QSETS];
 	struct sge_rspq fw_evtq ____cacheline_aligned_in_smp;
 	struct sge_uld_rxq_info **uld_rxq_info;
+	struct sge_uld_txq_info **uld_txq_info;
 
 	struct sge_rspq intrq ____cacheline_aligned_in_smp;
 	spinlock_t intrq_lock;
@@ -1298,8 +1305,9 @@ int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq,
 			  unsigned int cmplqid);
 int t4_sge_mod_ctrl_txq(struct adapter *adap, unsigned int eqid,
 			unsigned int cmplqid);
-int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq,
-			  struct net_device *dev, unsigned int iqid);
+int t4_sge_alloc_uld_txq(struct adapter *adap, struct sge_uld_txq *txq,
+			 struct net_device *dev, unsigned int iqid,
+			 unsigned int uld_type);
 irqreturn_t t4_sge_intr_msix(int irq, void *cookie);
 int t4_sge_init(struct adapter *adap);
 void t4_sge_start(struct adapter *adap);
@@ -1661,4 +1669,7 @@ int t4_uld_mem_alloc(struct adapter *adap);
 void t4_uld_clean_up(struct adapter *adap);
 void t4_register_netevent_notifier(void);
 void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq, struct sge_fl *fl);
+void free_tx_desc(struct adapter *adap, struct sge_txq *q,
+		  unsigned int n, bool unmap);
+void free_txq(struct adapter *adap, struct sge_txq *q);
 #endif /* __CXGB4_H__ */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
index 20455d082cb8..acc231293e4d 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
@@ -2512,18 +2512,6 @@ do { \
 		RL("FLLow:", fl.low);
 		RL("FLStarving:", fl.starving);
 
-	} else if (ofld_idx < ofld_entries) {
-		const struct sge_ofld_txq *tx =
-			&adap->sge.ofldtxq[ofld_idx * 4];
-		int n = min(4, adap->sge.ofldqsets - 4 * ofld_idx);
-
-		S("QType:", "OFLD-Txq");
-		T("TxQ ID:", q.cntxt_id);
-		T("TxQ size:", q.size);
-		T("TxQ inuse:", q.in_use);
-		T("TxQ CIDX:", q.cidx);
-		T("TxQ PIDX:", q.pidx);
-
 	} else if (ctrl_idx < ctrl_entries) {
 		const struct sge_ctrl_txq *tx = &adap->sge.ctrlq[ctrl_idx * 4];
 		int n = min(4, adap->params.nports - 4 * ctrl_idx);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index c0cc2ee77be7..449884f8dd67 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -530,15 +530,15 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp,
 
 		txq = q->adap->sge.egr_map[qid - q->adap->sge.egr_start];
 		txq->restarts++;
-		if ((u8 *)txq < (u8 *)q->adap->sge.ofldtxq) {
+		if (txq->q_type == CXGB4_TXQ_ETH) {
 			struct sge_eth_txq *eq;
 
 			eq = container_of(txq, struct sge_eth_txq, q);
 			netif_tx_wake_queue(eq->txq);
 		} else {
-			struct sge_ofld_txq *oq;
+			struct sge_uld_txq *oq;
 
-			oq = container_of(txq, struct sge_ofld_txq, q);
+			oq = container_of(txq, struct sge_uld_txq, q);
 			tasklet_schedule(&oq->qresume_tsk);
 		}
 	} else if (opcode == CPL_FW6_MSG || opcode == CPL_FW4_MSG) {
@@ -885,15 +885,6 @@ static int setup_sge_queues(struct adapter *adap)
 		}
 	}
 
-	j = s->ofldqsets / adap->params.nports; /* iscsi queues per channel */
-	for_each_ofldtxq(s, i) {
-		err = t4_sge_alloc_ofld_txq(adap, &s->ofldtxq[i],
-					    adap->port[i / j],
-					    s->fw_evtq.cntxt_id);
-		if (err)
-			goto freeout;
-	}
-
 	for_each_port(adap, i) {
 		/* Note that cmplqid below is 0 if we don't
 		 * have RDMA queues, and that's the right value.
@@ -1922,8 +1913,18 @@ static void disable_dbs(struct adapter *adap)
 
 	for_each_ethrxq(&adap->sge, i)
 		disable_txq_db(&adap->sge.ethtxq[i].q);
-	for_each_ofldtxq(&adap->sge, i)
-		disable_txq_db(&adap->sge.ofldtxq[i].q);
+	if (is_offload(adap)) {
+		struct sge_uld_txq_info *txq_info =
+			adap->sge.uld_txq_info[CXGB4_TX_OFLD];
+
+		if (txq_info) {
+			for_each_ofldtxq(&adap->sge, i) {
+				struct sge_uld_txq *txq = &txq_info->uldtxq[i];
+
+				disable_txq_db(&txq->q);
+			}
+		}
+	}
 	for_each_port(adap, i)
 		disable_txq_db(&adap->sge.ctrlq[i].q);
 }
@@ -1934,8 +1935,18 @@ static void enable_dbs(struct adapter *adap)
 
 	for_each_ethrxq(&adap->sge, i)
 		enable_txq_db(adap, &adap->sge.ethtxq[i].q);
-	for_each_ofldtxq(&adap->sge, i)
-		enable_txq_db(adap, &adap->sge.ofldtxq[i].q);
+	if (is_offload(adap)) {
+		struct sge_uld_txq_info *txq_info =
+			adap->sge.uld_txq_info[CXGB4_TX_OFLD];
+
+		if (txq_info) {
+			for_each_ofldtxq(&adap->sge, i) {
+				struct sge_uld_txq *txq = &txq_info->uldtxq[i];
+
+				enable_txq_db(adap, &txq->q);
+			}
+		}
+	}
 	for_each_port(adap, i)
 		enable_txq_db(adap, &adap->sge.ctrlq[i].q);
 }
@@ -2006,8 +2017,17 @@ static void recover_all_queues(struct adapter *adap)
 
 	for_each_ethrxq(&adap->sge, i)
 		sync_txq_pidx(adap, &adap->sge.ethtxq[i].q);
-	for_each_ofldtxq(&adap->sge, i)
-		sync_txq_pidx(adap, &adap->sge.ofldtxq[i].q);
+	if (is_offload(adap)) {
+		struct sge_uld_txq_info *txq_info =
+			adap->sge.uld_txq_info[CXGB4_TX_OFLD];
+		if (txq_info) {
+			for_each_ofldtxq(&adap->sge, i) {
+				struct sge_uld_txq *txq = &txq_info->uldtxq[i];
+
+				sync_txq_pidx(adap, &txq->q);
+			}
+		}
+	}
 	for_each_port(adap, i)
 		sync_txq_pidx(adap, &adap->sge.ctrlq[i].q);
 }
@@ -3991,7 +4011,7 @@ static inline bool is_x_10g_port(const struct link_config *lc)
 static void cfg_queues(struct adapter *adap)
 {
 	struct sge *s = &adap->sge;
-	int i, n10g = 0, qidx = 0;
+	int i = 0, n10g = 0, qidx = 0;
 #ifndef CONFIG_CHELSIO_T4_DCB
 	int q10g = 0;
 #endif
@@ -4006,8 +4026,7 @@ static void cfg_queues(struct adapter *adap)
 		adap->params.crypto = 0;
 	}
 
-	for_each_port(adap, i)
-		n10g += is_x_10g_port(&adap2pinfo(adap, i)->link_cfg);
+	n10g += is_x_10g_port(&adap2pinfo(adap, i)->link_cfg);
 #ifdef CONFIG_CHELSIO_T4_DCB
 	/* For Data Center Bridging support we need to be able to support up
 	 * to 8 Traffic Priorities; each of which will be assigned to its
@@ -4075,9 +4094,6 @@ static void cfg_queues(struct adapter *adap)
 	for (i = 0; i < ARRAY_SIZE(s->ctrlq); i++)
 		s->ctrlq[i].q.size = 512;
 
-	for (i = 0; i < ARRAY_SIZE(s->ofldtxq); i++)
-		s->ofldtxq[i].q.size = 1024;
-
 	init_rspq(adap, &s->fw_evtq, 0, 1, 1024, 64);
 	init_rspq(adap, &s->intrq, 0, 1, 512, 64);
 }
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c
index 2471ff465d5c..565a6c6bfeaf 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c
@@ -447,6 +447,106 @@ static void quiesce_rx_uld(struct adapter *adap, unsigned int uld_type)
 		quiesce_rx(adap, &rxq_info->uldrxq[idx].rspq);
 }
 
+static void
+free_sge_txq_uld(struct adapter *adap, struct sge_uld_txq_info *txq_info)
+{
+	int nq = txq_info->ntxq;
+	int i;
+
+	for (i = 0; i < nq; i++) {
+		struct sge_uld_txq *txq = &txq_info->uldtxq[i];
+
+		if (txq && txq->q.desc) {
+			tasklet_kill(&txq->qresume_tsk);
+			t4_ofld_eq_free(adap, adap->mbox, adap->pf, 0,
+					txq->q.cntxt_id);
+			free_tx_desc(adap, &txq->q, txq->q.in_use, false);
+			kfree(txq->q.sdesc);
+			__skb_queue_purge(&txq->sendq);
+			free_txq(adap, &txq->q);
+		}
+	}
+}
+
+static int
+alloc_sge_txq_uld(struct adapter *adap, struct sge_uld_txq_info *txq_info,
+		  unsigned int uld_type)
+{
+	struct sge *s = &adap->sge;
+	int nq = txq_info->ntxq;
+	int i, j, err;
+
+	j = nq / adap->params.nports;
+	for (i = 0; i < nq; i++) {
+		struct sge_uld_txq *txq = &txq_info->uldtxq[i];
+
+		txq->q.size = 1024;
+		err = t4_sge_alloc_uld_txq(adap, txq, adap->port[i / j],
+					   s->fw_evtq.cntxt_id, uld_type);
+		if (err)
+			goto freeout;
+	}
+	return 0;
+freeout:
+	free_sge_txq_uld(adap, txq_info);
+	return err;
+}
+
+static void
+release_sge_txq_uld(struct adapter *adap, unsigned int uld_type)
+{
+	struct sge_uld_txq_info *txq_info = NULL;
+	int tx_uld_type = TX_ULD(uld_type);
+
+	txq_info = adap->sge.uld_txq_info[tx_uld_type];
+
+	if (txq_info && atomic_dec_and_test(&txq_info->users)) {
+		free_sge_txq_uld(adap, txq_info);
+		kfree(txq_info->uldtxq);
+		kfree(txq_info);
+		adap->sge.uld_txq_info[tx_uld_type] = NULL;
+	}
+}
+
+static int
+setup_sge_txq_uld(struct adapter *adap, unsigned int uld_type,
+		  const struct cxgb4_uld_info *uld_info)
+{
+	struct sge_uld_txq_info *txq_info = NULL;
+	int tx_uld_type, i;
+
+	tx_uld_type = TX_ULD(uld_type);
+	txq_info = adap->sge.uld_txq_info[tx_uld_type];
+
+	if ((tx_uld_type == CXGB4_TX_OFLD) && txq_info &&
+	    (atomic_inc_return(&txq_info->users) > 1))
+		return 0;
+
+	txq_info = kzalloc(sizeof(*txq_info), GFP_KERNEL);
+	if (!txq_info)
+		return -ENOMEM;
+
+	i = min_t(int, uld_info->ntxq, num_online_cpus());
+	txq_info->ntxq = roundup(i, adap->params.nports);
+
+	txq_info->uldtxq = kcalloc(txq_info->ntxq, sizeof(struct sge_uld_txq),
+				   GFP_KERNEL);
+	if (!txq_info->uldtxq) {
+		kfree(txq_info->uldtxq);
+		return -ENOMEM;
+	}
+
+	if (alloc_sge_txq_uld(adap, txq_info, tx_uld_type)) {
+		kfree(txq_info->uldtxq);
+		kfree(txq_info);
+		return -ENOMEM;
+	}
+
+	atomic_inc(&txq_info->users);
+	adap->sge.uld_txq_info[tx_uld_type] = txq_info;
+	return 0;
+}
+
 static void uld_queue_init(struct adapter *adap, unsigned int uld_type,
 			   struct cxgb4_lld_info *lli)
 {
@@ -472,7 +572,15 @@ int t4_uld_mem_alloc(struct adapter *adap)
 	if (!s->uld_rxq_info)
 		goto err_uld;
 
+	s->uld_txq_info = kzalloc(CXGB4_TX_MAX *
+				  sizeof(struct sge_uld_txq_info *),
+				  GFP_KERNEL);
+	if (!s->uld_txq_info)
+		goto err_uld_rx;
 	return 0;
+
+err_uld_rx:
+	kfree(s->uld_rxq_info);
 err_uld:
 	kfree(adap->uld);
 	return -ENOMEM;
@@ -482,6 +590,7 @@ void t4_uld_mem_free(struct adapter *adap)
 {
 	struct sge *s = &adap->sge;
 
+	kfree(s->uld_txq_info);
 	kfree(s->uld_rxq_info);
 	kfree(adap->uld);
 }
@@ -616,6 +725,9 @@ int cxgb4_register_uld(enum cxgb4_uld type,
 			ret = -EBUSY;
 			goto free_irq;
 		}
+		ret = setup_sge_txq_uld(adap, type, p);
+		if (ret)
+			goto free_irq;
 		adap->uld[type] = *p;
 		uld_attach(adap, type);
 		adap_idx++;
@@ -644,6 +756,7 @@ int cxgb4_register_uld(enum cxgb4_uld type,
 			break;
 		adap->uld[type].handle = NULL;
 		adap->uld[type].add = NULL;
+		release_sge_txq_uld(adap, type);
 		if (adap->flags & FULL_INIT_DONE)
 			quiesce_rx_uld(adap, type);
 		if (adap->flags & USING_MSIX)
@@ -679,6 +792,7 @@ int cxgb4_unregister_uld(enum cxgb4_uld type)
 			continue;
 		adap->uld[type].handle = NULL;
 		adap->uld[type].add = NULL;
+		release_sge_txq_uld(adap, type);
 		if (adap->flags & FULL_INIT_DONE)
 			quiesce_rx_uld(adap, type);
 		if (adap->flags & USING_MSIX)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
index 2996793b1aaa..4c856605fdfa 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
@@ -77,6 +77,8 @@ enum {
 
 /* Special asynchronous notification message */
 #define CXGB4_MSG_AN ((void *)1)
+#define TX_ULD(uld)(((uld) != CXGB4_ULD_CRYPTO) ? CXGB4_TX_OFLD :\
+		      CXGB4_TX_CRYPTO)
 
 struct serv_entry {
 	void *data;
@@ -223,6 +225,19 @@ enum cxgb4_uld {
 	CXGB4_ULD_MAX
 };
 
+enum cxgb4_tx_uld {
+	CXGB4_TX_OFLD,
+	CXGB4_TX_CRYPTO,
+	CXGB4_TX_MAX
+};
+
+enum cxgb4_txq_type {
+	CXGB4_TXQ_ETH,
+	CXGB4_TXQ_ULD,
+	CXGB4_TXQ_CTRL,
+	CXGB4_TXQ_MAX
+};
+
 enum cxgb4_state {
 	CXGB4_STATE_UP,
 	CXGB4_STATE_START_RECOVERY,
@@ -316,6 +331,7 @@ struct cxgb4_uld_info {
 	void *handle;
 	unsigned int nrxq;
 	unsigned int rxq_size;
+	unsigned int ntxq;
 	bool ciq;
 	bool lro;
 	void *(*add)(const struct cxgb4_lld_info *p);
@@ -333,6 +349,7 @@ 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_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);
 unsigned int cxgb4_port_viid(const struct net_device *dev);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c
index 1e74fd6085df..b7d0753b9242 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c
@@ -377,8 +377,8 @@ unmap:			dma_unmap_page(dev, be64_to_cpu(p->addr[0]),
  *	Reclaims Tx descriptors from an SGE Tx queue and frees the associated
  *	Tx buffers.  Called with the Tx queue lock held.
  */
-static void free_tx_desc(struct adapter *adap, struct sge_txq *q,
-			 unsigned int n, bool unmap)
+void free_tx_desc(struct adapter *adap, struct sge_txq *q,
+		  unsigned int n, bool unmap)
 {
 	struct tx_sw_desc *d;
 	unsigned int cidx = q->cidx;
@@ -1543,7 +1543,7 @@ static inline unsigned int calc_tx_flits_ofld(const struct sk_buff *skb)
  *	inability to map packets.  A periodic timer attempts to restart
  *	queues so marked.
  */
-static void txq_stop_maperr(struct sge_ofld_txq *q)
+static void txq_stop_maperr(struct sge_uld_txq *q)
 {
 	q->mapping_err++;
 	q->q.stops++;
@@ -1559,7 +1559,7 @@ static void txq_stop_maperr(struct sge_ofld_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_ofld_txq *q, struct sk_buff *skb)
+static void ofldtxq_stop(struct sge_uld_txq *q, struct sk_buff *skb)
 {
 	struct fw_wr_hdr *wr = (struct fw_wr_hdr *)skb->data;
 
@@ -1586,7 +1586,7 @@ static void ofldtxq_stop(struct sge_ofld_txq *q, struct sk_buff *skb)
  *	boolean "service_ofldq_running" to make sure that only one instance
  *	is ever running at a time ...
  */
-static void service_ofldq(struct sge_ofld_txq *q)
+static void service_ofldq(struct sge_uld_txq *q)
 {
 	u64 *pos, *before, *end;
 	int credits;
@@ -1706,7 +1706,7 @@ static void service_ofldq(struct sge_ofld_txq *q)
  *
  *	Send an offload packet through an SGE offload queue.
  */
-static int ofld_xmit(struct sge_ofld_txq *q, struct sk_buff *skb)
+static int ofld_xmit(struct sge_uld_txq *q, struct sk_buff *skb)
 {
 	skb->priority = calc_tx_flits_ofld(skb);       /* save for restart */
 	spin_lock(&q->sendq.lock);
@@ -1735,7 +1735,7 @@ static int ofld_xmit(struct sge_ofld_txq *q, struct sk_buff *skb)
  */
 static void restart_ofldq(unsigned long data)
 {
-	struct sge_ofld_txq *q = (struct sge_ofld_txq *)data;
+	struct sge_uld_txq *q = (struct sge_uld_txq *)data;
 
 	spin_lock(&q->sendq.lock);
 	q->full = 0;            /* the queue actually is completely empty now */
@@ -1767,17 +1767,23 @@ static inline unsigned int is_ctrl_pkt(const struct sk_buff *skb)
 	return skb->queue_mapping & 1;
 }
 
-static inline int ofld_send(struct adapter *adap, struct sk_buff *skb)
+static inline int uld_send(struct adapter *adap, struct sk_buff *skb,
+			   unsigned int tx_uld_type)
 {
+	struct sge_uld_txq_info *txq_info;
+	struct sge_uld_txq *txq;
 	unsigned int idx = skb_txq(skb);
 
+	txq_info = adap->sge.uld_txq_info[tx_uld_type];
+	txq = &txq_info->uldtxq[idx];
+
 	if (unlikely(is_ctrl_pkt(skb))) {
 		/* Single ctrl queue is a requirement for LE workaround path */
 		if (adap->tids.nsftids)
 			idx = 0;
 		return ctrl_xmit(&adap->sge.ctrlq[idx], skb);
 	}
-	return ofld_xmit(&adap->sge.ofldtxq[idx], skb);
+	return ofld_xmit(txq, skb);
 }
 
 /**
@@ -1794,7 +1800,7 @@ int t4_ofld_send(struct adapter *adap, struct sk_buff *skb)
 	int ret;
 
 	local_bh_disable();
-	ret = ofld_send(adap, skb);
+	ret = uld_send(adap, skb, CXGB4_TX_OFLD);
 	local_bh_enable();
 	return ret;
 }
@@ -1813,6 +1819,39 @@ int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb)
 }
 EXPORT_SYMBOL(cxgb4_ofld_send);
 
+/**
+ *	t4_crypto_send - send crypto packet
+ *	@adap: the adapter
+ *	@skb: the packet
+ *
+ *	Sends crypto packet.  We use the packet queue_mapping to select the
+ *	appropriate Tx queue as follows: bit 0 indicates whether the packet
+ *	should be sent as regular or control, bits 1-15 select the queue.
+ */
+static int t4_crypto_send(struct adapter *adap, struct sk_buff *skb)
+{
+	int ret;
+
+	local_bh_disable();
+	ret = uld_send(adap, skb, CXGB4_TX_CRYPTO);
+	local_bh_enable();
+	return ret;
+}
+
+/**
+ *	cxgb4_crypto_send - send crypto packet
+ *	@dev: the net device
+ *	@skb: the packet
+ *
+ *	Sends crypto packet.  This is an exported version of @t4_crypto_send,
+ *	intended for ULDs.
+ */
+int cxgb4_crypto_send(struct net_device *dev, struct sk_buff *skb)
+{
+	return t4_crypto_send(netdev2adap(dev), skb);
+}
+EXPORT_SYMBOL(cxgb4_crypto_send);
+
 static inline void copy_frags(struct sk_buff *skb,
 			      const struct pkt_gl *gl, unsigned int offset)
 {
@@ -2479,7 +2518,7 @@ static void sge_tx_timer_cb(unsigned long data)
 	for (i = 0; i < BITS_TO_LONGS(s->egr_sz); i++)
 		for (m = s->txq_maperr[i]; m; m &= m - 1) {
 			unsigned long id = __ffs(m) + i * BITS_PER_LONG;
-			struct sge_ofld_txq *txq = s->egr_map[id];
+			struct sge_uld_txq *txq = s->egr_map[id];
 
 			clear_bit(id, s->txq_maperr);
 			tasklet_schedule(&txq->qresume_tsk);
@@ -2799,6 +2838,7 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
 		return ret;
 	}
 
+	txq->q.q_type = CXGB4_TXQ_ETH;
 	init_txq(adap, &txq->q, FW_EQ_ETH_CMD_EQID_G(ntohl(c.eqid_pkd)));
 	txq->txq = netdevq;
 	txq->tso = txq->tx_cso = txq->vlan_ins = 0;
@@ -2852,6 +2892,7 @@ int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq,
 		return ret;
 	}
 
+	txq->q.q_type = CXGB4_TXQ_CTRL;
 	init_txq(adap, &txq->q, FW_EQ_CTRL_CMD_EQID_G(ntohl(c.cmpliqid_eqid)));
 	txq->adap = adap;
 	skb_queue_head_init(&txq->sendq);
@@ -2872,13 +2913,15 @@ int t4_sge_mod_ctrl_txq(struct adapter *adap, unsigned int eqid,
 	return t4_set_params(adap, adap->mbox, adap->pf, 0, 1, &param, &val);
 }
 
-int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq,
-			  struct net_device *dev, unsigned int iqid)
+int t4_sge_alloc_uld_txq(struct adapter *adap, struct sge_uld_txq *txq,
+			 struct net_device *dev, unsigned int iqid,
+			 unsigned int uld_type)
 {
 	int ret, nentries;
 	struct fw_eq_ofld_cmd c;
 	struct sge *s = &adap->sge;
 	struct port_info *pi = netdev_priv(dev);
+	int cmd = FW_EQ_OFLD_CMD;
 
 	/* Add status entries */
 	nentries = txq->q.size + s->stat_len / sizeof(struct tx_desc);
@@ -2891,7 +2934,9 @@ int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq,
 		return -ENOMEM;
 
 	memset(&c, 0, sizeof(c));
-	c.op_to_vfn = htonl(FW_CMD_OP_V(FW_EQ_OFLD_CMD) | FW_CMD_REQUEST_F |
+	if (unlikely(uld_type == CXGB4_TX_CRYPTO))
+		cmd = FW_EQ_CTRL_CMD;
+	c.op_to_vfn = htonl(FW_CMD_OP_V(cmd) | FW_CMD_REQUEST_F |
 			    FW_CMD_WRITE_F | FW_CMD_EXEC_F |
 			    FW_EQ_OFLD_CMD_PFN_V(adap->pf) |
 			    FW_EQ_OFLD_CMD_VFN_V(0));
@@ -2919,6 +2964,7 @@ int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq,
 		return ret;
 	}
 
+	txq->q.q_type = CXGB4_TXQ_ULD;
 	init_txq(adap, &txq->q, FW_EQ_OFLD_CMD_EQID_G(ntohl(c.eqid_pkd)));
 	txq->adap = adap;
 	skb_queue_head_init(&txq->sendq);
@@ -2928,7 +2974,7 @@ int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq,
 	return 0;
 }
 
-static void free_txq(struct adapter *adap, struct sge_txq *q)
+void free_txq(struct adapter *adap, struct sge_txq *q)
 {
 	struct sge *s = &adap->sge;
 
@@ -3026,21 +3072,6 @@ void t4_free_sge_resources(struct adapter *adap)
 		}
 	}
 
-	/* clean up offload Tx queues */
-	for (i = 0; i < ARRAY_SIZE(adap->sge.ofldtxq); i++) {
-		struct sge_ofld_txq *q = &adap->sge.ofldtxq[i];
-
-		if (q->q.desc) {
-			tasklet_kill(&q->qresume_tsk);
-			t4_ofld_eq_free(adap, adap->mbox, adap->pf, 0,
-					q->q.cntxt_id);
-			free_tx_desc(adap, &q->q, q->q.in_use, false);
-			kfree(q->q.sdesc);
-			__skb_queue_purge(&q->sendq);
-			free_txq(adap, &q->q);
-		}
-	}
-
 	/* clean up control Tx queues */
 	for (i = 0; i < ARRAY_SIZE(adap->sge.ctrlq); i++) {
 		struct sge_ctrl_txq *cq = &adap->sge.ctrlq[i];
@@ -3093,12 +3124,34 @@ void t4_sge_stop(struct adapter *adap)
 	if (s->tx_timer.function)
 		del_timer_sync(&s->tx_timer);
 
-	for (i = 0; i < ARRAY_SIZE(s->ofldtxq); i++) {
-		struct sge_ofld_txq *q = &s->ofldtxq[i];
+	if (is_offload(adap)) {
+		struct sge_uld_txq_info *txq_info;
+
+		txq_info = adap->sge.uld_txq_info[CXGB4_TX_OFLD];
+		if (txq_info) {
+			struct sge_uld_txq *txq = txq_info->uldtxq;
 
-		if (q->q.desc)
-			tasklet_kill(&q->qresume_tsk);
+			for_each_ofldtxq(&adap->sge, i) {
+				if (txq->q.desc)
+					tasklet_kill(&txq->qresume_tsk);
+			}
+		}
 	}
+
+	if (is_pci_uld(adap)) {
+		struct sge_uld_txq_info *txq_info;
+
+		txq_info = adap->sge.uld_txq_info[CXGB4_TX_CRYPTO];
+		if (txq_info) {
+			struct sge_uld_txq *txq = txq_info->uldtxq;
+
+			for_each_ofldtxq(&adap->sge, i) {
+				if (txq->q.desc)
+					tasklet_kill(&txq->qresume_tsk);
+			}
+		}
+	}
+
 	for (i = 0; i < ARRAY_SIZE(s->ctrlq); i++) {
 		struct sge_ctrl_txq *cq = &s->ctrlq[i];
 
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
index 0039bebaa9e2..4655a9f9dcea 100644
--- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
+++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
@@ -85,6 +85,7 @@ static inline int send_tx_flowc_wr(struct cxgbi_sock *);
 static const struct cxgb4_uld_info cxgb4i_uld_info = {
 	.name = DRV_MODULE_NAME,
 	.nrxq = MAX_ULD_QSETS,
+	.ntxq = MAX_ULD_QSETS,
 	.rxq_size = 1024,
 	.lro = false,
 	.add = t4_uld_add,
diff --git a/drivers/target/iscsi/cxgbit/cxgbit_main.c b/drivers/target/iscsi/cxgbit/cxgbit_main.c
index ad26b9372f10..96eedfc49c94 100644
--- a/drivers/target/iscsi/cxgbit/cxgbit_main.c
+++ b/drivers/target/iscsi/cxgbit/cxgbit_main.c
@@ -653,6 +653,7 @@ static struct iscsit_transport cxgbit_transport = {
 static struct cxgb4_uld_info cxgbit_uld_info = {
 	.name		= DRV_NAME,
 	.nrxq		= MAX_ULD_QSETS,
+	.ntxq		= MAX_ULD_QSETS,
 	.rxq_size	= 1024,
 	.lro		= true,
 	.add		= cxgbit_uld_add,
-- 
2.3.4

^ permalink raw reply related

* Re: [PATCH] crypto: sun4i-ss: support the Security System PRNG
From: Corentin Labbe @ 2016-11-18  7:55 UTC (permalink / raw)
  To: Sandy Harris
  Cc: Herbert Xu, David S. Miller, maxime.ripard, wens, LKML,
	linux-crypto, linux-arm-kernel
In-Reply-To: <CACXcFmmMc7U1Qz6A+mvMXVnfSmOmssydcmSugo21jrX3u-95Qg@mail.gmail.com>

On Thu, Nov 17, 2016 at 08:07:09PM -0500, Sandy Harris wrote:
> Add Ted T'so to cc list. Shouldn't he be included on anything affecting
> the random(4) driver?
> 

Blindy used get_maintainer.pl, and since the file is in crypto, hw_random people were not set.
Note that get_maintainer.pl on drivers/char/hw_random/, does not give his address also.
My V2 patch will have them in CC/TO.

> On Tue, Oct 18, 2016 at 8:34 AM, Corentin Labbe
> <clabbe.montjoie@gmail.com> wrote:
> 
> > From: LABBE Corentin <clabbe.montjoie@gmail.com>
> >
> > The Security System have a PRNG.
> > This patch add support for it as an hwrng.
> 
> Which is it? A PRNG & a HW RNG are quite different things.
> It would, in general, be a fairly serious error to treat a PRNG
> as a HWRNG.
> 
> If it is just a prng (which it appears to be from a quick look
> at your code) then it is not clear it is useful since the
> random(4) driver already has two PRNGs. It might be
> but I cannot tell.

For me hwrng is a way to give user space an another way to get "random" data via /dev/hwrng.
The only impact of hwrng with random is that just after init some data of hwrng is used for having more entropy.

Grepping prng in drivers/char/hw_random/ and drivers/crypto show me some other PRNG used with hwrng.

Regards
Corentin Labbe

^ permalink raw reply

* Re: [PATCH] crypto: sun4i-ss: support the Security System PRNG
From: Sandy Harris @ 2016-11-18  1:07 UTC (permalink / raw)
  To: Corentin Labbe
  Cc: Herbert Xu, David S. Miller, maxime.ripard, wens, LKML,
	linux-crypto, linux-arm-kernel
In-Reply-To: <1476794067-28563-1-git-send-email-clabbe.montjoie@gmail.com>

Add Ted T'so to cc list. Shouldn't he be included on anything affecting
the random(4) driver?

On Tue, Oct 18, 2016 at 8:34 AM, Corentin Labbe
<clabbe.montjoie@gmail.com> wrote:

> From: LABBE Corentin <clabbe.montjoie@gmail.com>
>
> The Security System have a PRNG.
> This patch add support for it as an hwrng.

Which is it? A PRNG & a HW RNG are quite different things.
It would, in general, be a fairly serious error to treat a PRNG
as a HWRNG.

If it is just a prng (which it appears to be from a quick look
at your code) then it is not clear it is useful since the
random(4) driver already has two PRNGs. It might be
but I cannot tell.

^ permalink raw reply

* Re: BUG: algif_hash crash with extra recv() in 4.9-rc5
From: Laura Abbott @ 2016-11-17 21:20 UTC (permalink / raw)
  To: Herbert Xu, Mat Martineau; +Cc: linux-crypto, Russell King - ARM Linux
In-Reply-To: <20161117140757.GA1149@gondor.apana.org.au>

On 11/17/2016 06:07 AM, Herbert Xu wrote:
> On Wed, Nov 16, 2016 at 11:17:33AM -0800, Mat Martineau wrote:
>>
>> Herbert -
>>
>> Following commit 493b2ed3f7603a15ff738553384d5a4510ffeb95, there is a NULL
>> dereference crash in algif_hash when recv() is called twice like this:
>>
>> send(sk, data, len, MSG_MORE);
>> recv(sk, hash1, len, 0);
>> recv(sk, hash2, len, 0);
>>
>> In 4.8 and earlier, the two recvs return identical data. In 4.9-rc5, the
>> second recv triggers this:
>>
>> [   53.041287] BUG: unable to handle kernel NULL pointer dereference at 0000000000000010
>> [   53.042048] IP: [<ffffffffa73fdfb3>] shash_ahash_digest+0x23/0x130
> 
> Ugh.  It looks like the shash wrapper is incorrectly dereferencing
> the SG list even when the length is zero.  Rather than fixing it
> I'm just going to make algif_hash do the safe thing of doing an
> init followed by a final.
> 
> Thanks,
> 
> ---8<---
> Subject: crypto: algif_hash - Fix NULL hash crash with shash
> 
> Recently algif_hash has been changed to allow null hashes.  This
> triggers a bug when used with an shash algorithm whereby it will
> cause a crash during the digest operation.
> 
> This patch fixes it by avoiding the digest operation and instead
> doing an init followed by a final which avoids the buggy code in
> shash.
> 
> This patch also ensures that the result buffer is freed after an
> error so that it is not returned as a genuine hash result on the
> next recv call.
> 
> The shash/ahash wrapper code will be fixed later to handle this
> case correctly.
> 
> Fixes: 493b2ed3f760 ("crypto: algif_hash - Handle NULL hashes correctly")
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
> 
> diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c
> index 2d8466f..05e21b4 100644
> --- a/crypto/algif_hash.c
> +++ b/crypto/algif_hash.c
> @@ -214,23 +214,26 @@ static int hash_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
>  
>  	ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0);
>  
> -	if (ctx->more) {
> +	if (!result) {
> +		err = af_alg_wait_for_completion(
> +				crypto_ahash_init(&ctx->req),
> +				&ctx->completion);
> +		if (err)
> +			goto unlock;
> +	}
> +
> +	if (!result || ctx->more) {
>  		ctx->more = 0;
>  		err = af_alg_wait_for_completion(crypto_ahash_final(&ctx->req),
>  						 &ctx->completion);
>  		if (err)
>  			goto unlock;
> -	} else if (!result) {
> -		err = af_alg_wait_for_completion(
> -				crypto_ahash_digest(&ctx->req),
> -				&ctx->completion);
>  	}
>  
>  	err = memcpy_to_msg(msg, ctx->result, len);
>  
> -	hash_free_result(sk, ctx);
> -
>  unlock:
> +	hash_free_result(sk, ctx);
>  	release_sock(sk);
>  
>  	return err ?: len;
> 

Confirmed to work for me. You can take that as a Tested-by.

Thanks,
Laura

^ permalink raw reply

* Re: crypto: caam warning fix, was: master build: 0 failures 1 warnings (v4.9-rc5-177-g81bcfe5)
From: Arnd Bergmann @ 2016-11-17 15:42 UTC (permalink / raw)
  To: Herbert Xu
  Cc: linaro-kernel, Build bot for Mark Brown, kernel-build-reports,
	Horia Geantă, linux-crypto
In-Reply-To: <20161117153403.GA1687@gondor.apana.org.au>

On Thursday, November 17, 2016 11:34:04 PM CET Herbert Xu wrote:
> On Wed, Nov 16, 2016 at 05:40:41PM +0100, Arnd Bergmann wrote:
> > 
> > This is currently the only build warning reported for v4.9, and you have merged
> > the fix for v4.10 in
> > 
> > d69985a07692 ("crypto: caam - fix type mismatch warning")
> > 
> > Any chance you can send this for v4.9 so we have a clean build?
> 
> OK I'll push that along.
> 
> 

Thanks!

	Arnd

^ permalink raw reply

* Re: crypto: caam warning fix, was: master build: 0 failures 1 warnings (v4.9-rc5-177-g81bcfe5)
From: Herbert Xu @ 2016-11-17 15:34 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linaro-kernel, Build bot for Mark Brown, kernel-build-reports,
	Horia Geantă, linux-crypto
In-Reply-To: <5255539.MpGQJX1bep@wuerfel>

On Wed, Nov 16, 2016 at 05:40:41PM +0100, Arnd Bergmann wrote:
> 
> This is currently the only build warning reported for v4.9, and you have merged
> the fix for v4.10 in
> 
> d69985a07692 ("crypto: caam - fix type mismatch warning")
> 
> Any chance you can send this for v4.9 so we have a clean build?

OK I'll push that along.

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: BUG: algif_hash crash with extra recv() in 4.9-rc5
From: Herbert Xu @ 2016-11-17 14:07 UTC (permalink / raw)
  To: Mat Martineau; +Cc: linux-crypto, Laura Abbott, Russell King - ARM Linux
In-Reply-To: <alpine.OSX.2.20.1611161027010.67352@mjmartin-mac01.local>

On Wed, Nov 16, 2016 at 11:17:33AM -0800, Mat Martineau wrote:
> 
> Herbert -
> 
> Following commit 493b2ed3f7603a15ff738553384d5a4510ffeb95, there is a NULL
> dereference crash in algif_hash when recv() is called twice like this:
> 
> send(sk, data, len, MSG_MORE);
> recv(sk, hash1, len, 0);
> recv(sk, hash2, len, 0);
> 
> In 4.8 and earlier, the two recvs return identical data. In 4.9-rc5, the
> second recv triggers this:
> 
> [   53.041287] BUG: unable to handle kernel NULL pointer dereference at 0000000000000010
> [   53.042048] IP: [<ffffffffa73fdfb3>] shash_ahash_digest+0x23/0x130

Ugh.  It looks like the shash wrapper is incorrectly dereferencing
the SG list even when the length is zero.  Rather than fixing it
I'm just going to make algif_hash do the safe thing of doing an
init followed by a final.

Thanks,

---8<---
Subject: crypto: algif_hash - Fix NULL hash crash with shash

Recently algif_hash has been changed to allow null hashes.  This
triggers a bug when used with an shash algorithm whereby it will
cause a crash during the digest operation.

This patch fixes it by avoiding the digest operation and instead
doing an init followed by a final which avoids the buggy code in
shash.

This patch also ensures that the result buffer is freed after an
error so that it is not returned as a genuine hash result on the
next recv call.

The shash/ahash wrapper code will be fixed later to handle this
case correctly.

Fixes: 493b2ed3f760 ("crypto: algif_hash - Handle NULL hashes correctly")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c
index 2d8466f..05e21b4 100644
--- a/crypto/algif_hash.c
+++ b/crypto/algif_hash.c
@@ -214,23 +214,26 @@ static int hash_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 
 	ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0);
 
-	if (ctx->more) {
+	if (!result) {
+		err = af_alg_wait_for_completion(
+				crypto_ahash_init(&ctx->req),
+				&ctx->completion);
+		if (err)
+			goto unlock;
+	}
+
+	if (!result || ctx->more) {
 		ctx->more = 0;
 		err = af_alg_wait_for_completion(crypto_ahash_final(&ctx->req),
 						 &ctx->completion);
 		if (err)
 			goto unlock;
-	} else if (!result) {
-		err = af_alg_wait_for_completion(
-				crypto_ahash_digest(&ctx->req),
-				&ctx->completion);
 	}
 
 	err = memcpy_to_msg(msg, ctx->result, len);
 
-	hash_free_result(sk, ctx);
-
 unlock:
+	hash_free_result(sk, ctx);
 	release_sock(sk);
 
 	return err ?: len;
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply related

* Re: [PATCH] crypto: ccp - Fix handling of RSA exponent on a v5 device
From: Herbert Xu @ 2016-11-17 13:14 UTC (permalink / raw)
  To: Gary R Hook; +Cc: Gary R Hook, linux-crypto, thomas.lendacky, davem
In-Reply-To: <368b41ee-45e3-c330-10c5-16fcc22d3d16@amd.com>

On Wed, Nov 16, 2016 at 11:25:19AM -0600, Gary R Hook wrote:
>
> The kernel crypto layer does not yet support RSA, true. However, we
> designed the ccp.ko layer to be available to anyone that wants to use
> it. The underlying module currently has differing behavior/results
> between the v3 and v5 implementations of the RSA command function.
> This patch fixes the borked v5 code.

Do you mean that an out-of-tree module could enter the buggy
code path?

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: BUG: algif_hash crash with extra recv() in 4.9-rc5
From: Mat Martineau @ 2016-11-17 16:50 UTC (permalink / raw)
  To: Herbert Xu; +Cc: linux-crypto, Laura Abbott, Russell King - ARM Linux
In-Reply-To: <20161117140757.GA1149@gondor.apana.org.au>


Herbert,

On Thu, 17 Nov 2016, Herbert Xu wrote:

> On Wed, Nov 16, 2016 at 11:17:33AM -0800, Mat Martineau wrote:
>>
>> Herbert -
>>
>> Following commit 493b2ed3f7603a15ff738553384d5a4510ffeb95, there is a NULL
>> dereference crash in algif_hash when recv() is called twice like this:
>>
>> send(sk, data, len, MSG_MORE);
>> recv(sk, hash1, len, 0);
>> recv(sk, hash2, len, 0);
>>
>> In 4.8 and earlier, the two recvs return identical data. In 4.9-rc5, the
>> second recv triggers this:
>>
>> [   53.041287] BUG: unable to handle kernel NULL pointer dereference at 0000000000000010
>> [   53.042048] IP: [<ffffffffa73fdfb3>] shash_ahash_digest+0x23/0x130
>
> Ugh.  It looks like the shash wrapper is incorrectly dereferencing
> the SG list even when the length is zero.  Rather than fixing it
> I'm just going to make algif_hash do the safe thing of doing an
> init followed by a final.

Thanks for the patch. For my test code, it fixed the crash and restored 
the previous behavior.

Regards,
Mat


> ---8<---
> Subject: crypto: algif_hash - Fix NULL hash crash with shash
>
> Recently algif_hash has been changed to allow null hashes.  This
> triggers a bug when used with an shash algorithm whereby it will
> cause a crash during the digest operation.
>
> This patch fixes it by avoiding the digest operation and instead
> doing an init followed by a final which avoids the buggy code in
> shash.
>
> This patch also ensures that the result buffer is freed after an
> error so that it is not returned as a genuine hash result on the
> next recv call.
>
> The shash/ahash wrapper code will be fixed later to handle this
> case correctly.
>
> Fixes: 493b2ed3f760 ("crypto: algif_hash - Handle NULL hashes correctly")
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
>
> diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c
> index 2d8466f..05e21b4 100644
> --- a/crypto/algif_hash.c
> +++ b/crypto/algif_hash.c
> @@ -214,23 +214,26 @@ static int hash_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
>
> 	ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0);
>
> -	if (ctx->more) {
> +	if (!result) {
> +		err = af_alg_wait_for_completion(
> +				crypto_ahash_init(&ctx->req),
> +				&ctx->completion);
> +		if (err)
> +			goto unlock;
> +	}
> +
> +	if (!result || ctx->more) {
> 		ctx->more = 0;
> 		err = af_alg_wait_for_completion(crypto_ahash_final(&ctx->req),
> 						 &ctx->completion);
> 		if (err)
> 			goto unlock;
> -	} else if (!result) {
> -		err = af_alg_wait_for_completion(
> -				crypto_ahash_digest(&ctx->req),
> -				&ctx->completion);
> 	}
>
> 	err = memcpy_to_msg(msg, ctx->result, len);
>
> -	hash_free_result(sk, ctx);
> -
> unlock:
> +	hash_free_result(sk, ctx);
> 	release_sock(sk);
>
> 	return err ?: len;
> -- 
> Email: Herbert Xu <herbert@gondor.apana.org.au>
> Home Page: http://gondor.apana.org.au/~herbert/
> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
>

--
Mat Martineau
Intel OTC

^ permalink raw reply

* Re: [PATCH] crypto: ccp - Fix handling of RSA exponent on a v5 device
From: Gary R Hook @ 2016-11-17 14:22 UTC (permalink / raw)
  To: Herbert Xu; +Cc: linux-crypto, thomas.lendacky, davem
In-Reply-To: <20161117131447.GA2029@gondor.apana.org.au>

On 11/17/2016 07:14 AM, Herbert Xu wrote:
> On Wed, Nov 16, 2016 at 11:25:19AM -0600, Gary R Hook wrote:
>>
>> The kernel crypto layer does not yet support RSA, true. However, we
>> designed the ccp.ko layer to be available to anyone that wants to use
>> it. The underlying module currently has differing behavior/results
>> between the v3 and v5 implementations of the RSA command function.
>> This patch fixes the borked v5 code.
>
> Do you mean that an out-of-tree module could enter the buggy
> code path?

I mean that anything that can call ccp_run_cmd() (in ccp.ko) can run
into a problem, yes. Is this likely? We don't know, as we don't know
if anyone actually uses this layer. But it _is_ possible to find the
problem.

-- 
This is my day job. Follow me at:
IG/Twitter/Facebook: @grhookphoto
IG/Twitter/Facebook: @grhphotographer

^ permalink raw reply

* Re: [PATCH] crypto: add virtio-crypto driver
From: Benedetto, Salvatore @ 2016-11-17 15:55 UTC (permalink / raw)
  To: Gonglei, qemu-devel@nongnu.org, virtio-dev@lists.oasis-open.org,
	virtualization@lists.linux-foundation.org,
	linux-crypto@vger.kernel.org
  Cc: pasic@linux.vnet.ibm.com, weidong.huang@huawei.com,
	claudio.fontana@huawei.com, mst@redhat.com, luonengjun@huawei.com,
	hanweidong@huawei.com, Zeng, Xin, peter.huangpeng@huawei.com,
	Benedetto, Salvatore, xuquan8@huawei.com, stefanha@redhat.com,
	jianjay.zhou@huawei.com, cornelia.huck@de.ibm.com,
	arei.gonglei@hotmail.com, davem@davemloft.net,
	wu.wubin@huawei.com, herbert@gondor.apana.org.au
In-Reply-To: <1479106074-32036-1-git-send-email-arei.gonglei@huawei.com>

Hi Gonglei,

...
> +
> +static int virtio_crypto_alg_ablkcipher_init_session(
> +		struct virtio_crypto_ablkcipher_ctx *ctx,
> +		int alg, const uint8_t *key,
> +		unsigned int keylen,
> +		int encrypt)
> +{
> +	struct scatterlist outhdr, key_sg, inhdr, *sgs[3];
> +	unsigned int tmp;
> +	struct virtio_crypto_session_input input;
> +	struct virtio_crypto_op_ctrl_req ctrl;
> +	struct virtio_crypto *vcrypto = ctx->vcrypto;
> +	int op = encrypt ? VIRTIO_CRYPTO_OP_ENCRYPT :
> VIRTIO_CRYPTO_OP_DECRYPT;
> +	int err;
> +	unsigned int num_out = 0, num_in = 0;
> +
> +	memset(&ctrl, 0, sizeof(ctrl));
> +	memset(&input, 0, sizeof(input));
> +	/* Pad ctrl header */
> +	ctrl.header.opcode =
> cpu_to_le32(VIRTIO_CRYPTO_CIPHER_CREATE_SESSION);
> +	ctrl.header.algo = cpu_to_le32((uint32_t)alg);
> +	/* Set the default dataqueue id to 0 */
> +	ctrl.header.queue_id = 0;
> +
> +	input.status = cpu_to_le32(VIRTIO_CRYPTO_ERR);
> +	/* Pad cipher's parameters */
> +	ctrl.u.sym_create_session.op_type =
> +		cpu_to_le32(VIRTIO_CRYPTO_SYM_OP_CIPHER);
> +	ctrl.u.sym_create_session.u.cipher.para.algo = ctrl.header.algo;
> +	ctrl.u.sym_create_session.u.cipher.para.keylen =
> cpu_to_le32(keylen);
> +	ctrl.u.sym_create_session.u.cipher.para.op = cpu_to_le32(op);
> +
> +	sg_init_one(&outhdr, &ctrl, sizeof(ctrl));

I believe this won't work when the new virtually-mapped kernel stack (VMAP_STACK)
is enabled.

Regards,
Salvatore

^ permalink raw reply

* Re: [PATCH] powerpc: crypto/vmx: various build fixes
From: Herbert Xu @ 2016-11-17 15:40 UTC (permalink / raw)
  To: Naveen N. Rao
  Cc: Leonidas S. Barbosa, linuxppc-dev, linux-crypto,
	Paulo Flabiano Smorigo
In-Reply-To: <20161116151146.15720-1-naveen.n.rao@linux.vnet.ibm.com>

On Wed, Nov 16, 2016 at 08:41:46PM +0530, Naveen N. Rao wrote:
> First up, clean up the generated .S files properly on a 'make clean'.
> Secondly, force re-generation of these files when building for different
> endian-ness than what was built previously. Finally, generate the new
> files in the build tree, rather than the source tree.
> 
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>

Patch applied.  Thanks.
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [PATCH] powerpc: crypto/vmx: various build fixes
From: Naveen N. Rao @ 2016-11-17 14:22 UTC (permalink / raw)
  To: Herbert Xu
  Cc: Leonidas S. Barbosa, linuxppc-dev, linux-crypto,
	Paulo Flabiano Smorigo
In-Reply-To: <20161117130311.GA1839@gondor.apana.org.au>

On 2016/11/17 09:03PM, Herbert Xu wrote:
> On Thu, Nov 17, 2016 at 11:51:56AM +1100, Michael Ellerman wrote:
> > 
> > Crypto patches usually have a subject like:
> > 
> > crypto: vmx - Various build fixes

Ok.

> >
> > But maybe Herbert can fix it up for you when he applies this.
> 
> Sure I can fix it up.

Thanks,
- Naveen

^ permalink raw reply

* Re: [PATCH] powerpc: crypto/vmx: various build fixes
From: Herbert Xu @ 2016-11-17 13:03 UTC (permalink / raw)
  To: Michael Ellerman
  Cc: Leonidas S. Barbosa, Naveen N. Rao, linuxppc-dev, linux-crypto,
	Paulo Flabiano Smorigo
In-Reply-To: <87inrnx70z.fsf@concordia.ellerman.id.au>

On Thu, Nov 17, 2016 at 11:51:56AM +1100, Michael Ellerman wrote:
>
> But maybe Herbert can fix it up for you when he applies this.

Sure I can fix it up.

Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [PATCH] crypto: sun4i-ss: support the Security System PRNG
From: Stephan Mueller @ 2016-11-17  8:18 UTC (permalink / raw)
  To: Corentin Labbe
  Cc: herbert, davem, maxime.ripard, wens, linux-kernel, linux-crypto,
	linux-arm-kernel
In-Reply-To: <20161117080748.GB25394@Red>

Am Donnerstag, 17. November 2016, 09:07:48 CET schrieb Corentin Labbe:

Hi Corentin,
> 
> Seed again, or just do not seed (and so return -EAGAIN for read() function)
> until ready_callback ?

This is your choice. But for the start sequence, you should not simply rely on 
get_random_bytes.

For the DRBG in crypto/drbg.c we seed with get_random_bytes and the Jitter RNG 
in case the input_pool is not fully seeded. The reseed trigger is reduced to 
50 DRBG requests, i.e. after 50 requests, the DRBG again reseeds from 
get_random_bytes / Jitter RNG. This is continued until the input_pool has been 
sufficiently seeded (i.e. the registered callback is triggered). At that 
point, another get_random_bytes call is made, the Jitter RNG is deactivated 
and the reseed threshold is set to the common value.

Ciao
Stephan

^ permalink raw reply

* Re: [PATCH] crypto: sun4i-ss: support the Security System PRNG
From: Corentin Labbe @ 2016-11-17  8:07 UTC (permalink / raw)
  To: Stephan Mueller
  Cc: herbert, davem, maxime.ripard, wens, linux-kernel, linux-crypto,
	linux-arm-kernel
In-Reply-To: <1722218.eZlGktOxfL@tauon.atsec.com>

On Tue, Oct 18, 2016 at 04:24:22PM +0200, Stephan Mueller wrote:
> Am Dienstag, 18. Oktober 2016, 14:34:27 CEST schrieb Corentin Labbe:
> 
> Hi Corentin,
> 
> > diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-hwrng.c
> > b/drivers/crypto/sunxi-ss/sun4i-ss-hwrng.c new file mode 100644
> > index 0000000..95fadb7
> > --- /dev/null
> > +++ b/drivers/crypto/sunxi-ss/sun4i-ss-hwrng.c
> > @@ -0,0 +1,70 @@
> > +#include "sun4i-ss.h"
> > +
> > +static int sun4i_ss_hwrng_init(struct hwrng *hwrng)
> > +{
> > +	struct sun4i_ss_ctx *ss;
> > +
> > +	ss = container_of(hwrng, struct sun4i_ss_ctx, hwrng);
> > +	get_random_bytes(ss->seed, SS_SEED_LEN);
> 
> Is it wise to call get_random_bytes once in the init function and never 
> thereafter?
> 
> This init function may be called during boot time of the kernel at which the 
> input_pool may not yet have received sufficient amounts of entropy.
> 
> What about registering a callback with add_random_ready_callback and seed 
> again when sufficient entropy was collected?
> 

Seed again, or just do not seed (and so return -EAGAIN for read() function) until ready_callback ?

Thanks

Corentin Labbe

^ permalink raw reply

* Re: [PATCH] crypto: sun4i-ss: support the Security System PRNG
From: Corentin Labbe @ 2016-11-17  8:05 UTC (permalink / raw)
  To: PrasannaKumar Muralidharan
  Cc: Herbert Xu, davem, maxime.ripard, wens, linux-kernel,
	linux-crypto, linux-arm-kernel
In-Reply-To: <CANc+2y63p1b5ATDY0oU4nLckk9CJhSs3CXGHy=NwoXn_awP9aA@mail.gmail.com>

On Tue, Oct 18, 2016 at 09:39:17PM +0530, PrasannaKumar Muralidharan wrote:
> Hi Corentin,
> 
> I have a few minor comments.
> 
> On 18 October 2016 at 18:04, Corentin Labbe <clabbe.montjoie@gmail.com> wrote:
> > From: LABBE Corentin <clabbe.montjoie@gmail.com>
> >
> > The Security System have a PRNG.
> > This patch add support for it as an hwrng.
> >
> > Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
> > ---
> >  drivers/crypto/Kconfig                   |  8 ++++
> >  drivers/crypto/sunxi-ss/Makefile         |  1 +
> >  drivers/crypto/sunxi-ss/sun4i-ss-core.c  | 14 +++++++
> >  drivers/crypto/sunxi-ss/sun4i-ss-hwrng.c | 70 ++++++++++++++++++++++++++++++++
> >  drivers/crypto/sunxi-ss/sun4i-ss.h       |  8 ++++
> >  5 files changed, 101 insertions(+)
> >  create mode 100644 drivers/crypto/sunxi-ss/sun4i-ss-hwrng.c
> >
> > diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
> > index 4d2b81f..38f7aca 100644
> > --- a/drivers/crypto/Kconfig
> > +++ b/drivers/crypto/Kconfig
> > @@ -538,6 +538,14 @@ config CRYPTO_DEV_SUN4I_SS
> >           To compile this driver as a module, choose M here: the module
> >           will be called sun4i-ss.
> >
> > +config CRYPTO_DEV_SUN4I_SS_PRNG
> > +       bool "Support for Allwinner Security System PRNG"
> > +       depends on CRYPTO_DEV_SUN4I_SS
> > +       select HW_RANDOM
> > +       help
> > +         This driver provides kernel-side support for the Pseudo-Random
> > +         Number Generator found in the Security System.
> > +
> >  config CRYPTO_DEV_ROCKCHIP
> >         tristate "Rockchip's Cryptographic Engine driver"
> >         depends on OF && ARCH_ROCKCHIP
> > diff --git a/drivers/crypto/sunxi-ss/Makefile b/drivers/crypto/sunxi-ss/Makefile
> > index 8f4c7a2..ca049ee 100644
> > --- a/drivers/crypto/sunxi-ss/Makefile
> > +++ b/drivers/crypto/sunxi-ss/Makefile
> > @@ -1,2 +1,3 @@
> >  obj-$(CONFIG_CRYPTO_DEV_SUN4I_SS) += sun4i-ss.o
> >  sun4i-ss-y += sun4i-ss-core.o sun4i-ss-hash.o sun4i-ss-cipher.o
> > +sun4i-ss-$(CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG) += sun4i-ss-hwrng.o
> > diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-core.c b/drivers/crypto/sunxi-ss/sun4i-ss-core.c
> > index 3ac6c6c..fa739de 100644
> > --- a/drivers/crypto/sunxi-ss/sun4i-ss-core.c
> > +++ b/drivers/crypto/sunxi-ss/sun4i-ss-core.c
> > @@ -359,6 +359,16 @@ static int sun4i_ss_probe(struct platform_device *pdev)
> >                 }
> >         }
> >         platform_set_drvdata(pdev, ss);
> > +
> > +#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG
> > +       /* Voluntarily made the PRNG optional */
> > +       err = sun4i_ss_hwrng_register(&ss->hwrng);
> > +       if (!err)
> > +               dev_info(ss->dev, "sun4i-ss PRNG loaded");
> > +       else
> > +               dev_err(ss->dev, "sun4i-ss PRNG failed");
> > +#endif
> > +
> >         return 0;
> >  error_alg:
> >         i--;
> > @@ -386,6 +396,10 @@ static int sun4i_ss_remove(struct platform_device *pdev)
> >         int i;
> >         struct sun4i_ss_ctx *ss = platform_get_drvdata(pdev);
> >
> > +#ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG
> > +       sun4i_ss_hwrng_remove(&ss->hwrng);
> > +#endif
> > +
> >         for (i = 0; i < ARRAY_SIZE(ss_algs); i++) {
> >                 switch (ss_algs[i].type) {
> >                 case CRYPTO_ALG_TYPE_ABLKCIPHER:
> > diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-hwrng.c b/drivers/crypto/sunxi-ss/sun4i-ss-hwrng.c
> > new file mode 100644
> > index 0000000..95fadb7
> > --- /dev/null
> > +++ b/drivers/crypto/sunxi-ss/sun4i-ss-hwrng.c
> > @@ -0,0 +1,70 @@
> > +#include "sun4i-ss.h"
> > +
> > +static int sun4i_ss_hwrng_init(struct hwrng *hwrng)
> > +{
> > +       struct sun4i_ss_ctx *ss;
> > +
> > +       ss = container_of(hwrng, struct sun4i_ss_ctx, hwrng);
> > +       get_random_bytes(ss->seed, SS_SEED_LEN);
> > +
> > +       return 0;
> > +}
> > +
> > +static int sun4i_ss_hwrng_read(struct hwrng *hwrng, void *buf,
> > +                              size_t max, bool wait)
> > +{
> > +       int i;
> > +       u32 v;
> > +       u32 *data = buf;
> > +       const u32 mode = SS_OP_PRNG | SS_PRNG_CONTINUE | SS_ENABLED;
> > +       size_t len;
> > +       struct sun4i_ss_ctx *ss;
> > +
> > +       ss = container_of(hwrng, struct sun4i_ss_ctx, hwrng);
> > +       len = min_t(size_t, SS_DATA_LEN, max);
> > +
> > +       spin_lock_bh(&ss->slock);
> 
> Is spin_lock_bh really required here? I could see it is being used in
> sun4i-ss-hash.c but could not find any comment/info about the need.
> 

No for sun4i-ss-hwrng it seems not required and work perfecly without _bh

> > +       writel(mode, ss->base + SS_CTL);
> > +
> > +       /* write the seed */
> > +       for (i = 0; i < SS_SEED_LEN / 4; i++)
> > +               writel(ss->seed[i], ss->base + SS_KEY0 + i * 4);
> > +       writel(mode | SS_PRNG_START, ss->base + SS_CTL);
> > +
> > +       /* Read the random data */
> > +       readsl(ss->base + SS_TXFIFO, data, len / 4);
> > +
> > +       if (len % 4 > 0) {
> > +               v = readl(ss->base + SS_TXFIFO);
> > +               memcpy(data + len / 4, &v, len % 4);
> > +       }
> 
> hwrng core asks for "rng_buffer_size()" of data which is a multiple of
> 4. So len % 4 will be 0. I think the above check is not required. Feel
> free to correct if I am wrong.
> 

Agree, I removed that in v2

Thanks

Corentin Labbe

^ permalink raw reply

* Целевые клиентские базы Skype: prodawez390 Whatsapp: +79139230330 Viber:  +79139230330 Telegram: +79139230330 Email: prodawez391@gmail.com
From: beer.c@gmx.com @ 2016-11-18  0:55 UTC (permalink / raw)
  To: hp627@daum.net

Целевые клиентские базы Skype: prodawez390 Whatsapp: +79139230330 Viber:  +79139230330 Telegram: +79139230330 Email: prodawez391@gmail.com

^ permalink raw reply

* 22773 linux-crypto
From: membership @ 2016-11-17  4:56 UTC (permalink / raw)
  To: linux-crypto

[-- Attachment #1: EMAIL_284983759749_linux-crypto.zip --]
[-- Type: application/zip, Size: 4107 bytes --]

^ permalink raw reply

* 12225 linux-crypto
From: isaac @ 2016-11-17  3:14 UTC (permalink / raw)
  To: linux-crypto

[-- Attachment #1: EMAIL_2200126_linux-crypto.zip --]
[-- Type: application/zip, Size: 4839 bytes --]

^ permalink raw reply

* Re: [PATCH] powerpc: crypto/vmx: various build fixes
From: Michael Ellerman @ 2016-11-17  0:51 UTC (permalink / raw)
  To: Naveen N. Rao, Leonidas S. Barbosa, Herbert Xu
  Cc: Paulo Flabiano Smorigo, linux-crypto, linuxppc-dev
In-Reply-To: <20161116151146.15720-1-naveen.n.rao@linux.vnet.ibm.com>

"Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com> writes:

> First up, clean up the generated .S files properly on a 'make clean'.
> Secondly, force re-generation of these files when building for different
> endian-ness than what was built previously. Finally, generate the new
> files in the build tree, rather than the source tree.
>
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
> ---
> Michael,
> I've added your SOB here though you didn't explicitly include it in your
> previous mail. I hope that's fine from your end.

Yeah that's fine, thanks.

Crypto patches usually have a subject like:

crypto: vmx - Various build fixes


But maybe Herbert can fix it up for you when he applies this.

cheers

^ permalink raw reply

* [REGRESSION] 493b2ed3f760 ("crypto: algif_hash - Handle NULL hashes correctly")
From: Laura Abbott @ 2016-11-17  0:21 UTC (permalink / raw)
  To: Herbert Xu
  Cc: linux-crypto, Linux Kernel Mailing List, Russell King - ARM Linux

Hi,

Fedora got a bugzilla https://bugzilla.redhat.com/show_bug.cgi?id=1395896
of an oops with this program:

#include <linux/if_alg.h>
#include <stddef.h>
#include <sys/socket.h>

int main(int argc, char *argv[]) {
        static const union {
                struct sockaddr sa;
                struct sockaddr_alg alg;
        } sa = {
                .alg.salg_family = AF_ALG,
                .alg.salg_type = "hash",
                .alg.salg_name = "sha256",
        };
        char c;
        int fd1, fd2;

        fd1 = socket(AF_ALG, SOCK_SEQPACKET, 0);
        bind(fd1, &sa.sa, sizeof(sa));
        fd2 = accept(fd1, NULL, 0);
        recv(fd2, &c, sizeof(c), 0);

        return 0;
}


[   10.802304] BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
[   10.803970] IP: [<ffffffff812f743e>] shash_ahash_digest+0x1e/0x100
[   10.805046] PGD eb37067 PUD 12425067 PMD 0 
[   10.806019] Oops: 0000 [#1] SMP
[   10.806702] Modules linked in:
[   10.807421] CPU: 0 PID: 1098 Comm: a.out Not tainted 4.8.0-rc1+ #29
[   10.808444] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.1-1.fc24 04/01/2014
[   10.809839] task: ffff880010a92400 task.stack: ffff880012458000
[   10.810653] RIP: 0010:[<ffffffff812f743e>]  [<ffffffff812f743e>] shash_ahash_digest+0x1e/0x100
[   10.811979] RSP: 0018:ffff88001245bd48  EFLAGS: 00010246
[   10.812730] RAX: 0000000000001000 RBX: ffff88001249b390 RCX: 0000000000000000
[   10.814419] RDX: 0000000000000000 RSI: ffff88001249b390 RDI: ffff88001249b340
[   10.815303] RBP: ffff88001245bd68 R08: ffff88000eb54fa0 R09: 0000000000000000
[   10.816126] R10: ffff88000eb547d0 R11: 0000000000000001 R12: ffffffff812f7520
[   10.816946] R13: ffff88001249b340 R14: ffff88001245be38 R15: 0000000000000000
[   10.818098] FS:  00007f1849f3a700(0000) GS:ffff880011800000(0000) knlGS:0000000000000000
[   10.819644] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   10.820370] CR2: 0000000000000008 CR3: 000000000eb36000 CR4: 00000000000006f0
[   10.821198] Stack:
[   10.821641]  ffff88001249b340 ffffffff812f7520 ffff880012498c18 ffff88001245be38
[   10.822905]  ffff88001245bd78 ffffffff812f753f ffff88001245bda0 ffffffff812f6aa4
[   10.824168]  ffff88001249b060 ffff88001249b060 0000000000000001 ffff88001245bdb0
[   10.825434] Call Trace:
[   10.825910]  [<ffffffff812f7520>] ? shash_ahash_digest+0x100/0x100
[   10.826663]  [<ffffffff812f753f>] shash_async_digest+0x1f/0x30
[   10.827389]  [<ffffffff812f6aa4>] crypto_ahash_op+0x24/0x60
[   10.828097]  [<ffffffff812f6b31>] crypto_ahash_digest+0x11/0x20
[   10.828835]  [<ffffffff813087a4>] hash_recvmsg+0x1a4/0x1c0
[   10.829539]  [<ffffffff817253b8>] sock_recvmsg+0x38/0x40
[   10.830232]  [<ffffffff817255ab>] SYSC_recvfrom+0xcb/0x130
[   10.830937]  [<ffffffff81724ccf>] ? sock_map_fd+0x3f/0x60
[   10.831635]  [<ffffffff81726729>] SyS_recvfrom+0x9/0x10
[   10.832317]  [<ffffffff81922572>] entry_SYSCALL_64_fastpath+0x1a/0xa4
[   10.833091] Code: 44 00 00 66 2e 0f 1f 84 00 00 00 00 00 55 b8 00 10 00 00 48 89 e5 41 56 41 55 41 54 53 49 89 fd 48 8b 4f 38 41 8b 55 30 48 89 f3 <8b> 79 08 29 f8 39 41 0c 0f 46 41 0c 39 c2 73 74 48 8b 31 48 83 
[   10.838754] RIP  [<ffffffff812f743e>] shash_ahash_digest+0x1e/0x100
[   10.839560]  RSP <ffff88001245bd48>
[   10.840112] CR2: 0000000000000008
[   10.840674] ---[ end trace 4314dcc948f7acad ]---
[   10.841320] Kernel panic - not syncing: Fatal exception
[   10.842106] Kernel Offset: disabled

It looks like hash_recvmsg sets the sg to NULL with 

ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0);

which then blows up when crypto_ahash_digest -> hash_ahash_digest
tries to access it. 

Thanks,
Laura

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox