From e3f9490e89c2240f87c6d040575cdc11dd405afc Mon Sep 17 00:00:00 2001 From: Antoine Ténart Date: Thu, 1 Jun 2017 21:38:53 +0200 Subject: crypto: sun4i-ss - group variable definitions in sun4i_hash() Cosmetic change to avoid having a full screen a variable definitions. It also helps to see which variables share the same type. Signed-off-by: Antoine Tenart Tested-by: Corentin Labbe Acked-by: Corentin Labbe Signed-off-by: Herbert Xu --- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) (limited to 'drivers/crypto/sunxi-ss/sun4i-ss-hash.c') diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c index 0de2f62d51ff..855325338844 100644 --- a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c +++ b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c @@ -167,37 +167,28 @@ int sun4i_hash_import_sha1(struct ahash_request *areq, const void *in) */ static int sun4i_hash(struct ahash_request *areq) { - u32 v, ivmode = 0; - unsigned int i = 0; /* * i is the total bytes read from SGs, to be compared to areq->nbytes * i is important because we cannot rely on SG length since the sum of * SG->length could be greater than areq->nbytes + * + * end is the position when we need to stop writing to the device, + * to be compared to i + * + * in_i: advancement in the current SG */ - + unsigned int i = 0, end, index, padlen, nwait, nbw = 0, j = 0, todo; + unsigned int in_i = 0; + u32 spaces, rx_cnt = SS_RX_DEFAULT, bf[32], wb = 0, v, ivmode = 0; struct sun4i_req_ctx *op = ahash_request_ctx(areq); struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); struct sun4i_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); struct sun4i_ss_ctx *ss = tfmctx->ss; - unsigned int in_i = 0; /* advancement in the current SG */ - unsigned int end; - /* - * end is the position when we need to stop writing to the device, - * to be compared to i - */ - int in_r, err = 0; - unsigned int todo; - u32 spaces, rx_cnt = SS_RX_DEFAULT; - size_t copied = 0; + struct scatterlist *in_sg = areq->src; struct sg_mapping_iter mi; - unsigned int j = 0; - int zeros; - unsigned int index, padlen; + int in_r, err = 0, zeros; + size_t copied = 0; __be64 bits; - u32 bf[32]; - u32 wb = 0; - unsigned int nwait, nbw = 0; - struct scatterlist *in_sg = areq->src; dev_dbg(ss->dev, "%s %s bc=%llu len=%u mode=%x wl=%u h0=%0x", __func__, crypto_tfm_alg_name(areq->base.tfm), -- cgit v1.2.3-59-g8ed1b From a595e60a70c0d035b5a088f90ae3fde475c7e755 Mon Sep 17 00:00:00 2001 From: Antoine Ténart Date: Thu, 1 Jun 2017 21:38:54 +0200 Subject: crypto: sun4i-ss - remove conditional checks against 0 Cosmetic clean up if conditional checks on 0s values. Signed-off-by: Antoine Tenart Tested-by: Corentin Labbe Acked-by: Corentin Labbe Signed-off-by: Herbert Xu --- drivers/crypto/sunxi-ss/sun4i-ss-cipher.c | 28 +++++++++++----------- drivers/crypto/sunxi-ss/sun4i-ss-core.c | 10 ++++---- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 40 +++++++++++++++---------------- 3 files changed, 39 insertions(+), 39 deletions(-) (limited to 'drivers/crypto/sunxi-ss/sun4i-ss-hash.c') diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c b/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c index 90efd10d57a1..23e549204365 100644 --- a/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c +++ b/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c @@ -38,7 +38,7 @@ static int sun4i_ss_opti_poll(struct ablkcipher_request *areq) unsigned int oi, oo; /* offset for in and out */ unsigned long flags; - if (areq->nbytes == 0) + if (!areq->nbytes) return 0; if (!areq->info) { @@ -82,7 +82,7 @@ static int sun4i_ss_opti_poll(struct ablkcipher_request *areq) oo = 0; do { todo = min3(rx_cnt, ileft, (mi.length - oi) / 4); - if (todo > 0) { + if (todo) { ileft -= todo; writesl(ss->base + SS_RXFIFO, mi.addr + oi, todo); oi += todo * 4; @@ -97,7 +97,7 @@ static int sun4i_ss_opti_poll(struct ablkcipher_request *areq) tx_cnt = SS_TXFIFO_SPACES(spaces); todo = min3(tx_cnt, oleft, (mo.length - oo) / 4); - if (todo > 0) { + if (todo) { oleft -= todo; readsl(ss->base + SS_TXFIFO, mo.addr + oo, todo); oo += todo * 4; @@ -106,7 +106,7 @@ static int sun4i_ss_opti_poll(struct ablkcipher_request *areq) sg_miter_next(&mo); oo = 0; } - } while (oleft > 0); + } while (oleft); if (areq->info) { for (i = 0; i < 4 && i < ivsize / 4; i++) { @@ -154,7 +154,7 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq) unsigned int obl = 0; /* length of data in bufo */ unsigned long flags; - if (areq->nbytes == 0) + if (!areq->nbytes) return 0; if (!areq->info) { @@ -172,12 +172,12 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq) * we can use the SS optimized function */ while (in_sg && no_chunk == 1) { - if ((in_sg->length % 4) != 0) + if (in_sg->length % 4) no_chunk = 0; in_sg = sg_next(in_sg); } while (out_sg && no_chunk == 1) { - if ((out_sg->length % 4) != 0) + if (out_sg->length % 4) no_chunk = 0; out_sg = sg_next(out_sg); } @@ -214,14 +214,14 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq) oi = 0; oo = 0; - while (oleft > 0) { - if (ileft > 0) { + while (oleft) { + if (ileft) { /* * todo is the number of consecutive 4byte word that we * can read from current SG */ todo = min3(rx_cnt, ileft / 4, (mi.length - oi) / 4); - if (todo > 0 && ob == 0) { + if (todo && !ob) { writesl(ss->base + SS_RXFIFO, mi.addr + oi, todo); ileft -= todo * 4; @@ -240,7 +240,7 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq) ileft -= todo; oi += todo; ob += todo; - if (ob % 4 == 0) { + if (!(ob % 4)) { writesl(ss->base + SS_RXFIFO, buf, ob / 4); ob = 0; @@ -260,11 +260,11 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq) oi, mi.length, ileft, areq->nbytes, rx_cnt, oo, mo.length, oleft, areq->nbytes, tx_cnt, ob); - if (tx_cnt == 0) + if (!tx_cnt) continue; /* todo in 4bytes word */ todo = min3(tx_cnt, oleft / 4, (mo.length - oo) / 4); - if (todo > 0) { + if (todo) { readsl(ss->base + SS_TXFIFO, mo.addr + oo, todo); oleft -= todo * 4; oo += todo * 4; @@ -516,7 +516,7 @@ int sun4i_ss_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, flags = crypto_ablkcipher_get_flags(tfm); ret = des_ekey(tmp, key); - if (unlikely(ret == 0) && (flags & CRYPTO_TFM_REQ_WEAK_KEY)) { + if (unlikely(!ret) && (flags & CRYPTO_TFM_REQ_WEAK_KEY)) { crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_WEAK_KEY); dev_dbg(ss->dev, "Weak key %u\n", keylen); return -EINVAL; diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-core.c b/drivers/crypto/sunxi-ss/sun4i-ss-core.c index 3ac6c6c4ad18..50af81c3eb45 100644 --- a/drivers/crypto/sunxi-ss/sun4i-ss-core.c +++ b/drivers/crypto/sunxi-ss/sun4i-ss-core.c @@ -266,12 +266,12 @@ static int sun4i_ss_probe(struct platform_device *pdev) /* Enable both clocks */ err = clk_prepare_enable(ss->busclk); - if (err != 0) { + if (err) { dev_err(&pdev->dev, "Cannot prepare_enable busclk\n"); return err; } err = clk_prepare_enable(ss->ssclk); - if (err != 0) { + if (err) { dev_err(&pdev->dev, "Cannot prepare_enable ssclk\n"); goto error_ssclk; } @@ -281,7 +281,7 @@ static int sun4i_ss_probe(struct platform_device *pdev) * Try to set the clock to the maximum allowed */ err = clk_set_rate(ss->ssclk, cr_mod); - if (err != 0) { + if (err) { dev_err(&pdev->dev, "Cannot set clock rate to ssclk\n"); goto error_clk; } @@ -342,7 +342,7 @@ static int sun4i_ss_probe(struct platform_device *pdev) switch (ss_algs[i].type) { case CRYPTO_ALG_TYPE_ABLKCIPHER: err = crypto_register_alg(&ss_algs[i].alg.crypto); - if (err != 0) { + if (err) { dev_err(ss->dev, "Fail to register %s\n", ss_algs[i].alg.crypto.cra_name); goto error_alg; @@ -350,7 +350,7 @@ static int sun4i_ss_probe(struct platform_device *pdev) break; case CRYPTO_ALG_TYPE_AHASH: err = crypto_register_ahash(&ss_algs[i].alg.hash); - if (err != 0) { + if (err) { dev_err(ss->dev, "Fail to register %s\n", ss_algs[i].alg.hash.halg.base.cra_name); goto error_alg; diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c index 855325338844..39f0abe5ee25 100644 --- a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c +++ b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c @@ -60,7 +60,7 @@ int sun4i_hash_export_md5(struct ahash_request *areq, void *out) memcpy(octx->block, op->buf, op->len); - if (op->byte_count > 0) { + if (op->byte_count) { for (i = 0; i < 4; i++) octx->hash[i] = op->hash[i]; } else { @@ -102,7 +102,7 @@ int sun4i_hash_export_sha1(struct ahash_request *areq, void *out) memcpy(octx->buffer, op->buf, op->len); - if (op->byte_count > 0) { + if (op->byte_count) { for (i = 0; i < 5; i++) octx->state[i] = op->hash[i]; } else { @@ -195,7 +195,7 @@ static int sun4i_hash(struct ahash_request *areq) op->byte_count, areq->nbytes, op->mode, op->len, op->hash[0]); - if (unlikely(areq->nbytes == 0) && (op->flags & SS_HASH_FINAL) == 0) + if (unlikely(!areq->nbytes) && !(op->flags & SS_HASH_FINAL)) return 0; /* protect against overflow */ @@ -204,7 +204,7 @@ static int sun4i_hash(struct ahash_request *areq) return -EINVAL; } - if (op->len + areq->nbytes < 64 && (op->flags & SS_HASH_FINAL) == 0) { + if (op->len + areq->nbytes < 64 && !(op->flags & SS_HASH_FINAL)) { /* linearize data to op->buf */ copied = sg_pcopy_to_buffer(areq->src, sg_nents(areq->src), op->buf + op->len, areq->nbytes, 0); @@ -218,7 +218,7 @@ static int sun4i_hash(struct ahash_request *areq) * if some data have been processed before, * we need to restore the partial hash state */ - if (op->byte_count > 0) { + if (op->byte_count) { ivmode = SS_IV_ARBITRARY; for (i = 0; i < 5; i++) writel(op->hash[i], ss->base + SS_IV0 + i * 4); @@ -226,11 +226,11 @@ static int sun4i_hash(struct ahash_request *areq) /* Enable the device */ writel(op->mode | SS_ENABLED | ivmode, ss->base + SS_CTL); - if ((op->flags & SS_HASH_UPDATE) == 0) + if (!(op->flags & SS_HASH_UPDATE)) goto hash_final; /* start of handling data */ - if ((op->flags & SS_HASH_FINAL) == 0) { + if (!(op->flags & SS_HASH_FINAL)) { end = ((areq->nbytes + op->len) / 64) * 64 - op->len; if (end > areq->nbytes || areq->nbytes - end > 63) { @@ -244,14 +244,14 @@ static int sun4i_hash(struct ahash_request *areq) end = ((areq->nbytes + op->len) / 4) * 4 - op->len; } - /* TODO if SGlen % 4 and op->len == 0 then DMA */ + /* TODO if SGlen % 4 and !op->len then DMA */ i = 1; while (in_sg && i == 1) { - if ((in_sg->length % 4) != 0) + if (in_sg->length % 4) i = 0; in_sg = sg_next(in_sg); } - if (i == 1 && op->len == 0) + if (i == 1 && !op->len) dev_dbg(ss->dev, "We can DMA\n"); i = 0; @@ -266,7 +266,7 @@ static int sun4i_hash(struct ahash_request *areq) * - the buffer is already used * - the SG does not have enough byte remaining ( < 4) */ - if (op->len > 0 || (mi.length - in_i) < 4) { + if (op->len || (mi.length - in_i) < 4) { /* * if we have entered here we have two reason to stop * - the buffer is full @@ -285,7 +285,7 @@ static int sun4i_hash(struct ahash_request *areq) in_i = 0; } } - if (op->len > 3 && (op->len % 4) == 0) { + if (op->len > 3 && !(op->len % 4)) { /* write buf to the device */ writesl(ss->base + SS_RXFIFO, op->buf, op->len / 4); @@ -304,7 +304,7 @@ static int sun4i_hash(struct ahash_request *areq) i += todo * 4; in_i += todo * 4; rx_cnt -= todo; - if (rx_cnt == 0) { + if (!rx_cnt) { spaces = readl(ss->base + SS_FCSR); rx_cnt = SS_RXFIFO_SPACES(spaces); } @@ -342,7 +342,7 @@ static int sun4i_hash(struct ahash_request *areq) * Now if we have the flag final go to finalize part * If not, store the partial hash */ - if ((op->flags & SS_HASH_FINAL) > 0) + if (op->flags & SS_HASH_FINAL) goto hash_final; writel(op->mode | SS_ENABLED | SS_DATA_END, ss->base + SS_CTL); @@ -350,7 +350,7 @@ static int sun4i_hash(struct ahash_request *areq) do { v = readl(ss->base + SS_CTL); i++; - } while (i < SS_TIMEOUT && (v & SS_DATA_END) > 0); + } while (i < SS_TIMEOUT && (v & SS_DATA_END)); if (unlikely(i >= SS_TIMEOUT)) { dev_err_ratelimited(ss->dev, "ERROR: hash end timeout %d>%d ctl=%x len=%u\n", @@ -379,9 +379,9 @@ static int sun4i_hash(struct ahash_request *areq) hash_final: /* write the remaining words of the wait buffer */ - if (op->len > 0) { + if (op->len) { nwait = op->len / 4; - if (nwait > 0) { + if (nwait) { writesl(ss->base + SS_RXFIFO, op->buf, nwait); op->byte_count += 4 * nwait; } @@ -391,7 +391,7 @@ hash_final: } /* write the remaining bytes of the nbw buffer */ - if (nbw > 0) { + if (nbw) { wb |= ((1 << 7) << (nbw * 8)); bf[j++] = wb; } else { @@ -444,7 +444,7 @@ hash_final: do { v = readl(ss->base + SS_CTL); i++; - } while (i < SS_TIMEOUT && (v & SS_DATA_END) > 0); + } while (i < SS_TIMEOUT && (v & SS_DATA_END)); if (unlikely(i >= SS_TIMEOUT)) { dev_err_ratelimited(ss->dev, "ERROR: hash end timeout %d>%d ctl=%x len=%u\n", @@ -504,7 +504,7 @@ int sun4i_hash_digest(struct ahash_request *areq) struct sun4i_req_ctx *op = ahash_request_ctx(areq); err = sun4i_hash_init(areq); - if (err != 0) + if (err) return err; op->flags = SS_HASH_UPDATE | SS_HASH_FINAL; -- cgit v1.2.3-59-g8ed1b From 11be0107ab1a893121ff31325e1bf82d843ea4dc Mon Sep 17 00:00:00 2001 From: Antoine Ténart Date: Thu, 1 Jun 2017 21:38:55 +0200 Subject: crypto: sun4i-ss - use lower/upper_32_bits helpers Replace custom bit shifts and masks with lower/upper_32_bits helpers. Signed-off-by: Antoine Tenart Tested-by: Corentin Labbe Acked-by: Corentin Labbe Signed-off-by: Herbert Xu --- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/crypto/sunxi-ss/sun4i-ss-hash.c') diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c index 39f0abe5ee25..e53c3127b743 100644 --- a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c +++ b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c @@ -188,7 +188,6 @@ static int sun4i_hash(struct ahash_request *areq) struct sg_mapping_iter mi; int in_r, err = 0, zeros; size_t copied = 0; - __be64 bits; dev_dbg(ss->dev, "%s %s bc=%llu len=%u mode=%x wl=%u h0=%0x", __func__, crypto_tfm_alg_name(areq->base.tfm), @@ -423,12 +422,13 @@ hash_final: /* write the length of data */ if (op->mode == SS_OP_SHA1) { - bits = cpu_to_be64(op->byte_count << 3); - bf[j++] = bits & 0xffffffff; - bf[j++] = (bits >> 32) & 0xffffffff; + __be64 bits = cpu_to_be64(op->byte_count << 3); + bf[j++] = lower_32_bits(bits); + bf[j++] = upper_32_bits(bits); } else { - bf[j++] = (op->byte_count << 3) & 0xffffffff; - bf[j++] = (op->byte_count >> 29) & 0xffffffff; + __le64 bits = op->byte_count << 3; + bf[j++] = lower_32_bits(bits); + bf[j++] = upper_32_bits(bits); } writesl(ss->base + SS_RXFIFO, bf, j); -- cgit v1.2.3-59-g8ed1b From 0f52ddaed6500d0b74fcaf5568726068d385129f Mon Sep 17 00:00:00 2001 From: Antoine Ténart Date: Thu, 1 Jun 2017 21:38:56 +0200 Subject: crypto: sun4i-ss - cannot use DMA is the request is 0 length Do not use DMA is the request is 0 length. Signed-off-by: Antoine Tenart Tested-by: Corentin Labbe Acked-by: Corentin Labbe Signed-off-by: Herbert Xu --- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/crypto/sunxi-ss/sun4i-ss-hash.c') diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c index e53c3127b743..bc3cbde07219 100644 --- a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c +++ b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c @@ -250,7 +250,7 @@ static int sun4i_hash(struct ahash_request *areq) i = 0; in_sg = sg_next(in_sg); } - if (i == 1 && !op->len) + if (i == 1 && !op->len && areq->nbytes) dev_dbg(ss->dev, "We can DMA\n"); i = 0; -- cgit v1.2.3-59-g8ed1b From 7e6df1f7a3a5f379b04eee177be0571beb32b811 Mon Sep 17 00:00:00 2001 From: Antoine Ténart Date: Thu, 1 Jun 2017 21:38:57 +0200 Subject: crypto: sun4i-ss - do not dynamically set parts of the last buffer to 0 Parts of the bf buffer were dynamically set to 0. Change this to set the whole buffer to 0 by default to avoid any mistake. Signed-off-by: Antoine Tenart Tested-by: Corentin Labbe Acked-by: Corentin Labbe Signed-off-by: Herbert Xu --- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/crypto/sunxi-ss/sun4i-ss-hash.c') diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c index bc3cbde07219..518bc7a7df6a 100644 --- a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c +++ b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c @@ -179,7 +179,7 @@ static int sun4i_hash(struct ahash_request *areq) */ unsigned int i = 0, end, index, padlen, nwait, nbw = 0, j = 0, todo; unsigned int in_i = 0; - u32 spaces, rx_cnt = SS_RX_DEFAULT, bf[32], wb = 0, v, ivmode = 0; + u32 spaces, rx_cnt = SS_RX_DEFAULT, bf[32] = {0}, wb = 0, v, ivmode = 0; struct sun4i_req_ctx *op = ahash_request_ctx(areq); struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); struct sun4i_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); @@ -417,7 +417,6 @@ hash_final: zeros = (padlen - 1) / 4; } - memset(bf + j, 0, 4 * zeros); j += zeros; /* write the length of data */ -- cgit v1.2.3-59-g8ed1b From 214a9bd0f8dec468de6a32f445c540f786773ee8 Mon Sep 17 00:00:00 2001 From: Antoine Ténart Date: Thu, 1 Jun 2017 21:38:58 +0200 Subject: crypto: sun4i-ss - simplify the pad length calculation When sending the last block of data to the engine, it should be padded so that the total length of the request can be given to the engine as the last 2 words of the last 64 bytes block. Simplify the calculation of this pad offset. Signed-off-by: Antoine Tenart Tested-by: Corentin Labbe Acked-by: Corentin Labbe Signed-off-by: Herbert Xu --- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) (limited to 'drivers/crypto/sunxi-ss/sun4i-ss-hash.c') diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c index 518bc7a7df6a..59d9b4412aca 100644 --- a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c +++ b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c @@ -177,7 +177,7 @@ static int sun4i_hash(struct ahash_request *areq) * * in_i: advancement in the current SG */ - unsigned int i = 0, end, index, padlen, nwait, nbw = 0, j = 0, todo; + unsigned int i = 0, end, fill, min_fill, nwait, nbw = 0, j = 0, todo; unsigned int in_i = 0; u32 spaces, rx_cnt = SS_RX_DEFAULT, bf[32] = {0}, wb = 0, v, ivmode = 0; struct sun4i_req_ctx *op = ahash_request_ctx(areq); @@ -186,7 +186,7 @@ static int sun4i_hash(struct ahash_request *areq) struct sun4i_ss_ctx *ss = tfmctx->ss; struct scatterlist *in_sg = areq->src; struct sg_mapping_iter mi; - int in_r, err = 0, zeros; + int in_r, err = 0; size_t copied = 0; dev_dbg(ss->dev, "%s %s bc=%llu len=%u mode=%x wl=%u h0=%0x", @@ -387,6 +387,8 @@ hash_final: nbw = op->len - 4 * nwait; wb = *(u32 *)(op->buf + nwait * 4); wb &= (0xFFFFFFFF >> (4 - nbw) * 8); + + op->byte_count += nbw; } /* write the remaining bytes of the nbw buffer */ @@ -402,22 +404,15 @@ hash_final: * I take the operations from other MD5/SHA1 implementations */ - /* we have already send 4 more byte of which nbw data */ - if (op->mode == SS_OP_MD5) { - index = (op->byte_count + 4) & 0x3f; - op->byte_count += nbw; - if (index > 56) - zeros = (120 - index) / 4; - else - zeros = (56 - index) / 4; - } else { - op->byte_count += nbw; - index = op->byte_count & 0x3f; - padlen = (index < 56) ? (56 - index) : ((64 + 56) - index); - zeros = (padlen - 1) / 4; - } + /* last block size */ + fill = 64 - (op->byte_count % 64); + min_fill = 2 * sizeof(u32) + (nbw ? 0 : sizeof(u32)); + + /* if we can't fill all data, jump to the next 64 block */ + if (fill < min_fill) + fill += 64; - j += zeros; + j += (fill - min_fill) / sizeof(u32); /* write the length of data */ if (op->mode == SS_OP_SHA1) { -- cgit v1.2.3-59-g8ed1b From 303391d69b6ae7dff30f7886b717e39f47067d6d Mon Sep 17 00:00:00 2001 From: Antoine Ténart Date: Thu, 1 Jun 2017 21:38:59 +0200 Subject: crypto: sun4i-ss - simplify the appended bit assignment A bit is appended at the end of the input buffer for sha1. Simplify the code assigning it. Signed-off-by: Antoine Tenart Tested-by: Corentin Labbe Acked-by: Corentin Labbe Signed-off-by: Herbert Xu --- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/crypto/sunxi-ss/sun4i-ss-hash.c') diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c index 59d9b4412aca..0c2efc88bc0a 100644 --- a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c +++ b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c @@ -392,12 +392,8 @@ hash_final: } /* write the remaining bytes of the nbw buffer */ - if (nbw) { - wb |= ((1 << 7) << (nbw * 8)); - bf[j++] = wb; - } else { - bf[j++] = 1 << 7; - } + wb |= ((1 << 7) << (nbw * 8)); + bf[j++] = wb; /* * number of space to pad to obtain 64o minus 8(size) minus 4 (final 1) -- cgit v1.2.3-59-g8ed1b From d78867a94ea74b8d2dafdbf370e0707f37a58f4a Mon Sep 17 00:00:00 2001 From: Antoine Ténart Date: Thu, 1 Jun 2017 21:39:00 +0200 Subject: crypto: sun4i-ss - use GENMASK to generate masks Use the GENMASK helper instead of custom calculations to generate masks, It also helps the readability. Signed-off-by: Antoine Tenart Tested-by: Corentin Labbe Acked-by: Corentin Labbe Signed-off-by: Herbert Xu --- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/crypto/sunxi-ss/sun4i-ss-hash.c') diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c index 0c2efc88bc0a..685de5b6ab17 100644 --- a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c +++ b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c @@ -384,11 +384,14 @@ hash_final: writesl(ss->base + SS_RXFIFO, op->buf, nwait); op->byte_count += 4 * nwait; } + nbw = op->len - 4 * nwait; - wb = *(u32 *)(op->buf + nwait * 4); - wb &= (0xFFFFFFFF >> (4 - nbw) * 8); + if (nbw) { + wb = *(u32 *)(op->buf + nwait * 4); + wb &= GENMASK((nbw * 8) - 1, 0); - op->byte_count += nbw; + op->byte_count += nbw; + } } /* write the remaining bytes of the nbw buffer */ -- cgit v1.2.3-59-g8ed1b From 049655499e2ecc4d7d3920da44f117e091a2240b Mon Sep 17 00:00:00 2001 From: Antoine Ténart Date: Thu, 1 Jun 2017 21:39:03 +0200 Subject: crypto: sun4i-ss - fix large block size support The run-time self-tests fail quite early, as soon as the input block size is larger than 64 bytes: alg: hash: Test 4 failed for sha1-sun4i-ss 00000000: b9 c9 1e 52 c0 26 d8 39 81 ff f2 3c 99 b1 27 b2 00000010: 30 d6 c9 85 One thing to notice is the value of the last word, which is the one expected (it can sometime be the last two words). The datasheet isn't very clear about when the digest is ready to retrieve and is seems the bit SS_DATA_END is cleared when the digest was computed *but* that doesn't mean the digest is ready to retrieve in the registers. A ndelay(1) is added before reading the computed digest to ensure it is available in the SS_MD[] registers. Signed-off-by: Antoine Tenart Tested-by: Corentin Labbe Acked-by: Corentin Labbe Signed-off-by: Herbert Xu --- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers/crypto/sunxi-ss/sun4i-ss-hash.c') diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c index 685de5b6ab17..a4b5ff2b72f8 100644 --- a/drivers/crypto/sunxi-ss/sun4i-ss-hash.c +++ b/drivers/crypto/sunxi-ss/sun4i-ss-hash.c @@ -358,6 +358,15 @@ static int sun4i_hash(struct ahash_request *areq) goto release_ss; } + /* + * The datasheet isn't very clear about when to retrieve the digest. The + * bit SS_DATA_END is cleared when the engine has processed the data and + * when the digest is computed *but* it doesn't mean the digest is + * available in the digest registers. Hence the delay to be sure we can + * read it. + */ + ndelay(1); + for (i = 0; i < crypto_ahash_digestsize(tfm) / 4; i++) op->hash[i] = readl(ss->base + SS_MD0 + i * 4); @@ -446,6 +455,15 @@ hash_final: goto release_ss; } + /* + * The datasheet isn't very clear about when to retrieve the digest. The + * bit SS_DATA_END is cleared when the engine has processed the data and + * when the digest is computed *but* it doesn't mean the digest is + * available in the digest registers. Hence the delay to be sure we can + * read it. + */ + ndelay(1); + /* Get the hash from the device */ if (op->mode == SS_OP_SHA1) { for (i = 0; i < 5; i++) { -- cgit v1.2.3-59-g8ed1b