* Equivalent of blkciper_walk for skcipher
From: Alex Cope @ 2016-10-24 20:39 UTC (permalink / raw)
To: linux-crypto; +Cc: Michael Halcrow, Eric Biggers
How should an algorithm implementing the skcipher api walk over the
scatterlist? blkcipher_walk seems to be what I need, but the API is
not compatible with skciper at the moment. Repeatedly calling
scatterwalk_map_and_copy looks like it will work, but would be less
performant than using something akin to blkciper_walk.
^ permalink raw reply
* Re: [PATCH] nvmem: sunxi-sid: SID content is not a valid source of randomness
From: Maxime Ripard @ 2016-10-24 20:10 UTC (permalink / raw)
To: Corentin Labbe
Cc: srinivas.kandagatla, wens, linux-kernel, linux-arm-kernel,
linux-crypto
In-Reply-To: <1477144408-15896-1-git-send-email-clabbe.montjoie@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 538 bytes --]
On Sat, Oct 22, 2016 at 03:53:28PM +0200, Corentin Labbe wrote:
> Since SID's content is constant over reboot,
That's not true, at least not across all the Allwinner SoCs, and
especially not on the A10 and A20 that this driver supports.
> it must not be used as source of randomness.
And I don't think that's true either. A constant entropy provider will
not add any entropy, but will not remove any, would it?
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* [PATCH v2] crypto: mxs-dcp - Remove hash support
From: Fabio Estevam @ 2016-10-24 16:43 UTC (permalink / raw)
To: herbert; +Cc: marex, gianfranco.costamagna, linux-crypto, Fabio Estevam
From: Fabio Estevam <fabio.estevam@nxp.com>
mxs-dcp driver does not probe for a long time:
mxs-dcp 80028000.dcp: Failed to register sha1 hash!
mxs-dcp: probe of 80028000.dcp failed with error -22
There were some previous attempts to fix this, and the following
feedback was given by Herbert Xu [1]:
"This driver is hopelessly broken as its request context doesn't
contain the hash state at all. Unless someone can fix that we
should probably just remove the hash implementations altogether."
[1] http://www.spinics.net/lists/linux-crypto/msg18187.html
So remove the hash support for now.
Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>
---
Changes since v1:
- Fix typo in commit log
drivers/crypto/mxs-dcp.c | 367 +----------------------------------------------
1 file changed, 2 insertions(+), 365 deletions(-)
diff --git a/drivers/crypto/mxs-dcp.c b/drivers/crypto/mxs-dcp.c
index 625ee50..b1b1dda 100644
--- a/drivers/crypto/mxs-dcp.c
+++ b/drivers/crypto/mxs-dcp.c
@@ -498,278 +498,6 @@ static void mxs_dcp_aes_fallback_exit(struct crypto_tfm *tfm)
crypto_free_skcipher(actx->fallback);
}
-/*
- * Hashing (SHA1/SHA256)
- */
-static int mxs_dcp_run_sha(struct ahash_request *req)
-{
- struct dcp *sdcp = global_sdcp;
- int ret;
-
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
- struct dcp_async_ctx *actx = crypto_ahash_ctx(tfm);
- struct dcp_sha_req_ctx *rctx = ahash_request_ctx(req);
- struct hash_alg_common *halg = crypto_hash_alg_common(tfm);
-
- struct dcp_dma_desc *desc = &sdcp->coh->desc[actx->chan];
-
- dma_addr_t digest_phys = 0;
- dma_addr_t buf_phys = dma_map_single(sdcp->dev, sdcp->coh->sha_in_buf,
- DCP_BUF_SZ, DMA_TO_DEVICE);
-
- /* Fill in the DMA descriptor. */
- desc->control0 = MXS_DCP_CONTROL0_DECR_SEMAPHORE |
- MXS_DCP_CONTROL0_INTERRUPT |
- MXS_DCP_CONTROL0_ENABLE_HASH;
- if (rctx->init)
- desc->control0 |= MXS_DCP_CONTROL0_HASH_INIT;
-
- desc->control1 = actx->alg;
- desc->next_cmd_addr = 0;
- desc->source = buf_phys;
- desc->destination = 0;
- desc->size = actx->fill;
- desc->payload = 0;
- desc->status = 0;
-
- /* Set HASH_TERM bit for last transfer block. */
- if (rctx->fini) {
- digest_phys = dma_map_single(sdcp->dev, req->result,
- halg->digestsize, DMA_FROM_DEVICE);
- desc->control0 |= MXS_DCP_CONTROL0_HASH_TERM;
- desc->payload = digest_phys;
- }
-
- ret = mxs_dcp_start_dma(actx);
-
- if (rctx->fini)
- dma_unmap_single(sdcp->dev, digest_phys, halg->digestsize,
- DMA_FROM_DEVICE);
-
- dma_unmap_single(sdcp->dev, buf_phys, DCP_BUF_SZ, DMA_TO_DEVICE);
-
- return ret;
-}
-
-static int dcp_sha_req_to_buf(struct crypto_async_request *arq)
-{
- struct dcp *sdcp = global_sdcp;
-
- struct ahash_request *req = ahash_request_cast(arq);
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
- struct dcp_async_ctx *actx = crypto_ahash_ctx(tfm);
- struct dcp_sha_req_ctx *rctx = ahash_request_ctx(req);
- struct hash_alg_common *halg = crypto_hash_alg_common(tfm);
- const int nents = sg_nents(req->src);
-
- uint8_t *in_buf = sdcp->coh->sha_in_buf;
-
- uint8_t *src_buf;
-
- struct scatterlist *src;
-
- unsigned int i, len, clen;
- int ret;
-
- int fin = rctx->fini;
- if (fin)
- rctx->fini = 0;
-
- for_each_sg(req->src, src, nents, i) {
- src_buf = sg_virt(src);
- len = sg_dma_len(src);
-
- do {
- if (actx->fill + len > DCP_BUF_SZ)
- clen = DCP_BUF_SZ - actx->fill;
- else
- clen = len;
-
- memcpy(in_buf + actx->fill, src_buf, clen);
- len -= clen;
- src_buf += clen;
- actx->fill += clen;
-
- /*
- * If we filled the buffer and still have some
- * more data, submit the buffer.
- */
- if (len && actx->fill == DCP_BUF_SZ) {
- ret = mxs_dcp_run_sha(req);
- if (ret)
- return ret;
- actx->fill = 0;
- rctx->init = 0;
- }
- } while (len);
- }
-
- if (fin) {
- rctx->fini = 1;
-
- /* Submit whatever is left. */
- if (!req->result)
- return -EINVAL;
-
- ret = mxs_dcp_run_sha(req);
- if (ret)
- return ret;
-
- actx->fill = 0;
-
- /* For some reason, the result is flipped. */
- for (i = 0; i < halg->digestsize / 2; i++) {
- swap(req->result[i],
- req->result[halg->digestsize - i - 1]);
- }
- }
-
- return 0;
-}
-
-static int dcp_chan_thread_sha(void *data)
-{
- struct dcp *sdcp = global_sdcp;
- const int chan = DCP_CHAN_HASH_SHA;
-
- struct crypto_async_request *backlog;
- struct crypto_async_request *arq;
-
- struct dcp_sha_req_ctx *rctx;
-
- struct ahash_request *req;
- int ret, fini;
-
- do {
- __set_current_state(TASK_INTERRUPTIBLE);
-
- mutex_lock(&sdcp->mutex[chan]);
- backlog = crypto_get_backlog(&sdcp->queue[chan]);
- arq = crypto_dequeue_request(&sdcp->queue[chan]);
- mutex_unlock(&sdcp->mutex[chan]);
-
- if (backlog)
- backlog->complete(backlog, -EINPROGRESS);
-
- if (arq) {
- req = ahash_request_cast(arq);
- rctx = ahash_request_ctx(req);
-
- ret = dcp_sha_req_to_buf(arq);
- fini = rctx->fini;
- arq->complete(arq, ret);
- if (!fini)
- continue;
- }
-
- schedule();
- } while (!kthread_should_stop());
-
- return 0;
-}
-
-static int dcp_sha_init(struct ahash_request *req)
-{
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
- struct dcp_async_ctx *actx = crypto_ahash_ctx(tfm);
-
- struct hash_alg_common *halg = crypto_hash_alg_common(tfm);
-
- /*
- * Start hashing session. The code below only inits the
- * hashing session context, nothing more.
- */
- memset(actx, 0, sizeof(*actx));
-
- if (strcmp(halg->base.cra_name, "sha1") == 0)
- actx->alg = MXS_DCP_CONTROL1_HASH_SELECT_SHA1;
- else
- actx->alg = MXS_DCP_CONTROL1_HASH_SELECT_SHA256;
-
- actx->fill = 0;
- actx->hot = 0;
- actx->chan = DCP_CHAN_HASH_SHA;
-
- mutex_init(&actx->mutex);
-
- return 0;
-}
-
-static int dcp_sha_update_fx(struct ahash_request *req, int fini)
-{
- struct dcp *sdcp = global_sdcp;
-
- struct dcp_sha_req_ctx *rctx = ahash_request_ctx(req);
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
- struct dcp_async_ctx *actx = crypto_ahash_ctx(tfm);
-
- int ret;
-
- /*
- * Ignore requests that have no data in them and are not
- * the trailing requests in the stream of requests.
- */
- if (!req->nbytes && !fini)
- return 0;
-
- mutex_lock(&actx->mutex);
-
- rctx->fini = fini;
-
- if (!actx->hot) {
- actx->hot = 1;
- rctx->init = 1;
- }
-
- mutex_lock(&sdcp->mutex[actx->chan]);
- ret = crypto_enqueue_request(&sdcp->queue[actx->chan], &req->base);
- mutex_unlock(&sdcp->mutex[actx->chan]);
-
- wake_up_process(sdcp->thread[actx->chan]);
- mutex_unlock(&actx->mutex);
-
- return -EINPROGRESS;
-}
-
-static int dcp_sha_update(struct ahash_request *req)
-{
- return dcp_sha_update_fx(req, 0);
-}
-
-static int dcp_sha_final(struct ahash_request *req)
-{
- ahash_request_set_crypt(req, NULL, req->result, 0);
- req->nbytes = 0;
- return dcp_sha_update_fx(req, 1);
-}
-
-static int dcp_sha_finup(struct ahash_request *req)
-{
- return dcp_sha_update_fx(req, 1);
-}
-
-static int dcp_sha_digest(struct ahash_request *req)
-{
- int ret;
-
- ret = dcp_sha_init(req);
- if (ret)
- return ret;
-
- return dcp_sha_finup(req);
-}
-
-static int dcp_sha_cra_init(struct crypto_tfm *tfm)
-{
- crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
- sizeof(struct dcp_sha_req_ctx));
- return 0;
-}
-
-static void dcp_sha_cra_exit(struct crypto_tfm *tfm)
-{
-}
-
/* AES 128 ECB and AES 128 CBC */
static struct crypto_alg dcp_aes_algs[] = {
{
@@ -822,54 +550,6 @@ static struct crypto_alg dcp_aes_algs[] = {
},
};
-/* SHA1 */
-static struct ahash_alg dcp_sha1_alg = {
- .init = dcp_sha_init,
- .update = dcp_sha_update,
- .final = dcp_sha_final,
- .finup = dcp_sha_finup,
- .digest = dcp_sha_digest,
- .halg = {
- .digestsize = SHA1_DIGEST_SIZE,
- .base = {
- .cra_name = "sha1",
- .cra_driver_name = "sha1-dcp",
- .cra_priority = 400,
- .cra_alignmask = 63,
- .cra_flags = CRYPTO_ALG_ASYNC,
- .cra_blocksize = SHA1_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct dcp_async_ctx),
- .cra_module = THIS_MODULE,
- .cra_init = dcp_sha_cra_init,
- .cra_exit = dcp_sha_cra_exit,
- },
- },
-};
-
-/* SHA256 */
-static struct ahash_alg dcp_sha256_alg = {
- .init = dcp_sha_init,
- .update = dcp_sha_update,
- .final = dcp_sha_final,
- .finup = dcp_sha_finup,
- .digest = dcp_sha_digest,
- .halg = {
- .digestsize = SHA256_DIGEST_SIZE,
- .base = {
- .cra_name = "sha256",
- .cra_driver_name = "sha256-dcp",
- .cra_priority = 400,
- .cra_alignmask = 63,
- .cra_flags = CRYPTO_ALG_ASYNC,
- .cra_blocksize = SHA256_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct dcp_async_ctx),
- .cra_module = THIS_MODULE,
- .cra_init = dcp_sha_cra_init,
- .cra_exit = dcp_sha_cra_exit,
- },
- },
-};
-
static irqreturn_t mxs_dcp_irq(int irq, void *context)
{
struct dcp *sdcp = context;
@@ -984,20 +664,12 @@ static int mxs_dcp_probe(struct platform_device *pdev)
crypto_init_queue(&sdcp->queue[i], 50);
}
- /* Create the SHA and AES handler threads. */
- sdcp->thread[DCP_CHAN_HASH_SHA] = kthread_run(dcp_chan_thread_sha,
- NULL, "mxs_dcp_chan/sha");
- if (IS_ERR(sdcp->thread[DCP_CHAN_HASH_SHA])) {
- dev_err(dev, "Error starting SHA thread!\n");
- return PTR_ERR(sdcp->thread[DCP_CHAN_HASH_SHA]);
- }
-
+ /* Create the AES handler threads. */
sdcp->thread[DCP_CHAN_CRYPTO] = kthread_run(dcp_chan_thread_aes,
NULL, "mxs_dcp_chan/aes");
if (IS_ERR(sdcp->thread[DCP_CHAN_CRYPTO])) {
dev_err(dev, "Error starting SHA thread!\n");
- ret = PTR_ERR(sdcp->thread[DCP_CHAN_CRYPTO]);
- goto err_destroy_sha_thread;
+ return PTR_ERR(sdcp->thread[DCP_CHAN_CRYPTO]);
}
/* Register the various crypto algorithms. */
@@ -1013,39 +685,10 @@ static int mxs_dcp_probe(struct platform_device *pdev)
}
}
- if (sdcp->caps & MXS_DCP_CAPABILITY1_SHA1) {
- ret = crypto_register_ahash(&dcp_sha1_alg);
- if (ret) {
- dev_err(dev, "Failed to register %s hash!\n",
- dcp_sha1_alg.halg.base.cra_name);
- goto err_unregister_aes;
- }
- }
-
- if (sdcp->caps & MXS_DCP_CAPABILITY1_SHA256) {
- ret = crypto_register_ahash(&dcp_sha256_alg);
- if (ret) {
- dev_err(dev, "Failed to register %s hash!\n",
- dcp_sha256_alg.halg.base.cra_name);
- goto err_unregister_sha1;
- }
- }
-
return 0;
-err_unregister_sha1:
- if (sdcp->caps & MXS_DCP_CAPABILITY1_SHA1)
- crypto_unregister_ahash(&dcp_sha1_alg);
-
-err_unregister_aes:
- if (sdcp->caps & MXS_DCP_CAPABILITY1_AES128)
- crypto_unregister_algs(dcp_aes_algs, ARRAY_SIZE(dcp_aes_algs));
-
err_destroy_aes_thread:
kthread_stop(sdcp->thread[DCP_CHAN_CRYPTO]);
-
-err_destroy_sha_thread:
- kthread_stop(sdcp->thread[DCP_CHAN_HASH_SHA]);
return ret;
}
@@ -1053,12 +696,6 @@ static int mxs_dcp_remove(struct platform_device *pdev)
{
struct dcp *sdcp = platform_get_drvdata(pdev);
- if (sdcp->caps & MXS_DCP_CAPABILITY1_SHA256)
- crypto_unregister_ahash(&dcp_sha256_alg);
-
- if (sdcp->caps & MXS_DCP_CAPABILITY1_SHA1)
- crypto_unregister_ahash(&dcp_sha1_alg);
-
if (sdcp->caps & MXS_DCP_CAPABILITY1_AES128)
crypto_unregister_algs(dcp_aes_algs, ARRAY_SIZE(dcp_aes_algs));
--
2.7.4
^ permalink raw reply related
* [PATCH] crypto: mxs-dcp - Remove hash support
From: Fabio Estevam @ 2016-10-24 16:40 UTC (permalink / raw)
To: herbert; +Cc: marex, gianfranco.costamagna, linux-crypto, Fabio Estevam
From: Fabio Estevam <fabio.estevam@nxp.com>
mxs-dcp driver does not probe for a long time:
mxs-dcp 80028000.dcp: Failed to register sha1 hash!
mxs-dcp: probe of 80028000.dcp failed with error -22
There were some previous attempts to fix this, and the following
feedback was given by Herbert Xu's [1]:
"This driver is hopelessly broken as its request context doesn't
contain the hash state at all. Unless someone can fix that we
should probably just remove the hash implementations altogether."
[1] http://www.spinics.net/lists/linux-crypto/msg18187.html
So remove the hash support for now.
Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>
---
drivers/crypto/mxs-dcp.c | 367 +----------------------------------------------
1 file changed, 2 insertions(+), 365 deletions(-)
diff --git a/drivers/crypto/mxs-dcp.c b/drivers/crypto/mxs-dcp.c
index 625ee50..b1b1dda 100644
--- a/drivers/crypto/mxs-dcp.c
+++ b/drivers/crypto/mxs-dcp.c
@@ -498,278 +498,6 @@ static void mxs_dcp_aes_fallback_exit(struct crypto_tfm *tfm)
crypto_free_skcipher(actx->fallback);
}
-/*
- * Hashing (SHA1/SHA256)
- */
-static int mxs_dcp_run_sha(struct ahash_request *req)
-{
- struct dcp *sdcp = global_sdcp;
- int ret;
-
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
- struct dcp_async_ctx *actx = crypto_ahash_ctx(tfm);
- struct dcp_sha_req_ctx *rctx = ahash_request_ctx(req);
- struct hash_alg_common *halg = crypto_hash_alg_common(tfm);
-
- struct dcp_dma_desc *desc = &sdcp->coh->desc[actx->chan];
-
- dma_addr_t digest_phys = 0;
- dma_addr_t buf_phys = dma_map_single(sdcp->dev, sdcp->coh->sha_in_buf,
- DCP_BUF_SZ, DMA_TO_DEVICE);
-
- /* Fill in the DMA descriptor. */
- desc->control0 = MXS_DCP_CONTROL0_DECR_SEMAPHORE |
- MXS_DCP_CONTROL0_INTERRUPT |
- MXS_DCP_CONTROL0_ENABLE_HASH;
- if (rctx->init)
- desc->control0 |= MXS_DCP_CONTROL0_HASH_INIT;
-
- desc->control1 = actx->alg;
- desc->next_cmd_addr = 0;
- desc->source = buf_phys;
- desc->destination = 0;
- desc->size = actx->fill;
- desc->payload = 0;
- desc->status = 0;
-
- /* Set HASH_TERM bit for last transfer block. */
- if (rctx->fini) {
- digest_phys = dma_map_single(sdcp->dev, req->result,
- halg->digestsize, DMA_FROM_DEVICE);
- desc->control0 |= MXS_DCP_CONTROL0_HASH_TERM;
- desc->payload = digest_phys;
- }
-
- ret = mxs_dcp_start_dma(actx);
-
- if (rctx->fini)
- dma_unmap_single(sdcp->dev, digest_phys, halg->digestsize,
- DMA_FROM_DEVICE);
-
- dma_unmap_single(sdcp->dev, buf_phys, DCP_BUF_SZ, DMA_TO_DEVICE);
-
- return ret;
-}
-
-static int dcp_sha_req_to_buf(struct crypto_async_request *arq)
-{
- struct dcp *sdcp = global_sdcp;
-
- struct ahash_request *req = ahash_request_cast(arq);
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
- struct dcp_async_ctx *actx = crypto_ahash_ctx(tfm);
- struct dcp_sha_req_ctx *rctx = ahash_request_ctx(req);
- struct hash_alg_common *halg = crypto_hash_alg_common(tfm);
- const int nents = sg_nents(req->src);
-
- uint8_t *in_buf = sdcp->coh->sha_in_buf;
-
- uint8_t *src_buf;
-
- struct scatterlist *src;
-
- unsigned int i, len, clen;
- int ret;
-
- int fin = rctx->fini;
- if (fin)
- rctx->fini = 0;
-
- for_each_sg(req->src, src, nents, i) {
- src_buf = sg_virt(src);
- len = sg_dma_len(src);
-
- do {
- if (actx->fill + len > DCP_BUF_SZ)
- clen = DCP_BUF_SZ - actx->fill;
- else
- clen = len;
-
- memcpy(in_buf + actx->fill, src_buf, clen);
- len -= clen;
- src_buf += clen;
- actx->fill += clen;
-
- /*
- * If we filled the buffer and still have some
- * more data, submit the buffer.
- */
- if (len && actx->fill == DCP_BUF_SZ) {
- ret = mxs_dcp_run_sha(req);
- if (ret)
- return ret;
- actx->fill = 0;
- rctx->init = 0;
- }
- } while (len);
- }
-
- if (fin) {
- rctx->fini = 1;
-
- /* Submit whatever is left. */
- if (!req->result)
- return -EINVAL;
-
- ret = mxs_dcp_run_sha(req);
- if (ret)
- return ret;
-
- actx->fill = 0;
-
- /* For some reason, the result is flipped. */
- for (i = 0; i < halg->digestsize / 2; i++) {
- swap(req->result[i],
- req->result[halg->digestsize - i - 1]);
- }
- }
-
- return 0;
-}
-
-static int dcp_chan_thread_sha(void *data)
-{
- struct dcp *sdcp = global_sdcp;
- const int chan = DCP_CHAN_HASH_SHA;
-
- struct crypto_async_request *backlog;
- struct crypto_async_request *arq;
-
- struct dcp_sha_req_ctx *rctx;
-
- struct ahash_request *req;
- int ret, fini;
-
- do {
- __set_current_state(TASK_INTERRUPTIBLE);
-
- mutex_lock(&sdcp->mutex[chan]);
- backlog = crypto_get_backlog(&sdcp->queue[chan]);
- arq = crypto_dequeue_request(&sdcp->queue[chan]);
- mutex_unlock(&sdcp->mutex[chan]);
-
- if (backlog)
- backlog->complete(backlog, -EINPROGRESS);
-
- if (arq) {
- req = ahash_request_cast(arq);
- rctx = ahash_request_ctx(req);
-
- ret = dcp_sha_req_to_buf(arq);
- fini = rctx->fini;
- arq->complete(arq, ret);
- if (!fini)
- continue;
- }
-
- schedule();
- } while (!kthread_should_stop());
-
- return 0;
-}
-
-static int dcp_sha_init(struct ahash_request *req)
-{
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
- struct dcp_async_ctx *actx = crypto_ahash_ctx(tfm);
-
- struct hash_alg_common *halg = crypto_hash_alg_common(tfm);
-
- /*
- * Start hashing session. The code below only inits the
- * hashing session context, nothing more.
- */
- memset(actx, 0, sizeof(*actx));
-
- if (strcmp(halg->base.cra_name, "sha1") == 0)
- actx->alg = MXS_DCP_CONTROL1_HASH_SELECT_SHA1;
- else
- actx->alg = MXS_DCP_CONTROL1_HASH_SELECT_SHA256;
-
- actx->fill = 0;
- actx->hot = 0;
- actx->chan = DCP_CHAN_HASH_SHA;
-
- mutex_init(&actx->mutex);
-
- return 0;
-}
-
-static int dcp_sha_update_fx(struct ahash_request *req, int fini)
-{
- struct dcp *sdcp = global_sdcp;
-
- struct dcp_sha_req_ctx *rctx = ahash_request_ctx(req);
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
- struct dcp_async_ctx *actx = crypto_ahash_ctx(tfm);
-
- int ret;
-
- /*
- * Ignore requests that have no data in them and are not
- * the trailing requests in the stream of requests.
- */
- if (!req->nbytes && !fini)
- return 0;
-
- mutex_lock(&actx->mutex);
-
- rctx->fini = fini;
-
- if (!actx->hot) {
- actx->hot = 1;
- rctx->init = 1;
- }
-
- mutex_lock(&sdcp->mutex[actx->chan]);
- ret = crypto_enqueue_request(&sdcp->queue[actx->chan], &req->base);
- mutex_unlock(&sdcp->mutex[actx->chan]);
-
- wake_up_process(sdcp->thread[actx->chan]);
- mutex_unlock(&actx->mutex);
-
- return -EINPROGRESS;
-}
-
-static int dcp_sha_update(struct ahash_request *req)
-{
- return dcp_sha_update_fx(req, 0);
-}
-
-static int dcp_sha_final(struct ahash_request *req)
-{
- ahash_request_set_crypt(req, NULL, req->result, 0);
- req->nbytes = 0;
- return dcp_sha_update_fx(req, 1);
-}
-
-static int dcp_sha_finup(struct ahash_request *req)
-{
- return dcp_sha_update_fx(req, 1);
-}
-
-static int dcp_sha_digest(struct ahash_request *req)
-{
- int ret;
-
- ret = dcp_sha_init(req);
- if (ret)
- return ret;
-
- return dcp_sha_finup(req);
-}
-
-static int dcp_sha_cra_init(struct crypto_tfm *tfm)
-{
- crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
- sizeof(struct dcp_sha_req_ctx));
- return 0;
-}
-
-static void dcp_sha_cra_exit(struct crypto_tfm *tfm)
-{
-}
-
/* AES 128 ECB and AES 128 CBC */
static struct crypto_alg dcp_aes_algs[] = {
{
@@ -822,54 +550,6 @@ static struct crypto_alg dcp_aes_algs[] = {
},
};
-/* SHA1 */
-static struct ahash_alg dcp_sha1_alg = {
- .init = dcp_sha_init,
- .update = dcp_sha_update,
- .final = dcp_sha_final,
- .finup = dcp_sha_finup,
- .digest = dcp_sha_digest,
- .halg = {
- .digestsize = SHA1_DIGEST_SIZE,
- .base = {
- .cra_name = "sha1",
- .cra_driver_name = "sha1-dcp",
- .cra_priority = 400,
- .cra_alignmask = 63,
- .cra_flags = CRYPTO_ALG_ASYNC,
- .cra_blocksize = SHA1_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct dcp_async_ctx),
- .cra_module = THIS_MODULE,
- .cra_init = dcp_sha_cra_init,
- .cra_exit = dcp_sha_cra_exit,
- },
- },
-};
-
-/* SHA256 */
-static struct ahash_alg dcp_sha256_alg = {
- .init = dcp_sha_init,
- .update = dcp_sha_update,
- .final = dcp_sha_final,
- .finup = dcp_sha_finup,
- .digest = dcp_sha_digest,
- .halg = {
- .digestsize = SHA256_DIGEST_SIZE,
- .base = {
- .cra_name = "sha256",
- .cra_driver_name = "sha256-dcp",
- .cra_priority = 400,
- .cra_alignmask = 63,
- .cra_flags = CRYPTO_ALG_ASYNC,
- .cra_blocksize = SHA256_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct dcp_async_ctx),
- .cra_module = THIS_MODULE,
- .cra_init = dcp_sha_cra_init,
- .cra_exit = dcp_sha_cra_exit,
- },
- },
-};
-
static irqreturn_t mxs_dcp_irq(int irq, void *context)
{
struct dcp *sdcp = context;
@@ -984,20 +664,12 @@ static int mxs_dcp_probe(struct platform_device *pdev)
crypto_init_queue(&sdcp->queue[i], 50);
}
- /* Create the SHA and AES handler threads. */
- sdcp->thread[DCP_CHAN_HASH_SHA] = kthread_run(dcp_chan_thread_sha,
- NULL, "mxs_dcp_chan/sha");
- if (IS_ERR(sdcp->thread[DCP_CHAN_HASH_SHA])) {
- dev_err(dev, "Error starting SHA thread!\n");
- return PTR_ERR(sdcp->thread[DCP_CHAN_HASH_SHA]);
- }
-
+ /* Create the AES handler threads. */
sdcp->thread[DCP_CHAN_CRYPTO] = kthread_run(dcp_chan_thread_aes,
NULL, "mxs_dcp_chan/aes");
if (IS_ERR(sdcp->thread[DCP_CHAN_CRYPTO])) {
dev_err(dev, "Error starting SHA thread!\n");
- ret = PTR_ERR(sdcp->thread[DCP_CHAN_CRYPTO]);
- goto err_destroy_sha_thread;
+ return PTR_ERR(sdcp->thread[DCP_CHAN_CRYPTO]);
}
/* Register the various crypto algorithms. */
@@ -1013,39 +685,10 @@ static int mxs_dcp_probe(struct platform_device *pdev)
}
}
- if (sdcp->caps & MXS_DCP_CAPABILITY1_SHA1) {
- ret = crypto_register_ahash(&dcp_sha1_alg);
- if (ret) {
- dev_err(dev, "Failed to register %s hash!\n",
- dcp_sha1_alg.halg.base.cra_name);
- goto err_unregister_aes;
- }
- }
-
- if (sdcp->caps & MXS_DCP_CAPABILITY1_SHA256) {
- ret = crypto_register_ahash(&dcp_sha256_alg);
- if (ret) {
- dev_err(dev, "Failed to register %s hash!\n",
- dcp_sha256_alg.halg.base.cra_name);
- goto err_unregister_sha1;
- }
- }
-
return 0;
-err_unregister_sha1:
- if (sdcp->caps & MXS_DCP_CAPABILITY1_SHA1)
- crypto_unregister_ahash(&dcp_sha1_alg);
-
-err_unregister_aes:
- if (sdcp->caps & MXS_DCP_CAPABILITY1_AES128)
- crypto_unregister_algs(dcp_aes_algs, ARRAY_SIZE(dcp_aes_algs));
-
err_destroy_aes_thread:
kthread_stop(sdcp->thread[DCP_CHAN_CRYPTO]);
-
-err_destroy_sha_thread:
- kthread_stop(sdcp->thread[DCP_CHAN_HASH_SHA]);
return ret;
}
@@ -1053,12 +696,6 @@ static int mxs_dcp_remove(struct platform_device *pdev)
{
struct dcp *sdcp = platform_get_drvdata(pdev);
- if (sdcp->caps & MXS_DCP_CAPABILITY1_SHA256)
- crypto_unregister_ahash(&dcp_sha256_alg);
-
- if (sdcp->caps & MXS_DCP_CAPABILITY1_SHA1)
- crypto_unregister_ahash(&dcp_sha1_alg);
-
if (sdcp->caps & MXS_DCP_CAPABILITY1_AES128)
crypto_unregister_algs(dcp_aes_algs, ARRAY_SIZE(dcp_aes_algs));
--
2.7.4
^ permalink raw reply related
* [PATCH -next] crypto: drop pointless static qualifier in atmel_aes_probe()
From: Wei Yongjun @ 2016-10-24 14:51 UTC (permalink / raw)
To: Herbert Xu; +Cc: Wei Yongjun, linux-crypto
From: Wei Yongjun <weiyongjun1@huawei.com>
There is no need to have the 'struct atmel_aes_dev *aes_dd' variable
static since new value always be assigned before use it.
Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
---
drivers/crypto/atmel-aes.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c
index 6b656f4..0e3d0d6 100644
--- a/drivers/crypto/atmel-aes.c
+++ b/drivers/crypto/atmel-aes.c
@@ -2311,7 +2311,7 @@ static int atmel_aes_probe(struct platform_device *pdev)
static int atmel_aes_remove(struct platform_device *pdev)
{
- static struct atmel_aes_dev *aes_dd;
+ struct atmel_aes_dev *aes_dd;
aes_dd = platform_get_drvdata(pdev);
if (!aes_dd)
^ permalink raw reply related
* Re: [PATCH v1] char: hw_random: atmel-rng: disable TRNG during suspend
From: Nicolas Ferre @ 2016-10-24 12:07 UTC (permalink / raw)
To: Wenyou Yang, Herbert Xu, Matt Mackall
Cc: linux-crypto, Wenyou Yang, linux-arm-kernel
In-Reply-To: <1477296208-28335-1-git-send-email-wenyou.yang@atmel.com>
Le 24/10/2016 à 10:03, Wenyou Yang a écrit :
> To fix the over consumption on the VDDCore due to the TRNG enabled,
> disable the TRNG during suspend, not only disable the user interface
> clock (which is controlled by PMC). Because the user interface clock
> is independent from any clock that may be used in the entropy source
> logic circuitry.
>
> Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
> ---
>
> drivers/char/hw_random/atmel-rng.c | 16 ++++++++++++++--
> 1 file changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c
> index 0fcc9e6..2e2d09a 100644
> --- a/drivers/char/hw_random/atmel-rng.c
> +++ b/drivers/char/hw_random/atmel-rng.c
> @@ -48,6 +48,16 @@ static int atmel_trng_read(struct hwrng *rng, void *buf, size_t max,
> return 0;
> }
>
> +static void atmel_trng_enable(struct atmel_trng *trng)
> +{
> + writel(TRNG_KEY | 1, trng->base + TRNG_CR);
> +}
> +
> +static void atmel_trng_disable(struct atmel_trng *trng)
> +{
> + writel(TRNG_KEY, trng->base + TRNG_CR);
> +}
> +
> static int atmel_trng_probe(struct platform_device *pdev)
> {
> struct atmel_trng *trng;
> @@ -71,7 +81,7 @@ static int atmel_trng_probe(struct platform_device *pdev)
> if (ret)
> return ret;
>
> - writel(TRNG_KEY | 1, trng->base + TRNG_CR);
> + atmel_trng_enable(trng);
> trng->rng.name = pdev->name;
> trng->rng.read = atmel_trng_read;
>
> @@ -94,7 +104,7 @@ static int atmel_trng_remove(struct platform_device *pdev)
>
> hwrng_unregister(&trng->rng);
>
> - writel(TRNG_KEY, trng->base + TRNG_CR);
> + atmel_trng_disable(trng);
> clk_disable_unprepare(trng->clk);
>
> return 0;
> @@ -105,6 +115,7 @@ static int atmel_trng_suspend(struct device *dev)
> {
> struct atmel_trng *trng = dev_get_drvdata(dev);
>
> + atmel_trng_disable(trng);
> clk_disable_unprepare(trng->clk);
>
> return 0;
> @@ -114,6 +125,7 @@ static int atmel_trng_resume(struct device *dev)
> {
> struct atmel_trng *trng = dev_get_drvdata(dev);
>
> + atmel_trng_enable(trng);
> return clk_prepare_enable(trng->clk);
Isn't it the other way around:
enable the user interface first, then enable the internal clock? like:
clk_prepare_enable(trng->clk);
atmel_trng_enable(trng);
Regards,
--
Nicolas Ferre
^ permalink raw reply
* [PATCH v1] char: hw_random: atmel-rng: disable TRNG during suspend
From: Wenyou Yang @ 2016-10-24 8:03 UTC (permalink / raw)
To: Herbert Xu, Matt Mackall
Cc: linux-crypto, Wenyou Yang, linux-arm-kernel, Nicolas Ferre,
Wenyou Yang
To fix the over consumption on the VDDCore due to the TRNG enabled,
disable the TRNG during suspend, not only disable the user interface
clock (which is controlled by PMC). Because the user interface clock
is independent from any clock that may be used in the entropy source
logic circuitry.
Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
---
drivers/char/hw_random/atmel-rng.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c
index 0fcc9e6..2e2d09a 100644
--- a/drivers/char/hw_random/atmel-rng.c
+++ b/drivers/char/hw_random/atmel-rng.c
@@ -48,6 +48,16 @@ static int atmel_trng_read(struct hwrng *rng, void *buf, size_t max,
return 0;
}
+static void atmel_trng_enable(struct atmel_trng *trng)
+{
+ writel(TRNG_KEY | 1, trng->base + TRNG_CR);
+}
+
+static void atmel_trng_disable(struct atmel_trng *trng)
+{
+ writel(TRNG_KEY, trng->base + TRNG_CR);
+}
+
static int atmel_trng_probe(struct platform_device *pdev)
{
struct atmel_trng *trng;
@@ -71,7 +81,7 @@ static int atmel_trng_probe(struct platform_device *pdev)
if (ret)
return ret;
- writel(TRNG_KEY | 1, trng->base + TRNG_CR);
+ atmel_trng_enable(trng);
trng->rng.name = pdev->name;
trng->rng.read = atmel_trng_read;
@@ -94,7 +104,7 @@ static int atmel_trng_remove(struct platform_device *pdev)
hwrng_unregister(&trng->rng);
- writel(TRNG_KEY, trng->base + TRNG_CR);
+ atmel_trng_disable(trng);
clk_disable_unprepare(trng->clk);
return 0;
@@ -105,6 +115,7 @@ static int atmel_trng_suspend(struct device *dev)
{
struct atmel_trng *trng = dev_get_drvdata(dev);
+ atmel_trng_disable(trng);
clk_disable_unprepare(trng->clk);
return 0;
@@ -114,6 +125,7 @@ static int atmel_trng_resume(struct device *dev)
{
struct atmel_trng *trng = dev_get_drvdata(dev);
+ atmel_trng_enable(trng);
return clk_prepare_enable(trng->clk);
}
--
2.7.4
^ permalink raw reply related
* Re: [PATCH v2 0/8] Conversion crypto API documentation to Sphinx
From: Stephan Mueller @ 2016-10-23 16:46 UTC (permalink / raw)
To: Jonathan Corbet; +Cc: herbert, linux-crypto, linux-doc
In-Reply-To: <20161023103238.4fceddac@lwn.net>
Am Sonntag, 23. Oktober 2016, 10:32:38 CEST schrieb Jonathan Corbet:
Hi Jonathan,
> On Fri, 21 Oct 2016 04:53:45 +0200
>
> Stephan Mueller <smueller@chronox.de> wrote:
> > the attached patch set converts the existing crypto API documentation
> > from DocBook to Sphinx.
>
> This looks generally good to me - thanks for doing it!
>
> Is there any chance of running the Documentation/ parts through the docs
> tree? Documentation/index.rst has become a bit of a conflict point
> otherwise...
Unless Herbert objects, I would not see any reason why we should not push it
through the docs tree.
Yet we should wait for Herbert's ack as I have added also new information in
the patch set (the KPP API documentation and the change in the AEAD
documentation).
Ciao
Stephan
^ permalink raw reply
* Re: [PATCH v2 0/8] Conversion crypto API documentation to Sphinx
From: Jonathan Corbet @ 2016-10-23 16:32 UTC (permalink / raw)
To: Stephan Mueller; +Cc: herbert, linux-crypto, linux-doc
In-Reply-To: <2053893.WjF01BJSDF@positron.chronox.de>
On Fri, 21 Oct 2016 04:53:45 +0200
Stephan Mueller <smueller@chronox.de> wrote:
> the attached patch set converts the existing crypto API documentation
> from DocBook to Sphinx.
This looks generally good to me - thanks for doing it!
Is there any chance of running the Documentation/ parts through the docs
tree? Documentation/index.rst has become a bit of a conflict point
otherwise...
Thanks,
jon
^ permalink raw reply
* [ANNOUNCE] /dev/random - a new approach code for 4.9-rc1
From: Stephan Mueller @ 2016-10-22 23:54 UTC (permalink / raw)
To: linux-crypto, linux-kernel
Hi,
The patch set that can be downloaded at [1] provides a different approach to /
dev/random which I call Linux Random Number Generator (LRNG) to collect
entropy within the Linux kernel. The main improvements compared to the legacy
/dev/random is to provide sufficient entropy during boot time as well as in
virtual environments and when using SSDs or Device Mapper targets. A secondary
design goal is to limit the impact of the entropy collection on massive
parallel systems and also allow the use accelerated cryptographic primitives.
Also, all steps of the entropic data processing are testable. Finally
performance improvements are visible at /dev/urandom and get_random_bytes.
The design and implementation is driven by a set of goals described in [2]
that the LRNG completely implements. Furthermore, [2] includes a
comparison with RNG design suggestions such as SP800-90B, SP800-90C, and
AIS20/31.
[1] http://www.chronox.de/lrng.html
[2] http://www.chronox.de/lrng/doc/lrng.pdf
Ciao
Stephan
^ permalink raw reply
* Talent Scout
From: Camilia Brunnet @ 2016-10-22 17:31 UTC (permalink / raw)
To: Recipients
Dear Concern,
I am Talent Scout For BLUE SKY FILM STUDIO, Present Blue sky Studio a
Film Corporation Located in the United State, is Soliciting for the
Right to use Your Photo/Face and Personality as One of the Semi -Major
Role/ Character in our Upcoming ANIMATED Stereoscope 3D Movie-The Story
of Ferdinand (Ferdinand 2017) The Movie is Currently Filming (In
Production) Please Note That There Will Be No Auditions, Traveling or
Any Special / Professional Acting Skills, Since the Production of This
Movie Will Be Done with our State of Art Computer -Generating Imagery
Equipment. We Are Prepared to Pay the Total Sum of $620,000.00 USD. For
More Information/Understanding, Please Write us on the E-Mail Below.
CONTACT EMAIL: blueskystudios@usa.com
All Reply to: blueskystudios@usa.com
Note: Only the Response send to this mail will be Given a Prior
Consideration.
Talent Scout
Camilia Brunnet
^ permalink raw reply
* Talent Scout
From: Camilia Brunnet @ 2016-10-22 17:27 UTC (permalink / raw)
To: Recipients
Dear Concern,
I am Talent Scout For BLUE SKY FILM STUDIO, Present Blue sky Studio a
Film Corporation Located in the United State, is Soliciting for the
Right to use Your Photo/Face and Personality as One of the Semi -Major
Role/ Character in our Upcoming ANIMATED Stereoscope 3D Movie-The Story
of Ferdinand (Ferdinand 2017) The Movie is Currently Filming (In
Production) Please Note That There Will Be No Auditions, Traveling or
Any Special / Professional Acting Skills, Since the Production of This
Movie Will Be Done with our State of Art Computer -Generating Imagery
Equipment. We Are Prepared to Pay the Total Sum of $620,000.00 USD. For
More Information/Understanding, Please Write us on the E-Mail Below.
CONTACT EMAIL: blueskystudios@usa.com
All Reply to: blueskystudios@usa.com
Note: Only the Response send to this mail will be Given a Prior
Consideration.
Talent Scout
Camilia Brunnet
^ permalink raw reply
* [PATCH] hwrng: core - zeroize buffers with random data
From: Stephan Mueller @ 2016-10-22 13:57 UTC (permalink / raw)
To: herbert; +Cc: linux-crypto, Andy Lutomirski
Hi Herbert,
As requested by Andy, I have created the following patch. This patch is against the cryptodev-2.6 tree and applies cleanly. However, due to Andy's patch to Linus' tree, the patch will fail to apply to that tree.
How would you want to proceed? Do you want to pull Andy's patch into your cryptodev-2.6 tree which means I will rework the patch?
Thanks
Stephan
---8<---
The HWRNG core allocates two buffers during initialization which are
used to obtain random data. After that data is processed, it is now
zeroized as it is possible that the HWRNG core will not be asked to
produce more random data for a long time. This prevents leaving such
sensitive data in memory.
Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
drivers/char/hw_random/core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index d2d2c89..f976641 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -92,6 +92,7 @@ static void add_early_randomness(struct hwrng *rng)
mutex_unlock(&reading_mutex);
if (bytes_read > 0)
add_device_randomness(rng_buffer, bytes_read);
+ memset(rng_buffer, 0, size);
}
static inline void cleanup_rng(struct kref *kref)
@@ -287,6 +288,7 @@ static ssize_t rng_dev_read(struct file *filp, char __user *buf,
}
}
out:
+ memset(rng_buffer, 0, rng_buffer_size());
return ret ? : err;
out_unlock_reading:
@@ -425,6 +427,7 @@ static int hwrng_fillfn(void *unused)
/* Outside lock, sure, but y'know: randomness. */
add_hwgenerator_randomness((void *)rng_fillbuf, rc,
rc * current_quality * 8 >> 10);
+ memset(rng_fillbuf, 0, rng_buffer_size());
}
hwrng_fill = NULL;
return 0;
--
2.7.4
^ permalink raw reply related
* [PATCH] nvmem: sunxi-sid: SID content is not a valid source of randomness
From: Corentin Labbe @ 2016-10-22 13:53 UTC (permalink / raw)
To: srinivas.kandagatla, maxime.ripard, wens
Cc: linux-arm-kernel, linux-kernel, linux-crypto, Corentin Labbe
Since SID's content is constant over reboot, it must not be used
as source of randomness.
This patch remove the use of SID content as source of randomness.
Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
---
drivers/nvmem/sunxi_sid.c | 21 ---------------------
1 file changed, 21 deletions(-)
diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c
index 1567ccc..c82d5d1 100644
--- a/drivers/nvmem/sunxi_sid.c
+++ b/drivers/nvmem/sunxi_sid.c
@@ -21,8 +21,6 @@
#include <linux/nvmem-provider.h>
#include <linux/of.h>
#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/random.h>
static struct nvmem_config econfig = {
.name = "sunxi-sid",
@@ -70,8 +68,6 @@ static int sunxi_sid_probe(struct platform_device *pdev)
struct resource *res;
struct nvmem_device *nvmem;
struct sunxi_sid *sid;
- int ret, i, size;
- char *randomness;
sid = devm_kzalloc(dev, sizeof(*sid), GFP_KERNEL);
if (!sid)
@@ -82,7 +78,6 @@ static int sunxi_sid_probe(struct platform_device *pdev)
if (IS_ERR(sid->base))
return PTR_ERR(sid->base);
- size = resource_size(res) - 1;
econfig.size = resource_size(res);
econfig.dev = dev;
econfig.reg_read = sunxi_sid_read;
@@ -91,25 +86,9 @@ static int sunxi_sid_probe(struct platform_device *pdev)
if (IS_ERR(nvmem))
return PTR_ERR(nvmem);
- randomness = kzalloc(sizeof(u8) * (size), GFP_KERNEL);
- if (!randomness) {
- ret = -EINVAL;
- goto err_unreg_nvmem;
- }
-
- for (i = 0; i < size; i++)
- randomness[i] = sunxi_sid_read_byte(sid, i);
-
- add_device_randomness(randomness, size);
- kfree(randomness);
-
platform_set_drvdata(pdev, nvmem);
return 0;
-
-err_unreg_nvmem:
- nvmem_unregister(nvmem);
- return ret;
}
static int sunxi_sid_remove(struct platform_device *pdev)
--
2.7.3
^ permalink raw reply related
* Re: [PATCH RESEND] hwrng: core - don't pass stack allocated buffer to rng->read()
From: Laszlo Ersek @ 2016-10-21 21:34 UTC (permalink / raw)
To: Richard W.M. Jones, Andy Lutomirski
Cc: linux-crypto, linux-kernel@vger.kernel.org, stable, Amit Shah,
Andy Lutomirski, Herbert Xu, Kees Cook, Matt Mackall
In-Reply-To: <20161021211739.GR11243@redhat.com>
On 10/21/16 23:17, Richard W.M. Jones wrote:
> On Fri, Oct 21, 2016 at 02:04:27PM -0700, Andy Lutomirski wrote:
>> https://git.kernel.org/cgit/linux/kernel/git/herbert/cryptodev-2.6.git/commit/?id=6d4952d9d9d4dc2bb9c0255d95a09405a1e958f7
>
> I have tested this one, and it also fixes the bug I was seeing.
>
> Thanks Laszlo as well for his fix, and sorry for not finding the
> patch above first.
No problem, it was fun :)
^ permalink raw reply
* Re: [PATCH RESEND] hwrng: core - don't pass stack allocated buffer to rng->read()
From: Laszlo Ersek @ 2016-10-21 21:34 UTC (permalink / raw)
To: Andy Lutomirski
Cc: linux-crypto, linux-kernel@vger.kernel.org, Richard W.M. Jones,
stable, Amit Shah, Andy Lutomirski, Herbert Xu, Kees Cook,
Matt Mackall
In-Reply-To: <CALCETrUUBJT81Yxm7f19kX+dbyqx9skYEVjYMzMx4zm-vGWWXQ@mail.gmail.com>
On 10/21/16 23:04, Andy Lutomirski wrote:
> On Fri, Oct 21, 2016 at 1:48 PM, Laszlo Ersek <lersek@redhat.com> wrote:
>> The virtio-rng backend for hwrng passes the buffer that it receives for
>> filling to sg_set_buf() directly, in:
>>
>> virtio_read() [drivers/char/hw_random/virtio-rng.c]
>> register_buffer() [drivers/char/hw_random/virtio-rng.c]
>> sg_init_one() [lib/scatterlist.c]
>> sg_set_buf() [include/linux/scatterlist.h]
>>
>> In turn, the sg_set_buf() function, when built with CONFIG_DEBUG_SG,
>> actively enforces (justifiedly) that the buffer used within the
>> scatter-gather list live in physically contiguous memory:
>>
>> BUG_ON(!virt_addr_valid(buf));
>>
>> The combination of the above two facts means that whatever calls
>> virtio_read() -- via the hwrng.read() method -- has to allocate the
>> recipient buffer in physically contiguous memory.
>
> Indeed. This bug should be fixed by:
>
> https://git.kernel.org/cgit/linux/kernel/git/herbert/cryptodev-2.6.git/commit/?id=6d4952d9d9d4dc2bb9c0255d95a09405a1e958f7
>
Cool, thanks!
(My commit message is better tho ;))
Cheers
Laszlo
^ permalink raw reply
* Re: [PATCH RESEND] hwrng: core - don't pass stack allocated buffer to rng->read()
From: Richard W.M. Jones @ 2016-10-21 21:17 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Laszlo Ersek, linux-crypto, linux-kernel@vger.kernel.org, stable,
Amit Shah, Andy Lutomirski, Herbert Xu, Kees Cook, Matt Mackall
In-Reply-To: <CALCETrUUBJT81Yxm7f19kX+dbyqx9skYEVjYMzMx4zm-vGWWXQ@mail.gmail.com>
On Fri, Oct 21, 2016 at 02:04:27PM -0700, Andy Lutomirski wrote:
> https://git.kernel.org/cgit/linux/kernel/git/herbert/cryptodev-2.6.git/commit/?id=6d4952d9d9d4dc2bb9c0255d95a09405a1e958f7
I have tested this one, and it also fixes the bug I was seeing.
Thanks Laszlo as well for his fix, and sorry for not finding the
patch above first.
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
Fedora Windows cross-compiler. Compile Windows programs, test, and
build Windows installers. Over 100 libraries supported.
http://fedoraproject.org/wiki/MinGW
^ permalink raw reply
* Re: [PATCH RESEND] hwrng: core - don't pass stack allocated buffer to rng->read()
From: Andy Lutomirski @ 2016-10-21 21:04 UTC (permalink / raw)
To: Laszlo Ersek
Cc: linux-crypto, linux-kernel@vger.kernel.org, Richard W.M. Jones,
stable, Amit Shah, Andy Lutomirski, Herbert Xu, Kees Cook,
Matt Mackall
In-Reply-To: <20161021204809.14068-1-lersek@redhat.com>
On Fri, Oct 21, 2016 at 1:48 PM, Laszlo Ersek <lersek@redhat.com> wrote:
> The virtio-rng backend for hwrng passes the buffer that it receives for
> filling to sg_set_buf() directly, in:
>
> virtio_read() [drivers/char/hw_random/virtio-rng.c]
> register_buffer() [drivers/char/hw_random/virtio-rng.c]
> sg_init_one() [lib/scatterlist.c]
> sg_set_buf() [include/linux/scatterlist.h]
>
> In turn, the sg_set_buf() function, when built with CONFIG_DEBUG_SG,
> actively enforces (justifiedly) that the buffer used within the
> scatter-gather list live in physically contiguous memory:
>
> BUG_ON(!virt_addr_valid(buf));
>
> The combination of the above two facts means that whatever calls
> virtio_read() -- via the hwrng.read() method -- has to allocate the
> recipient buffer in physically contiguous memory.
Indeed. This bug should be fixed by:
https://git.kernel.org/cgit/linux/kernel/git/herbert/cryptodev-2.6.git/commit/?id=6d4952d9d9d4dc2bb9c0255d95a09405a1e958f7
^ permalink raw reply
* [PATCH RESEND] hwrng: core - don't pass stack allocated buffer to rng->read()
From: Laszlo Ersek @ 2016-10-21 20:48 UTC (permalink / raw)
To: linux-crypto, linux-kernel, Laszlo Ersek
Cc: Richard W.M. Jones, stable, Amit Shah, Andy Lutomirski,
Herbert Xu, Kees Cook, Matt Mackall
The virtio-rng backend for hwrng passes the buffer that it receives for
filling to sg_set_buf() directly, in:
virtio_read() [drivers/char/hw_random/virtio-rng.c]
register_buffer() [drivers/char/hw_random/virtio-rng.c]
sg_init_one() [lib/scatterlist.c]
sg_set_buf() [include/linux/scatterlist.h]
In turn, the sg_set_buf() function, when built with CONFIG_DEBUG_SG,
actively enforces (justifiedly) that the buffer used within the
scatter-gather list live in physically contiguous memory:
BUG_ON(!virt_addr_valid(buf));
The combination of the above two facts means that whatever calls
virtio_read() -- via the hwrng.read() method -- has to allocate the
recipient buffer in physically contiguous memory.
Although this ends up being a generic interface restriction that is not
documented at the abstract hwrng level ("include/linux/hw_random.h",
"Documentation/hw_random.txt"), the virtio-rng provider has not been
changed to implement bounce buffering. Instead, existing core commits have
accommodated the silent restriction, such as:
- f7f154f1246c hw_random: make buffer usable in scatterlist.
which would allocate "rng_buffer" with kmalloc(), and
- be4000bc4644 hwrng: create filler thread
which would allocate the new "rng_fillbuf" similarly.
One call site remains that breaks the silent restriction: the
add_early_randomness() function passes an on-stack array to hwrng.read(),
via rng_get_data(), resulting in the following (valid) BUG, when
CONFIG_DEBUG_SG is enabled:
> ------------[ cut here ]------------
> kernel BUG at ./include/linux/scatterlist.h:140!
> invalid opcode: 0000 [#1] SMP
> Modules linked in: virtio_pci(+) virtio_mmio virtio_input virtio_balloon
> virtio_scsi nd_pmem nd_btt virtio_net virtio_console virtio_rng
> virtio_blk virtio_ring virtio nfit crc32_generic crct10dif_pclmul
> crc32c_intel crc32_pclmul
> CPU: 0 PID: 1 Comm: init Not tainted 4.9.0-0.rc0.git6.2.fc26.x86_64 #1
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.3-1.fc26
> 04/01/2014
> task: ffff91f29de53240 task.stack: ffffb820000cc000
> RIP: 0010:[<ffffffff8347e3fc>] [<ffffffff8347e3fc>]
> sg_init_one+0x8c/0xa0
> RSP: 0018:ffffb820000cf7d0 EFLAGS: 00010246
> RAX: 0000000000000000 RBX: ffffb820000cf858 RCX: 0000000000000028
> RDX: 0000262d800cf858 RSI: 0000000000000026 RDI: ffffb820800cf858
> RBP: ffffb820000cf7e8 R08: 000000000000006a R09: ffffb820000cf7f8
> R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000010
> R13: ffffb820000cf7f8 R14: 0000000000000010 R15: 0000000000000000
> FS: 00007fffd6e6e140(0000) GS:ffff91f29ee00000(0000)
> knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00007fc67e24e000 CR3: 000000001bdad000 CR4: 00000000000406f0
> Stack:
> ffff91f29be3b400 0000000000000001 ffffb820000cf858 ffffb820000cf848
> ffffffffc0056226 0000000087654321 0000000000000002 0000000000000000
> 0000000000000000 0000000000000000 000000002a14e409 ffff91f29be3b400
> Call Trace:
> [<ffffffffc0056226>] virtio_read+0xc6/0x110 [virtio_rng]
> [<ffffffff835be9ee>] add_early_randomness+0x5e/0xd0
> [<ffffffff835beaa5>] set_current_rng+0x45/0x160
> [<ffffffff835bee47>] hwrng_register+0xf7/0x130
> [<ffffffffc0056149>] virtrng_scan+0x19/0x30 [virtio_rng]
> [<ffffffffc00467a8>] virtio_dev_probe+0x198/0x1e0 [virtio]
> [<ffffffff835ebd53>] driver_probe_device+0x223/0x430
> [<ffffffff835ec0dc>] __device_attach_driver+0x8c/0x100
> [<ffffffff835ec050>] ? __driver_attach+0xf0/0xf0
> [<ffffffff835e972a>] bus_for_each_drv+0x6a/0xb0
> [<ffffffff835eb9c2>] __device_attach+0xe2/0x160
> [<ffffffff835ec193>] device_initial_probe+0x13/0x20
> [<ffffffff835eab93>] bus_probe_device+0xa3/0xb0
> [<ffffffff835e85f2>] device_add+0x382/0x650
> [<ffffffffc00929b0>] ? vp_modern_find_vqs+0x70/0x70 [virtio_pci]
> [<ffffffffc00929b0>] ? vp_modern_find_vqs+0x70/0x70 [virtio_pci]
> [<ffffffff835e88da>] device_register+0x1a/0x20
> [<ffffffffc00463f9>] register_virtio_device+0xb9/0x100 [virtio]
> [<ffffffffc0093673>] virtio_pci_probe+0xc3/0x140 [virtio_pci]
> [<ffffffff834c97b5>] local_pci_probe+0x45/0xa0
> [<ffffffff834ca81a>] ? pci_match_device+0xca/0x110
> [<ffffffff834cac33>] pci_device_probe+0x103/0x150
> [<ffffffff835ebd53>] driver_probe_device+0x223/0x430
> [<ffffffff835ec043>] __driver_attach+0xe3/0xf0
> [<ffffffff835ebf60>] ? driver_probe_device+0x430/0x430
> [<ffffffff835e9653>] bus_for_each_dev+0x73/0xc0
> [<ffffffff835eb47e>] driver_attach+0x1e/0x20
> [<ffffffff835eaea3>] bus_add_driver+0x173/0x270
> [<ffffffffc0099000>] ? 0xffffffffc0099000
> [<ffffffff835ecca0>] driver_register+0x60/0xe0
> [<ffffffffc0099000>] ? 0xffffffffc0099000
> [<ffffffff834c90d0>] __pci_register_driver+0x60/0x70
> [<ffffffffc009901e>] virtio_pci_driver_init+0x1e/0x1000 [virtio_pci]
> [<ffffffff83002190>] do_one_initcall+0x50/0x180
> [<ffffffff83130ac5>] ? rcu_read_lock_sched_held+0x45/0x80
> [<ffffffff83275517>] ? kmem_cache_alloc_trace+0x277/0x2d0
> [<ffffffff831fa457>] ? do_init_module+0x27/0x1f1
> [<ffffffff831fa48f>] do_init_module+0x5f/0x1f1
> [<ffffffff8315df91>] load_module+0x2401/0x2b40
> [<ffffffff8315a7c0>] ? __symbol_put+0x70/0x70
> [<ffffffff830ec480>] ? sched_clock_cpu+0x90/0xc0
> [<ffffffff8323a9f3>] ? __might_fault+0x43/0xa0
> [<ffffffff8315e86b>] SYSC_init_module+0x19b/0x1c0
> [<ffffffff8315e9ae>] SyS_init_module+0xe/0x10
> [<ffffffff83909941>] entry_SYSCALL_64_fastpath+0x1f/0xc2
> Code: ca 75 2c 49 8b 55 08 f6 c2 01 75 25 83 e2 03 81 e3 ff 0f 00 00 45
> 89 65 14 48 09 d0 41 89 5d 10 49 89 45 08 5b 41 5c 41 5d 5d c3 <0f> 0b
> 0f 0b 0f 0b 0f 0b 48 8b 15 05 ec 98 00 eb a3 0f 1f 00 55
> RIP [<ffffffff8347e3fc>] sg_init_one+0x8c/0xa0
> RSP <ffffb820000cf7d0>
> ---[ end trace 8120a17353b469c4 ]---
Prevent this by allocating a temporary buffer in add_early_randomness()
with kmalloc(). (The function add_early_randomness() should be called very
infrequently, therefore it makes sense to trade speed for storage; i.e.,
to allocate the buffer only temporarily, for every call separately.)
Cc: "Richard W.M. Jones" <rjones@redhat.com>
Cc: <stable@vger.kernel.org>
Cc: Amit Shah <amit.shah@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Kees Cook <keescook@chromium.org>
Cc: Matt Mackall <mpm@selenic.com>
Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1383451
Fixes: d9e797261933 ("hwrng: add randomness to system from rng sources")
See-also: 5e59d9a1aed2 ("virtio_console: Stop doing DMA on the stack")
Reported-by: "Richard W.M. Jones" <rjones@redhat.com>
Tested-by: "Richard W.M. Jones" <rjones@redhat.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---
Notes:
- (GFP_NOWAIT | __GFP_NOWARN) could be overly cautious, but I'm better
safe than sorry.
- If / when responding, please keep me addressed personally; I'm not
subscribed to either linux-crypto or linux-kernel. Thanks.
drivers/char/hw_random/core.c | 28 ++++++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 482794526e8c..66831bd5331d 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -50,6 +50,7 @@
#define PFX RNG_MODULE_NAME ": "
#define RNG_MISCDEV_MINOR 183 /* official */
+#define EARLY_RANDOMNESS_SIZE 16
static struct hwrng *current_rng;
static struct task_struct *hwrng_fill;
@@ -84,14 +85,37 @@ static size_t rng_buffer_size(void)
static void add_early_randomness(struct hwrng *rng)
{
- unsigned char bytes[16];
+ unsigned char *bytes;
int bytes_read;
+ /*
+ * This code can be reached with rng_mutex held, through the following
+ * call chain:
+ *
+ * hwrng_attr_current_store()
+ * set_current_rng()
+ * hwrng_init()
+ * add_early_randomness()
+ *
+ * (that is, when a different RNG is selected through the "rng_current"
+ * sysfs attribute). For that reason, allocate memory without enabling
+ * sleep.
+ *
+ * If the (immediate) allocation fails, we just pretend to have read
+ * zero bytes from the RNG, as that is already valid behavior. Also,
+ * feeding initial randomness from the device to the system entropy
+ * pool is not important enough to tap into emergency memory pools.
+ */
+ bytes = kmalloc(EARLY_RANDOMNESS_SIZE, GFP_NOWAIT | __GFP_NOWARN);
+ if (!bytes)
+ return;
+
mutex_lock(&reading_mutex);
- bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1);
+ bytes_read = rng_get_data(rng, bytes, EARLY_RANDOMNESS_SIZE, 1);
mutex_unlock(&reading_mutex);
if (bytes_read > 0)
add_device_randomness(bytes, bytes_read);
+ kfree(bytes);
}
static inline void cleanup_rng(struct kref *kref)
--
2.9.2
^ permalink raw reply related
* Re: [PATCH] hwrng: core - don't pass stack allocated buffer to rng->read()
From: Laszlo Ersek @ 2016-10-21 20:43 UTC (permalink / raw)
To: linux-crypto, linux-kernel
Cc: stable, Amit Shah, Andy Lutomirski, Herbert Xu, Kees Cook,
Matt Mackall, Richard W . M . Jones
In-Reply-To: <20161021203204.12556-1-lersek@redhat.com>
On 10/21/16 22:32, Laszlo Ersek wrote:
> [...]
Self-NAK, I'll resend in a minute. I added a tag like this:
Cc: <stable@vger.kernel.org> # For v3.15+
and git turned it into a garbage email address. I'll drop the "# For
v3.15+" part in the repost.
(I'll also add explicit quotes around Rich's name -- I had a suspicion
that the dots wouldn't be correct without quoting. git-send-email
armored them itself, but it also inserted gratuitous whitespace in front
of the dots.)
Sorry about the inconvenience.
Thanks
Laszlo
^ permalink raw reply
* [PATCH] hwrng: core - don't pass stack allocated buffer to rng->read()
From: Laszlo Ersek @ 2016-10-21 20:32 UTC (permalink / raw)
To: linux-crypto, linux-kernel, Laszlo Ersek
Cc: stable, Amit Shah, Andy Lutomirski, Herbert Xu, Kees Cook,
Matt Mackall, Richard W . M . Jones
The virtio-rng backend for hwrng passes the buffer that it receives for
filling to sg_set_buf() directly, in:
virtio_read() [drivers/char/hw_random/virtio-rng.c]
register_buffer() [drivers/char/hw_random/virtio-rng.c]
sg_init_one() [lib/scatterlist.c]
sg_set_buf() [include/linux/scatterlist.h]
In turn, the sg_set_buf() function, when built with CONFIG_DEBUG_SG,
actively enforces (justifiedly) that the buffer used within the
scatter-gather list live in physically contiguous memory:
BUG_ON(!virt_addr_valid(buf));
The combination of the above two facts means that whatever calls
virtio_read() -- via the hwrng.read() method -- has to allocate the
recipient buffer in physically contiguous memory.
Although this ends up being a generic interface restriction that is not
documented at the abstract hwrng level ("include/linux/hw_random.h",
"Documentation/hw_random.txt"), the virtio-rng provider has not been
changed to implement bounce buffering. Instead, existing core commits have
accommodated the silent restriction, such as:
- f7f154f1246c hw_random: make buffer usable in scatterlist.
which would allocate "rng_buffer" with kmalloc(), and
- be4000bc4644 hwrng: create filler thread
which would allocate the new "rng_fillbuf" similarly.
One call site remains that breaks the silent restriction: the
add_early_randomness() function passes an on-stack array to hwrng.read(),
via rng_get_data(), resulting in the following (valid) BUG, when
CONFIG_DEBUG_SG is enabled:
> ------------[ cut here ]------------
> kernel BUG at ./include/linux/scatterlist.h:140!
> invalid opcode: 0000 [#1] SMP
> Modules linked in: virtio_pci(+) virtio_mmio virtio_input virtio_balloon
> virtio_scsi nd_pmem nd_btt virtio_net virtio_console virtio_rng
> virtio_blk virtio_ring virtio nfit crc32_generic crct10dif_pclmul
> crc32c_intel crc32_pclmul
> CPU: 0 PID: 1 Comm: init Not tainted 4.9.0-0.rc0.git6.2.fc26.x86_64 #1
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.3-1.fc26
> 04/01/2014
> task: ffff91f29de53240 task.stack: ffffb820000cc000
> RIP: 0010:[<ffffffff8347e3fc>] [<ffffffff8347e3fc>]
> sg_init_one+0x8c/0xa0
> RSP: 0018:ffffb820000cf7d0 EFLAGS: 00010246
> RAX: 0000000000000000 RBX: ffffb820000cf858 RCX: 0000000000000028
> RDX: 0000262d800cf858 RSI: 0000000000000026 RDI: ffffb820800cf858
> RBP: ffffb820000cf7e8 R08: 000000000000006a R09: ffffb820000cf7f8
> R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000010
> R13: ffffb820000cf7f8 R14: 0000000000000010 R15: 0000000000000000
> FS: 00007fffd6e6e140(0000) GS:ffff91f29ee00000(0000)
> knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00007fc67e24e000 CR3: 000000001bdad000 CR4: 00000000000406f0
> Stack:
> ffff91f29be3b400 0000000000000001 ffffb820000cf858 ffffb820000cf848
> ffffffffc0056226 0000000087654321 0000000000000002 0000000000000000
> 0000000000000000 0000000000000000 000000002a14e409 ffff91f29be3b400
> Call Trace:
> [<ffffffffc0056226>] virtio_read+0xc6/0x110 [virtio_rng]
> [<ffffffff835be9ee>] add_early_randomness+0x5e/0xd0
> [<ffffffff835beaa5>] set_current_rng+0x45/0x160
> [<ffffffff835bee47>] hwrng_register+0xf7/0x130
> [<ffffffffc0056149>] virtrng_scan+0x19/0x30 [virtio_rng]
> [<ffffffffc00467a8>] virtio_dev_probe+0x198/0x1e0 [virtio]
> [<ffffffff835ebd53>] driver_probe_device+0x223/0x430
> [<ffffffff835ec0dc>] __device_attach_driver+0x8c/0x100
> [<ffffffff835ec050>] ? __driver_attach+0xf0/0xf0
> [<ffffffff835e972a>] bus_for_each_drv+0x6a/0xb0
> [<ffffffff835eb9c2>] __device_attach+0xe2/0x160
> [<ffffffff835ec193>] device_initial_probe+0x13/0x20
> [<ffffffff835eab93>] bus_probe_device+0xa3/0xb0
> [<ffffffff835e85f2>] device_add+0x382/0x650
> [<ffffffffc00929b0>] ? vp_modern_find_vqs+0x70/0x70 [virtio_pci]
> [<ffffffffc00929b0>] ? vp_modern_find_vqs+0x70/0x70 [virtio_pci]
> [<ffffffff835e88da>] device_register+0x1a/0x20
> [<ffffffffc00463f9>] register_virtio_device+0xb9/0x100 [virtio]
> [<ffffffffc0093673>] virtio_pci_probe+0xc3/0x140 [virtio_pci]
> [<ffffffff834c97b5>] local_pci_probe+0x45/0xa0
> [<ffffffff834ca81a>] ? pci_match_device+0xca/0x110
> [<ffffffff834cac33>] pci_device_probe+0x103/0x150
> [<ffffffff835ebd53>] driver_probe_device+0x223/0x430
> [<ffffffff835ec043>] __driver_attach+0xe3/0xf0
> [<ffffffff835ebf60>] ? driver_probe_device+0x430/0x430
> [<ffffffff835e9653>] bus_for_each_dev+0x73/0xc0
> [<ffffffff835eb47e>] driver_attach+0x1e/0x20
> [<ffffffff835eaea3>] bus_add_driver+0x173/0x270
> [<ffffffffc0099000>] ? 0xffffffffc0099000
> [<ffffffff835ecca0>] driver_register+0x60/0xe0
> [<ffffffffc0099000>] ? 0xffffffffc0099000
> [<ffffffff834c90d0>] __pci_register_driver+0x60/0x70
> [<ffffffffc009901e>] virtio_pci_driver_init+0x1e/0x1000 [virtio_pci]
> [<ffffffff83002190>] do_one_initcall+0x50/0x180
> [<ffffffff83130ac5>] ? rcu_read_lock_sched_held+0x45/0x80
> [<ffffffff83275517>] ? kmem_cache_alloc_trace+0x277/0x2d0
> [<ffffffff831fa457>] ? do_init_module+0x27/0x1f1
> [<ffffffff831fa48f>] do_init_module+0x5f/0x1f1
> [<ffffffff8315df91>] load_module+0x2401/0x2b40
> [<ffffffff8315a7c0>] ? __symbol_put+0x70/0x70
> [<ffffffff830ec480>] ? sched_clock_cpu+0x90/0xc0
> [<ffffffff8323a9f3>] ? __might_fault+0x43/0xa0
> [<ffffffff8315e86b>] SYSC_init_module+0x19b/0x1c0
> [<ffffffff8315e9ae>] SyS_init_module+0xe/0x10
> [<ffffffff83909941>] entry_SYSCALL_64_fastpath+0x1f/0xc2
> Code: ca 75 2c 49 8b 55 08 f6 c2 01 75 25 83 e2 03 81 e3 ff 0f 00 00 45
> 89 65 14 48 09 d0 41 89 5d 10 49 89 45 08 5b 41 5c 41 5d 5d c3 <0f> 0b
> 0f 0b 0f 0b 0f 0b 48 8b 15 05 ec 98 00 eb a3 0f 1f 00 55
> RIP [<ffffffff8347e3fc>] sg_init_one+0x8c/0xa0
> RSP <ffffb820000cf7d0>
> ---[ end trace 8120a17353b469c4 ]---
Prevent this by allocating a temporary buffer in add_early_randomness()
with kmalloc(). (The function add_early_randomness() should be called very
infrequently, therefore it makes sense to trade speed for storage; i.e.,
to allocate the buffer only temporarily, for every call separately.)
Cc: <stable@vger.kernel.org> # For v3.15+
Cc: Amit Shah <amit.shah@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Kees Cook <keescook@chromium.org>
Cc: Matt Mackall <mpm@selenic.com>
Cc: Richard W.M. Jones <rjones@redhat.com>
Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1383451
Fixes: d9e797261933 ("hwrng: add randomness to system from rng sources")
See-also: 5e59d9a1aed2 ("virtio_console: Stop doing DMA on the stack")
Reported-by: Richard W.M. Jones <rjones@redhat.com>
Tested-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---
Notes:
- (GFP_NOWAIT | __GFP_NOWARN) could be overly cautious, but I'm better
safe than sorry.
- If / when responding, please keep me addressed personally; I'm not
subscribed to either linux-crypto or linux-kernel. Thanks.
drivers/char/hw_random/core.c | 28 ++++++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 482794526e8c..66831bd5331d 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -50,6 +50,7 @@
#define PFX RNG_MODULE_NAME ": "
#define RNG_MISCDEV_MINOR 183 /* official */
+#define EARLY_RANDOMNESS_SIZE 16
static struct hwrng *current_rng;
static struct task_struct *hwrng_fill;
@@ -84,14 +85,37 @@ static size_t rng_buffer_size(void)
static void add_early_randomness(struct hwrng *rng)
{
- unsigned char bytes[16];
+ unsigned char *bytes;
int bytes_read;
+ /*
+ * This code can be reached with rng_mutex held, through the following
+ * call chain:
+ *
+ * hwrng_attr_current_store()
+ * set_current_rng()
+ * hwrng_init()
+ * add_early_randomness()
+ *
+ * (that is, when a different RNG is selected through the "rng_current"
+ * sysfs attribute). For that reason, allocate memory without enabling
+ * sleep.
+ *
+ * If the (immediate) allocation fails, we just pretend to have read
+ * zero bytes from the RNG, as that is already valid behavior. Also,
+ * feeding initial randomness from the device to the system entropy
+ * pool is not important enough to tap into emergency memory pools.
+ */
+ bytes = kmalloc(EARLY_RANDOMNESS_SIZE, GFP_NOWAIT | __GFP_NOWARN);
+ if (!bytes)
+ return;
+
mutex_lock(&reading_mutex);
- bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1);
+ bytes_read = rng_get_data(rng, bytes, EARLY_RANDOMNESS_SIZE, 1);
mutex_unlock(&reading_mutex);
if (bytes_read > 0)
add_device_randomness(bytes, bytes_read);
+ kfree(bytes);
}
static inline void cleanup_rng(struct kref *kref)
--
2.9.2
^ permalink raw reply related
* Re: [PATCH] hwrng: meson: Remove unneeded platform MODULE_ALIAS
From: Neil Armstrong @ 2016-10-21 14:11 UTC (permalink / raw)
To: Javier Martinez Canillas, linux-kernel
Cc: Kevin Hilman, PrasannaKumar Muralidharan, Carlo Caione,
linux-amlogic, Herbert Xu, Matt Mackall, linux-arm-kernel,
linux-crypto
In-Reply-To: <1476906618-14455-1-git-send-email-javier@osg.samsung.com>
On 10/19/2016 09:50 PM, Javier Martinez Canillas wrote:
> The Amlogic Meson is a DT-only platform, which means the devices are
> registered via OF and not using the legacy platform devices support.
>
> So there's no need to have a MODULE_ALIAS("platform:meson-rng") since
> the reported uevent MODALIAS to user-space will always be the OF one.
>
> Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
> ---
>
> drivers/char/hw_random/meson-rng.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/drivers/char/hw_random/meson-rng.c b/drivers/char/hw_random/meson-rng.c
> index 51864a509be7..119d698439ae 100644
> --- a/drivers/char/hw_random/meson-rng.c
> +++ b/drivers/char/hw_random/meson-rng.c
> @@ -122,7 +122,6 @@ static struct platform_driver meson_rng_driver = {
>
> module_platform_driver(meson_rng_driver);
>
> -MODULE_ALIAS("platform:meson-rng");
> MODULE_DESCRIPTION("Meson H/W Random Number Generator driver");
> MODULE_AUTHOR("Lawrence Mok <lawrence.mok@amlogic.com>");
> MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
>
Acked-by: Neil Armstrong <narmstrong@baylibre.com>
^ permalink raw reply
* Re: sg_set_buf
From: Christoph Hellwig @ 2016-10-21 12:26 UTC (permalink / raw)
To: J. Bruce Fields
Cc: Christoph Hellwig, Rusty Russell,
linux-nfs-u79uwXL29TY76Z2rM5mHXA,
linux-crypto-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20161020214219.GC4347-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org>
On Thu, Oct 20, 2016 at 05:42:19PM -0400, J. Bruce Fields wrote:
> Turns out there are several places in the kerberos code where it just
> needs to encrypt one small checksum or sequence number, and it's been
> doing that on the stack.
>
> For now I'll just sprinkle kmalloc()'s all over. Eventually we'll need
> to find something better.
I agree that it would be nice to be able to hash small objects on the
stack. But unless I've missed something there is no way to do that
without using struct scatterlist. I've added linux-crypto to the cc
list to confirm that I really didn't miss anything.
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v10 8/8] crypto: acomp - update testmgr with support for acomp
From: Giovanni Cabiddu @ 2016-10-21 12:19 UTC (permalink / raw)
To: herbert; +Cc: linux-crypto, Giovanni Cabiddu
In-Reply-To: <1477052394-19826-1-git-send-email-giovanni.cabiddu@intel.com>
Add tests to the test manager for algorithms exposed through acomp.
Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
---
crypto/testmgr.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 145 insertions(+), 13 deletions(-)
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 62dffa0..ded50b6 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -33,6 +33,7 @@
#include <crypto/drbg.h>
#include <crypto/akcipher.h>
#include <crypto/kpp.h>
+#include <crypto/acompress.h>
#include "internal.h"
@@ -1442,6 +1443,121 @@ static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
return ret;
}
+static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
+ struct comp_testvec *dtemplate, int ctcount, int dtcount)
+{
+ const char *algo = crypto_tfm_alg_driver_name(crypto_acomp_tfm(tfm));
+ unsigned int i;
+ char output[COMP_BUF_SIZE];
+ int ret;
+ struct scatterlist src, dst;
+ struct acomp_req *req;
+ struct tcrypt_result result;
+
+ for (i = 0; i < ctcount; i++) {
+ unsigned int dlen = COMP_BUF_SIZE;
+ int ilen = ctemplate[i].inlen;
+
+ memset(output, 0, sizeof(output));
+ init_completion(&result.completion);
+ sg_init_one(&src, ctemplate[i].input, ilen);
+ sg_init_one(&dst, output, dlen);
+
+ req = acomp_request_alloc(tfm);
+ if (!req) {
+ pr_err("alg: acomp: request alloc failed for %s\n",
+ algo);
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ acomp_request_set_params(req, &src, &dst, ilen, dlen);
+ acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ tcrypt_complete, &result);
+
+ ret = wait_async_op(&result, crypto_acomp_compress(req));
+ if (ret) {
+ pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n",
+ i + 1, algo, -ret);
+ acomp_request_free(req);
+ goto out;
+ }
+
+ if (req->dlen != ctemplate[i].outlen) {
+ pr_err("alg: acomp: Compression test %d failed for %s: output len = %d\n",
+ i + 1, algo, req->dlen);
+ ret = -EINVAL;
+ acomp_request_free(req);
+ goto out;
+ }
+
+ if (memcmp(output, ctemplate[i].output, req->dlen)) {
+ pr_err("alg: acomp: Compression test %d failed for %s\n",
+ i + 1, algo);
+ hexdump(output, req->dlen);
+ ret = -EINVAL;
+ acomp_request_free(req);
+ goto out;
+ }
+
+ acomp_request_free(req);
+ }
+
+ for (i = 0; i < dtcount; i++) {
+ unsigned int dlen = COMP_BUF_SIZE;
+ int ilen = dtemplate[i].inlen;
+
+ memset(output, 0, sizeof(output));
+ init_completion(&result.completion);
+ sg_init_one(&src, dtemplate[i].input, ilen);
+ sg_init_one(&dst, output, dlen);
+
+ req = acomp_request_alloc(tfm);
+ if (!req) {
+ pr_err("alg: acomp: request alloc failed for %s\n",
+ algo);
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ acomp_request_set_params(req, &src, &dst, ilen, dlen);
+ acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ tcrypt_complete, &result);
+
+ ret = wait_async_op(&result, crypto_acomp_decompress(req));
+ if (ret) {
+ pr_err("alg: acomp: decompression failed on test %d for %s: ret=%d\n",
+ i + 1, algo, -ret);
+ acomp_request_free(req);
+ goto out;
+ }
+
+ if (req->dlen != dtemplate[i].outlen) {
+ pr_err("alg: acomp: Decompression test %d failed for %s: output len = %d\n",
+ i + 1, algo, req->dlen);
+ ret = -EINVAL;
+ acomp_request_free(req);
+ goto out;
+ }
+
+ if (memcmp(output, dtemplate[i].output, req->dlen)) {
+ pr_err("alg: acomp: Decompression test %d failed for %s\n",
+ i + 1, algo);
+ hexdump(output, req->dlen);
+ ret = -EINVAL;
+ acomp_request_free(req);
+ goto out;
+ }
+
+ acomp_request_free(req);
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
static int test_cprng(struct crypto_rng *tfm, struct cprng_testvec *template,
unsigned int tcount)
{
@@ -1593,22 +1709,38 @@ static int alg_test_skcipher(const struct alg_test_desc *desc,
static int alg_test_comp(const struct alg_test_desc *desc, const char *driver,
u32 type, u32 mask)
{
- struct crypto_comp *tfm;
+ struct crypto_comp *comp;
+ struct crypto_acomp *acomp;
int err;
+ u32 algo_type = type & CRYPTO_ALG_TYPE_ACOMPRESS_MASK;
+
+ if (algo_type == CRYPTO_ALG_TYPE_ACOMPRESS) {
+ acomp = crypto_alloc_acomp(driver, type, mask);
+ if (IS_ERR(acomp)) {
+ pr_err("alg: acomp: Failed to load transform for %s: %ld\n",
+ driver, PTR_ERR(acomp));
+ return PTR_ERR(acomp);
+ }
+ err = test_acomp(acomp, desc->suite.comp.comp.vecs,
+ desc->suite.comp.decomp.vecs,
+ desc->suite.comp.comp.count,
+ desc->suite.comp.decomp.count);
+ crypto_free_acomp(acomp);
+ } else {
+ comp = crypto_alloc_comp(driver, type, mask);
+ if (IS_ERR(comp)) {
+ pr_err("alg: comp: Failed to load transform for %s: %ld\n",
+ driver, PTR_ERR(comp));
+ return PTR_ERR(comp);
+ }
- tfm = crypto_alloc_comp(driver, type, mask);
- if (IS_ERR(tfm)) {
- printk(KERN_ERR "alg: comp: Failed to load transform for %s: "
- "%ld\n", driver, PTR_ERR(tfm));
- return PTR_ERR(tfm);
- }
-
- err = test_comp(tfm, desc->suite.comp.comp.vecs,
- desc->suite.comp.decomp.vecs,
- desc->suite.comp.comp.count,
- desc->suite.comp.decomp.count);
+ err = test_comp(comp, desc->suite.comp.comp.vecs,
+ desc->suite.comp.decomp.vecs,
+ desc->suite.comp.comp.count,
+ desc->suite.comp.decomp.count);
- crypto_free_comp(tfm);
+ crypto_free_comp(comp);
+ }
return err;
}
--
2.4.11
^ permalink raw reply related
* [PATCH v10 7/8] crypto: acomp - add support for deflate via scomp
From: Giovanni Cabiddu @ 2016-10-21 12:19 UTC (permalink / raw)
To: herbert; +Cc: linux-crypto, Giovanni Cabiddu
In-Reply-To: <1477052394-19826-1-git-send-email-giovanni.cabiddu@intel.com>
Add scomp backend for deflate compression algorithm.
Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
---
crypto/Kconfig | 1 +
crypto/deflate.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 102 insertions(+), 10 deletions(-)
diff --git a/crypto/Kconfig b/crypto/Kconfig
index b0718ce..1db2a19 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -1578,6 +1578,7 @@ comment "Compression"
config CRYPTO_DEFLATE
tristate "Deflate compression algorithm"
select CRYPTO_ALGAPI
+ select CRYPTO_ACOMP2
select ZLIB_INFLATE
select ZLIB_DEFLATE
help
diff --git a/crypto/deflate.c b/crypto/deflate.c
index 95d8d37..f942cb3 100644
--- a/crypto/deflate.c
+++ b/crypto/deflate.c
@@ -32,6 +32,7 @@
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/net.h>
+#include <crypto/internal/scompress.h>
#define DEFLATE_DEF_LEVEL Z_DEFAULT_COMPRESSION
#define DEFLATE_DEF_WINBITS 11
@@ -101,9 +102,8 @@ static void deflate_decomp_exit(struct deflate_ctx *ctx)
vfree(ctx->decomp_stream.workspace);
}
-static int deflate_init(struct crypto_tfm *tfm)
+static int __deflate_init(void *ctx)
{
- struct deflate_ctx *ctx = crypto_tfm_ctx(tfm);
int ret;
ret = deflate_comp_init(ctx);
@@ -116,19 +116,55 @@ static int deflate_init(struct crypto_tfm *tfm)
return ret;
}
-static void deflate_exit(struct crypto_tfm *tfm)
+static void *deflate_alloc_ctx(struct crypto_scomp *tfm)
+{
+ struct deflate_ctx *ctx;
+ int ret;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return ERR_PTR(-ENOMEM);
+
+ ret = __deflate_init(ctx);
+ if (ret) {
+ kfree(ctx);
+ return ERR_PTR(ret);
+ }
+
+ return ctx;
+}
+
+static int deflate_init(struct crypto_tfm *tfm)
{
struct deflate_ctx *ctx = crypto_tfm_ctx(tfm);
+ return __deflate_init(ctx);
+}
+
+static void __deflate_exit(void *ctx)
+{
deflate_comp_exit(ctx);
deflate_decomp_exit(ctx);
}
-static int deflate_compress(struct crypto_tfm *tfm, const u8 *src,
- unsigned int slen, u8 *dst, unsigned int *dlen)
+static void deflate_free_ctx(struct crypto_scomp *tfm, void *ctx)
+{
+ __deflate_exit(ctx);
+ kzfree(ctx);
+}
+
+static void deflate_exit(struct crypto_tfm *tfm)
+{
+ struct deflate_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ __deflate_exit(ctx);
+}
+
+static int __deflate_compress(const u8 *src, unsigned int slen,
+ u8 *dst, unsigned int *dlen, void *ctx)
{
int ret = 0;
- struct deflate_ctx *dctx = crypto_tfm_ctx(tfm);
+ struct deflate_ctx *dctx = ctx;
struct z_stream_s *stream = &dctx->comp_stream;
ret = zlib_deflateReset(stream);
@@ -153,12 +189,27 @@ static int deflate_compress(struct crypto_tfm *tfm, const u8 *src,
return ret;
}
-static int deflate_decompress(struct crypto_tfm *tfm, const u8 *src,
- unsigned int slen, u8 *dst, unsigned int *dlen)
+static int deflate_compress(struct crypto_tfm *tfm, const u8 *src,
+ unsigned int slen, u8 *dst, unsigned int *dlen)
+{
+ struct deflate_ctx *dctx = crypto_tfm_ctx(tfm);
+
+ return __deflate_compress(src, slen, dst, dlen, dctx);
+}
+
+static int deflate_scompress(struct crypto_scomp *tfm, const u8 *src,
+ unsigned int slen, u8 *dst, unsigned int *dlen,
+ void *ctx)
+{
+ return __deflate_compress(src, slen, dst, dlen, ctx);
+}
+
+static int __deflate_decompress(const u8 *src, unsigned int slen,
+ u8 *dst, unsigned int *dlen, void *ctx)
{
int ret = 0;
- struct deflate_ctx *dctx = crypto_tfm_ctx(tfm);
+ struct deflate_ctx *dctx = ctx;
struct z_stream_s *stream = &dctx->decomp_stream;
ret = zlib_inflateReset(stream);
@@ -194,6 +245,21 @@ static int deflate_decompress(struct crypto_tfm *tfm, const u8 *src,
return ret;
}
+static int deflate_decompress(struct crypto_tfm *tfm, const u8 *src,
+ unsigned int slen, u8 *dst, unsigned int *dlen)
+{
+ struct deflate_ctx *dctx = crypto_tfm_ctx(tfm);
+
+ return __deflate_decompress(src, slen, dst, dlen, dctx);
+}
+
+static int deflate_sdecompress(struct crypto_scomp *tfm, const u8 *src,
+ unsigned int slen, u8 *dst, unsigned int *dlen,
+ void *ctx)
+{
+ return __deflate_decompress(src, slen, dst, dlen, ctx);
+}
+
static struct crypto_alg alg = {
.cra_name = "deflate",
.cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
@@ -206,14 +272,39 @@ static struct crypto_alg alg = {
.coa_decompress = deflate_decompress } }
};
+static struct scomp_alg scomp = {
+ .alloc_ctx = deflate_alloc_ctx,
+ .free_ctx = deflate_free_ctx,
+ .compress = deflate_scompress,
+ .decompress = deflate_sdecompress,
+ .base = {
+ .cra_name = "deflate",
+ .cra_driver_name = "deflate-scomp",
+ .cra_module = THIS_MODULE,
+ }
+};
+
static int __init deflate_mod_init(void)
{
- return crypto_register_alg(&alg);
+ int ret;
+
+ ret = crypto_register_alg(&alg);
+ if (ret)
+ return ret;
+
+ ret = crypto_register_scomp(&scomp);
+ if (ret) {
+ crypto_unregister_alg(&alg);
+ return ret;
+ }
+
+ return ret;
}
static void __exit deflate_mod_fini(void)
{
crypto_unregister_alg(&alg);
+ crypto_unregister_scomp(&scomp);
}
module_init(deflate_mod_init);
--
2.4.11
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox