ARM: sun5i: cryptographic engine support
Subsystems (3)
v2 cover ARM: sun5i: cryptographic engine support
Hello,
This series adds the cryptographic engine support to sun5i SoCs. This is based on top of v4.12-rc1 and was tested on a CHIP. The series begins with fixes and improvements. The series is available at:
https://github.com/atenart/linux v4.12-rc1/sun5i-crypto
The 8 first patches are reworks and cosmetic improvements.
Patch 9 moves the cipher part of the sun4i-ss driver from the ablkcipher API to the newer skcipher API.
Patch 10 adds the CRYPTO_ALG_KERN_DRIVER_ONLY flag for ciphers exposed by the sun4i-ss driver.
Patch 11 fixes the crypto framework selftests on the CHIP. It might fix other users too.
Patch 12 adds a cryptographic engine node for sun5i SoCs.
Thanks,
Antoine
Since v1:
- Fixed a typo.
- Made the CRYPTO_ALG_KERN_DRIVER_ONLY flag addition in a dedicated patch.
Antoine Tenart (12):
crypto: sun4i-ss: group variable definitions in sun4i_hash()
crypto: sun4i-ss: remove conditional checks against 0
crypto: sun4i-ss: use lower/upper_32_bits helpers
crypto: sun4i-ss: cannot use DMA is the request is 0 length
crypto: sun4i-ss: do not dynamically set parts of the last buffer to 0
crypto: sun4i-ss: simplify the pad length calculation
crypto: sun4i-ss: simplify the appended bit assignment
crypto: sun4i-ss: use GENMASK to generate masks
crypto: sun4i-ss: move from ablkcipher to skcipher API
crypto: sun4i-ss: add the CRYPTO_ALG_KERN_DRIVER_ONLY flag
crypto: sun4i-ss: fix large block size support
ARM: sun5i: add a cryptographic engine node
arch/arm/boot/dts/sun5i.dtsi | 8 + drivers/crypto/sunxi-ss/sun4i-ss-cipher.c | 213 ++++++++++++++------------- drivers/crypto/sunxi-ss/sun4i-ss-core.c | 237 +++++++++++++++--------------- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 138 ++++++++--------- drivers/crypto/sunxi-ss/sun4i-ss.h | 34 +++-- 5 files changed, 321 insertions(+), 309 deletions(-)
Signature · 1 line
2.9.4
PATCH v2 1/12 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.
--- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-)
drivers/crypto/sunxi-ss/sun4i-ss-hash.c +11 -20
@@ -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),
Signature · 1 line
2.9.4
PATCH v2 2/12 crypto: sun4i-ss: remove conditional checks against 0
In reply to Antoine TenartCosmetic clean up if conditional checks on 0s values.
--- 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(-)
drivers/crypto/sunxi-ss/sun4i-ss-cipher.c +14 -14
@@ -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 ;
drivers/crypto/sunxi-ss/sun4i-ss-core.c +5 -5
@@ -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;
drivers/crypto/sunxi-ss/sun4i-ss-hash.c +20 -20
@@ -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 @@ static int sun4i_hash(struct ahash_request *areq) }/* 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 @@ 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",
@@ -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 ;
Signature · 1 line
2.9.4
PATCH v2 3/12 crypto: sun4i-ss: use lower/upper_32_bits helpers
In reply to Antoine TenartReplace custom bit shifts and masks with lower/upper_32_bits helpers.
--- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/crypto/sunxi-ss/sun4i-ss-hash.c +6 -6
@@ -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 @@ static int sun4i_hash(struct ahash_request *areq)/* 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);
Signature · 1 line
2.9.4
PATCH v2 4/12 crypto: sun4i-ss: cannot use DMA is the request is 0 length
In reply to Antoine TenartDo not use DMA is the request is 0 length.
--- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/crypto/sunxi-ss/sun4i-ss-hash.c +1 -1
@@ -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 ;
Signature · 1 line
2.9.4
PATCH v2 5/12 crypto: sun4i-ss: do not dynamically set parts of the last buffer to 0
In reply to Antoine TenartParts of the bf buffer were dynamically set to 0. Change this to set the whole buffer to 0 by default to avoid any mistake.
--- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/crypto/sunxi-ss/sun4i-ss-hash.c +1 -2
@@ -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 @@ static int sun4i_hash(struct ahash_request *areq) zeros = (padlen -1 ) /4 ; } -memset (bf + j,0 ,4 * zeros); j += zeros;/* write the length of data */
Signature · 1 line
2.9.4
PATCH v2 6/12 crypto: sun4i-ss: simplify the pad length calculation
In reply to Antoine TenartWhen 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.
--- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-)
drivers/crypto/sunxi-ss/sun4i-ss-hash.c +12 -17
@@ -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 @@ static int sun4i_hash(struct ahash_request *areq) 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 @@ static int sun4i_hash(struct ahash_request *areq)* 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 ) {
Signature · 1 line
2.9.4
PATCH v2 7/12 crypto: sun4i-ss: simplify the appended bit assignment
In reply to Antoine TenartA bit is appended at the end of the input buffer for sha1. Simplify the code assigning it.
--- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
drivers/crypto/sunxi-ss/sun4i-ss-hash.c +2 -6
@@ -392,12 +392,8 @@ static int sun4i_hash(struct ahash_request *areq) }/* 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)
Signature · 1 line
2.9.4
PATCH v2 8/12 crypto: sun4i-ss: use GENMASK to generate masks
In reply to Antoine TenartUse the GENMASK helper instead of custom calculations to generate masks, It also helps the readability.
--- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/crypto/sunxi-ss/sun4i-ss-hash.c +6 -3
@@ -384,11 +384,14 @@ static int sun4i_hash(struct ahash_request *areq)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 */
Signature · 1 line
2.9.4
PATCH v2 9/12 crypto: sun4i-ss: move from ablkcipher to skcipher API
In reply to Antoine TenartUpdate the sun4i-ss driver to use the skcipher API instead of the old ablkcipher one. It's a bit more tricky than s/ablkcipher/skcipher/, but still nothing special and the driver's logic stays the same.
--- drivers/crypto/sunxi-ss/sun4i-ss-cipher.c | 189 ++++++++++++------------- drivers/crypto/sunxi-ss/sun4i-ss-core.c | 222 +++++++++++++++--------------- drivers/crypto/sunxi-ss/sun4i-ss.h | 34 ++--- 3 files changed, 221 insertions(+), 224 deletions(-)
drivers/crypto/sunxi-ss/sun4i-ss-cipher.c +95 -94
@@ -16,13 +16,13 @@*/ #include "sun4i-ss.h" -static int sun4i_ss_opti_poll (struct ablkcipher_request *areq) +static int sun4i_ss_opti_poll (struct skcipher_request *areq) { -struct crypto_ablkcipher *tfm =crypto_ablkcipher_reqtfm (areq); -struct sun4i_tfm_ctx *op =crypto_ablkcipher_ctx (tfm); +struct crypto_skcipher *tfm =crypto_skcipher_reqtfm (areq); +struct sun4i_tfm_ctx *op =crypto_skcipher_ctx (tfm);struct sun4i_ss_ctx *ss = op->ss; -unsigned int ivsize =crypto_ablkcipher_ivsize (tfm); -struct sun4i_cipher_req_ctx *ctx =ablkcipher_request_ctx (areq); +unsigned int ivsize =crypto_skcipher_ivsize (tfm); +struct sun4i_cipher_req_ctx *ctx =skcipher_request_ctx (areq);u32 mode = ctx->mode;/* when activating SS, the default FIFO space is SS_RX_DEFAULT(32) */ u32 rx_cnt =SS_RX_DEFAULT ;
@@ -31,17 +31,17 @@ static int sun4i_ss_opti_poll(struct ablkcipher_request *areq)u32 v;int err =0 ;unsigned int i; -unsigned int ileft = areq->nbytes; -unsigned int oleft = areq->nbytes; +unsigned int ileft = areq->cryptlen; +unsigned int oleft = areq->cryptlen;unsigned int todo;struct sg_mapping_iter mi, mo;unsigned int oi, oo;/* offset for in and out */ unsigned long flags; -if (!areq->nbytes) +if (!areq->cryptlen)return 0 ; -if (!areq->info) { +if (!areq->iv) {dev_err_ratelimited (ss->dev,"ERROR: Empty IV\n" );return -EINVAL ; }
@@ -56,9 +56,9 @@ static int sun4i_ss_opti_poll(struct ablkcipher_request *areq)for (i =0 ; i < op->keylen; i +=4 )writel (*(op->key + i /4 ), ss->base +SS_KEY0 + i); -if (areq->info) { +if (areq->iv) {for (i =0 ; i <4 && i < ivsize /4 ; i++) { - v = *(u32 *)(areq->info + i *4 ); + v = *(u32 *)(areq->iv + i *4 );writel (v, ss->base +SS_IV0 + i *4 ); } }
@@ -76,8 +76,8 @@ static int sun4i_ss_opti_poll(struct ablkcipher_request *areq) goto release_ss; } - ileft = areq->nbytes /4 ; - oleft = areq->nbytes /4 ; + ileft = areq->cryptlen /4 ; + oleft = areq->cryptlen /4 ; oi =0 ; oo =0 ; do {
@@ -108,10 +108,10 @@ static int sun4i_ss_opti_poll(struct ablkcipher_request *areq) } }while (oleft); -if (areq->info) { +if (areq->iv) {for (i =0 ; i <4 && i < ivsize /4 ; i++) { v =readl (ss->base +SS_IV0 + i *4 ); - *(u32 *)(areq->info + i *4 ) = v; + *(u32 *)(areq->iv + i *4 ) = v; } }
@@ -124,16 +124,16 @@ static int sun4i_ss_opti_poll(struct ablkcipher_request *areq) }/* Generic function that support SG with size not multiple of 4 */ -static int sun4i_ss_cipher_poll (struct ablkcipher_request *areq) +static int sun4i_ss_cipher_poll (struct skcipher_request *areq) { -struct crypto_ablkcipher *tfm =crypto_ablkcipher_reqtfm (areq); -struct sun4i_tfm_ctx *op =crypto_ablkcipher_ctx (tfm); +struct crypto_skcipher *tfm =crypto_skcipher_reqtfm (areq); +struct sun4i_tfm_ctx *op =crypto_skcipher_ctx (tfm);struct sun4i_ss_ctx *ss = op->ss;int no_chunk =1 ;struct scatterlist *in_sg = areq->src;struct scatterlist *out_sg = areq->dst; -unsigned int ivsize =crypto_ablkcipher_ivsize (tfm); -struct sun4i_cipher_req_ctx *ctx =ablkcipher_request_ctx (areq); +unsigned int ivsize =crypto_skcipher_ivsize (tfm); +struct sun4i_cipher_req_ctx *ctx =skcipher_request_ctx (areq);u32 mode = ctx->mode;/* when activating SS, the default FIFO space is SS_RX_DEFAULT(32) */ u32 rx_cnt =SS_RX_DEFAULT ;
@@ -142,8 +142,8 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq)u32 spaces;int err =0 ;unsigned int i; -unsigned int ileft = areq->nbytes; -unsigned int oleft = areq->nbytes; +unsigned int ileft = areq->cryptlen; +unsigned int oleft = areq->cryptlen;unsigned int todo;struct sg_mapping_iter mi, mo;unsigned int oi, oo;/* offset for in and out */
@@ -154,10 +154,10 @@ 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) +if (!areq->cryptlen)return 0 ; -if (!areq->info) { +if (!areq->iv) {dev_err_ratelimited (ss->dev,"ERROR: Empty IV\n" );return -EINVAL ; }
@@ -190,9 +190,9 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq)for (i =0 ; i < op->keylen; i +=4 )writel (*(op->key + i /4 ), ss->base +SS_KEY0 + i); -if (areq->info) { +if (areq->iv) {for (i =0 ; i <4 && i < ivsize /4 ; i++) { - v = *(u32 *)(areq->info + i *4 ); + v = *(u32 *)(areq->iv + i *4 );writel (v, ss->base +SS_IV0 + i *4 ); } }
@@ -209,8 +209,8 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq) err = -EINVAL ; goto release_ss; } - ileft = areq->nbytes; - oleft = areq->nbytes; + ileft = areq->cryptlen; + oleft = areq->cryptlen; oi =0 ; oo =0 ;
@@ -257,8 +257,8 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq) tx_cnt =SS_TXFIFO_SPACES (spaces);dev_dbg (ss->dev,"%x %u/%u %u/%u cnt=%u %u/%u %u/%u cnt=%u %u\n" , mode, - oi, mi.length, ileft, areq->nbytes, rx_cnt, - oo, mo.length, oleft, areq->nbytes, tx_cnt, ob); + oi, mi.length, ileft, areq->cryptlen, rx_cnt, + oo, mo.length, oleft, areq->cryptlen, tx_cnt, ob);if (!tx_cnt)continue ;
@@ -300,10 +300,10 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq)/* bufo must be fully used here */ } } -if (areq->info) { +if (areq->iv) {for (i =0 ; i <4 && i < ivsize /4 ; i++) { v =readl (ss->base +SS_IV0 + i *4 ); - *(u32 *)(areq->info + i *4 ) = v; + *(u32 *)(areq->iv + i *4 ) = v; } }
@@ -317,22 +317,22 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq) }/* CBC AES */ -int sun4i_ss_cbc_aes_encrypt (struct ablkcipher_request *areq) +int sun4i_ss_cbc_aes_encrypt (struct skcipher_request *areq) { -struct crypto_ablkcipher *tfm =crypto_ablkcipher_reqtfm (areq); -struct sun4i_tfm_ctx *op =crypto_ablkcipher_ctx (tfm); -struct sun4i_cipher_req_ctx *rctx =ablkcipher_request_ctx (areq); +struct crypto_skcipher *tfm =crypto_skcipher_reqtfm (areq); +struct sun4i_tfm_ctx *op =crypto_skcipher_ctx (tfm); +struct sun4i_cipher_req_ctx *rctx =skcipher_request_ctx (areq); rctx->mode =SS_OP_AES |SS_CBC |SS_ENABLED |SS_ENCRYPTION | op->keymode;return sun4i_ss_cipher_poll (areq); } -int sun4i_ss_cbc_aes_decrypt (struct ablkcipher_request *areq) +int sun4i_ss_cbc_aes_decrypt (struct skcipher_request *areq) { -struct crypto_ablkcipher *tfm =crypto_ablkcipher_reqtfm (areq); -struct sun4i_tfm_ctx *op =crypto_ablkcipher_ctx (tfm); -struct sun4i_cipher_req_ctx *rctx =ablkcipher_request_ctx (areq); +struct crypto_skcipher *tfm =crypto_skcipher_reqtfm (areq); +struct sun4i_tfm_ctx *op =crypto_skcipher_ctx (tfm); +struct sun4i_cipher_req_ctx *rctx =skcipher_request_ctx (areq); rctx->mode =SS_OP_AES |SS_CBC |SS_ENABLED |SS_DECRYPTION | op->keymode;
@@ -340,22 +340,22 @@ int sun4i_ss_cbc_aes_decrypt(struct ablkcipher_request *areq) }/* ECB AES */ -int sun4i_ss_ecb_aes_encrypt (struct ablkcipher_request *areq) +int sun4i_ss_ecb_aes_encrypt (struct skcipher_request *areq) { -struct crypto_ablkcipher *tfm =crypto_ablkcipher_reqtfm (areq); -struct sun4i_tfm_ctx *op =crypto_ablkcipher_ctx (tfm); -struct sun4i_cipher_req_ctx *rctx =ablkcipher_request_ctx (areq); +struct crypto_skcipher *tfm =crypto_skcipher_reqtfm (areq); +struct sun4i_tfm_ctx *op =crypto_skcipher_ctx (tfm); +struct sun4i_cipher_req_ctx *rctx =skcipher_request_ctx (areq); rctx->mode =SS_OP_AES |SS_ECB |SS_ENABLED |SS_ENCRYPTION | op->keymode;return sun4i_ss_cipher_poll (areq); } -int sun4i_ss_ecb_aes_decrypt (struct ablkcipher_request *areq) +int sun4i_ss_ecb_aes_decrypt (struct skcipher_request *areq) { -struct crypto_ablkcipher *tfm =crypto_ablkcipher_reqtfm (areq); -struct sun4i_tfm_ctx *op =crypto_ablkcipher_ctx (tfm); -struct sun4i_cipher_req_ctx *rctx =ablkcipher_request_ctx (areq); +struct crypto_skcipher *tfm =crypto_skcipher_reqtfm (areq); +struct sun4i_tfm_ctx *op =crypto_skcipher_ctx (tfm); +struct sun4i_cipher_req_ctx *rctx =skcipher_request_ctx (areq); rctx->mode =SS_OP_AES |SS_ECB |SS_ENABLED |SS_DECRYPTION | op->keymode;
@@ -363,22 +363,22 @@ int sun4i_ss_ecb_aes_decrypt(struct ablkcipher_request *areq) }/* CBC DES */ -int sun4i_ss_cbc_des_encrypt (struct ablkcipher_request *areq) +int sun4i_ss_cbc_des_encrypt (struct skcipher_request *areq) { -struct crypto_ablkcipher *tfm =crypto_ablkcipher_reqtfm (areq); -struct sun4i_tfm_ctx *op =crypto_ablkcipher_ctx (tfm); -struct sun4i_cipher_req_ctx *rctx =ablkcipher_request_ctx (areq); +struct crypto_skcipher *tfm =crypto_skcipher_reqtfm (areq); +struct sun4i_tfm_ctx *op =crypto_skcipher_ctx (tfm); +struct sun4i_cipher_req_ctx *rctx =skcipher_request_ctx (areq); rctx->mode =SS_OP_DES |SS_CBC |SS_ENABLED |SS_ENCRYPTION | op->keymode;return sun4i_ss_cipher_poll (areq); } -int sun4i_ss_cbc_des_decrypt (struct ablkcipher_request *areq) +int sun4i_ss_cbc_des_decrypt (struct skcipher_request *areq) { -struct crypto_ablkcipher *tfm =crypto_ablkcipher_reqtfm (areq); -struct sun4i_tfm_ctx *op =crypto_ablkcipher_ctx (tfm); -struct sun4i_cipher_req_ctx *rctx =ablkcipher_request_ctx (areq); +struct crypto_skcipher *tfm =crypto_skcipher_reqtfm (areq); +struct sun4i_tfm_ctx *op =crypto_skcipher_ctx (tfm); +struct sun4i_cipher_req_ctx *rctx =skcipher_request_ctx (areq); rctx->mode =SS_OP_DES |SS_CBC |SS_ENABLED |SS_DECRYPTION | op->keymode;
@@ -386,22 +386,22 @@ int sun4i_ss_cbc_des_decrypt(struct ablkcipher_request *areq) }/* ECB DES */ -int sun4i_ss_ecb_des_encrypt (struct ablkcipher_request *areq) +int sun4i_ss_ecb_des_encrypt (struct skcipher_request *areq) { -struct crypto_ablkcipher *tfm =crypto_ablkcipher_reqtfm (areq); -struct sun4i_tfm_ctx *op =crypto_ablkcipher_ctx (tfm); -struct sun4i_cipher_req_ctx *rctx =ablkcipher_request_ctx (areq); +struct crypto_skcipher *tfm =crypto_skcipher_reqtfm (areq); +struct sun4i_tfm_ctx *op =crypto_skcipher_ctx (tfm); +struct sun4i_cipher_req_ctx *rctx =skcipher_request_ctx (areq); rctx->mode =SS_OP_DES |SS_ECB |SS_ENABLED |SS_ENCRYPTION | op->keymode;return sun4i_ss_cipher_poll (areq); } -int sun4i_ss_ecb_des_decrypt (struct ablkcipher_request *areq) +int sun4i_ss_ecb_des_decrypt (struct skcipher_request *areq) { -struct crypto_ablkcipher *tfm =crypto_ablkcipher_reqtfm (areq); -struct sun4i_tfm_ctx *op =crypto_ablkcipher_ctx (tfm); -struct sun4i_cipher_req_ctx *rctx =ablkcipher_request_ctx (areq); +struct crypto_skcipher *tfm =crypto_skcipher_reqtfm (areq); +struct sun4i_tfm_ctx *op =crypto_skcipher_ctx (tfm); +struct sun4i_cipher_req_ctx *rctx =skcipher_request_ctx (areq); rctx->mode =SS_OP_DES |SS_ECB |SS_ENABLED |SS_DECRYPTION | op->keymode;
@@ -409,22 +409,22 @@ int sun4i_ss_ecb_des_decrypt(struct ablkcipher_request *areq) }/* CBC 3DES */ -int sun4i_ss_cbc_des3_encrypt (struct ablkcipher_request *areq) +int sun4i_ss_cbc_des3_encrypt (struct skcipher_request *areq) { -struct crypto_ablkcipher *tfm =crypto_ablkcipher_reqtfm (areq); -struct sun4i_tfm_ctx *op =crypto_ablkcipher_ctx (tfm); -struct sun4i_cipher_req_ctx *rctx =ablkcipher_request_ctx (areq); +struct crypto_skcipher *tfm =crypto_skcipher_reqtfm (areq); +struct sun4i_tfm_ctx *op =crypto_skcipher_ctx (tfm); +struct sun4i_cipher_req_ctx *rctx =skcipher_request_ctx (areq); rctx->mode =SS_OP_3DES |SS_CBC |SS_ENABLED |SS_ENCRYPTION | op->keymode;return sun4i_ss_cipher_poll (areq); } -int sun4i_ss_cbc_des3_decrypt (struct ablkcipher_request *areq) +int sun4i_ss_cbc_des3_decrypt (struct skcipher_request *areq) { -struct crypto_ablkcipher *tfm =crypto_ablkcipher_reqtfm (areq); -struct sun4i_tfm_ctx *op =crypto_ablkcipher_ctx (tfm); -struct sun4i_cipher_req_ctx *rctx =ablkcipher_request_ctx (areq); +struct crypto_skcipher *tfm =crypto_skcipher_reqtfm (areq); +struct sun4i_tfm_ctx *op =crypto_skcipher_ctx (tfm); +struct sun4i_cipher_req_ctx *rctx =skcipher_request_ctx (areq); rctx->mode =SS_OP_3DES |SS_CBC |SS_ENABLED |SS_DECRYPTION | op->keymode;
@@ -432,22 +432,22 @@ int sun4i_ss_cbc_des3_decrypt(struct ablkcipher_request *areq) }/* ECB 3DES */ -int sun4i_ss_ecb_des3_encrypt (struct ablkcipher_request *areq) +int sun4i_ss_ecb_des3_encrypt (struct skcipher_request *areq) { -struct crypto_ablkcipher *tfm =crypto_ablkcipher_reqtfm (areq); -struct sun4i_tfm_ctx *op =crypto_ablkcipher_ctx (tfm); -struct sun4i_cipher_req_ctx *rctx =ablkcipher_request_ctx (areq); +struct crypto_skcipher *tfm =crypto_skcipher_reqtfm (areq); +struct sun4i_tfm_ctx *op =crypto_skcipher_ctx (tfm); +struct sun4i_cipher_req_ctx *rctx =skcipher_request_ctx (areq); rctx->mode =SS_OP_3DES |SS_ECB |SS_ENABLED |SS_ENCRYPTION | op->keymode;return sun4i_ss_cipher_poll (areq); } -int sun4i_ss_ecb_des3_decrypt (struct ablkcipher_request *areq) +int sun4i_ss_ecb_des3_decrypt (struct skcipher_request *areq) { -struct crypto_ablkcipher *tfm =crypto_ablkcipher_reqtfm (areq); -struct sun4i_tfm_ctx *op =crypto_ablkcipher_ctx (tfm); -struct sun4i_cipher_req_ctx *rctx =ablkcipher_request_ctx (areq); +struct crypto_skcipher *tfm =crypto_skcipher_reqtfm (areq); +struct sun4i_tfm_ctx *op =crypto_skcipher_ctx (tfm); +struct sun4i_cipher_req_ctx *rctx =skcipher_request_ctx (areq); rctx->mode =SS_OP_3DES |SS_ECB |SS_ENABLED |SS_DECRYPTION | op->keymode;
@@ -457,24 +457,25 @@ int sun4i_ss_ecb_des3_decrypt(struct ablkcipher_request *areq)int sun4i_ss_cipher_init (struct crypto_tfm *tfm) {struct sun4i_tfm_ctx *op =crypto_tfm_ctx (tfm); -struct crypto_alg *alg = tfm->__crt_alg;struct sun4i_ss_alg_template *algt;memset (op,0 ,sizeof (struct sun4i_tfm_ctx )); - algt = container_of(alg, struct sun4i_ss_alg_template, alg.crypto); + algt = container_of(tfm->__crt_alg, struct sun4i_ss_alg_template, + alg.crypto.base); op->ss = algt->ss; - tfm->crt_ablkcipher.reqsize =sizeof (struct sun4i_cipher_req_ctx ); +crypto_skcipher_set_reqsize (__crypto_skcipher_cast (tfm), +sizeof (struct sun4i_cipher_req_ctx ));return 0 ; }/* check and set the AES key, prepare the mode to be used */ -int sun4i_ss_aes_setkey (struct crypto_ablkcipher *tfm,const u8 *key, +int sun4i_ss_aes_setkey (struct crypto_skcipher *tfm,const u8 *key,unsigned int keylen) { -struct sun4i_tfm_ctx *op =crypto_ablkcipher_ctx (tfm); +struct sun4i_tfm_ctx *op =crypto_skcipher_ctx (tfm);struct sun4i_ss_ctx *ss = op->ss;switch (keylen) {
@@ -489,7 +490,7 @@ int sun4i_ss_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,break ;default :dev_err (ss->dev,"ERROR: Invalid keylen %u\n" , keylen); -crypto_ablkcipher_set_flags (tfm,CRYPTO_TFM_RES_BAD_KEY_LEN ); +crypto_skcipher_set_flags (tfm,CRYPTO_TFM_RES_BAD_KEY_LEN );return -EINVAL ; } op->keylen = keylen;
@@ -498,10 +499,10 @@ int sun4i_ss_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, }/* check and set the DES key, prepare the mode to be used */ -int sun4i_ss_des_setkey (struct crypto_ablkcipher *tfm,const u8 *key, +int sun4i_ss_des_setkey (struct crypto_skcipher *tfm,const u8 *key,unsigned int keylen) { -struct sun4i_tfm_ctx *op =crypto_ablkcipher_ctx (tfm); +struct sun4i_tfm_ctx *op =crypto_skcipher_ctx (tfm);struct sun4i_ss_ctx *ss = op->ss;u32 flags;u32 tmp[DES_EXPKEY_WORDS ];
@@ -509,15 +510,15 @@ int sun4i_ss_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key,if (unlikely (keylen !=DES_KEY_SIZE )) {dev_err (ss->dev,"Invalid keylen %u\n" , keylen); -crypto_ablkcipher_set_flags (tfm,CRYPTO_TFM_RES_BAD_KEY_LEN ); +crypto_skcipher_set_flags (tfm,CRYPTO_TFM_RES_BAD_KEY_LEN );return -EINVAL ; } - flags =crypto_ablkcipher_get_flags (tfm); + flags =crypto_skcipher_get_flags (tfm); ret =des_ekey (tmp, key);if (unlikely (!ret) && (flags &CRYPTO_TFM_REQ_WEAK_KEY )) { -crypto_ablkcipher_set_flags (tfm,CRYPTO_TFM_RES_WEAK_KEY ); +crypto_skcipher_set_flags (tfm,CRYPTO_TFM_RES_WEAK_KEY );dev_dbg (ss->dev,"Weak key %u\n" , keylen);return -EINVAL ; }
@@ -528,15 +529,15 @@ int sun4i_ss_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, }/* check and set the 3DES key, prepare the mode to be used */ -int sun4i_ss_des3_setkey (struct crypto_ablkcipher *tfm,const u8 *key, +int sun4i_ss_des3_setkey (struct crypto_skcipher *tfm,const u8 *key,unsigned int keylen) { -struct sun4i_tfm_ctx *op =crypto_ablkcipher_ctx (tfm); +struct sun4i_tfm_ctx *op =crypto_skcipher_ctx (tfm);struct sun4i_ss_ctx *ss = op->ss;if (unlikely (keylen !=3 *DES_KEY_SIZE )) {dev_err (ss->dev,"Invalid keylen %u\n" , keylen); -crypto_ablkcipher_set_flags (tfm,CRYPTO_TFM_RES_BAD_KEY_LEN ); +crypto_skcipher_set_flags (tfm,CRYPTO_TFM_RES_BAD_KEY_LEN );return -EINVAL ; } op->keylen = keylen;
drivers/crypto/sunxi-ss/sun4i-ss-core.c +108 -114
269 lines not on this page · raw message
drivers/crypto/sunxi-ss/sun4i-ss.h +18 -16
@@ -24,9 +24,11 @@#include <linux/interrupt.h> #include <linux/delay.h> #include <crypto/md5.h> +#include <crypto/skcipher.h> #include <crypto/sha.h> #include <crypto/hash.h> #include <crypto/internal/hash.h> +#include <crypto/internal/skcipher.h> #include <crypto/aes.h> #include <crypto/des.h> #include <crypto/internal/rng.h>
@@ -140,7 +142,7 @@ struct sun4i_ss_alg_template {u32 type;u32 mode;union { -struct crypto_alg crypto; +struct skcipher_alg crypto;struct ahash_alg hash; } alg;struct sun4i_ss_ctx *ss;
@@ -177,25 +179,25 @@ int sun4i_hash_import_md5(struct ahash_request *areq, const void *in);int sun4i_hash_export_sha1 (struct ahash_request *areq,void *out);int sun4i_hash_import_sha1 (struct ahash_request *areq,const void *in); -int sun4i_ss_cbc_aes_encrypt (struct ablkcipher_request *areq); -int sun4i_ss_cbc_aes_decrypt (struct ablkcipher_request *areq); -int sun4i_ss_ecb_aes_encrypt (struct ablkcipher_request *areq); -int sun4i_ss_ecb_aes_decrypt (struct ablkcipher_request *areq); +int sun4i_ss_cbc_aes_encrypt (struct skcipher_request *areq); +int sun4i_ss_cbc_aes_decrypt (struct skcipher_request *areq); +int sun4i_ss_ecb_aes_encrypt (struct skcipher_request *areq); +int sun4i_ss_ecb_aes_decrypt (struct skcipher_request *areq); -int sun4i_ss_cbc_des_encrypt (struct ablkcipher_request *areq); -int sun4i_ss_cbc_des_decrypt (struct ablkcipher_request *areq); -int sun4i_ss_ecb_des_encrypt (struct ablkcipher_request *areq); -int sun4i_ss_ecb_des_decrypt (struct ablkcipher_request *areq); +int sun4i_ss_cbc_des_encrypt (struct skcipher_request *areq); +int sun4i_ss_cbc_des_decrypt (struct skcipher_request *areq); +int sun4i_ss_ecb_des_encrypt (struct skcipher_request *areq); +int sun4i_ss_ecb_des_decrypt (struct skcipher_request *areq); -int sun4i_ss_cbc_des3_encrypt (struct ablkcipher_request *areq); -int sun4i_ss_cbc_des3_decrypt (struct ablkcipher_request *areq); -int sun4i_ss_ecb_des3_encrypt (struct ablkcipher_request *areq); -int sun4i_ss_ecb_des3_decrypt (struct ablkcipher_request *areq); +int sun4i_ss_cbc_des3_encrypt (struct skcipher_request *areq); +int sun4i_ss_cbc_des3_decrypt (struct skcipher_request *areq); +int sun4i_ss_ecb_des3_encrypt (struct skcipher_request *areq); +int sun4i_ss_ecb_des3_decrypt (struct skcipher_request *areq);int sun4i_ss_cipher_init (struct crypto_tfm *tfm); -int sun4i_ss_aes_setkey (struct crypto_ablkcipher *tfm,const u8 *key, +int sun4i_ss_aes_setkey (struct crypto_skcipher *tfm,const u8 *key,unsigned int keylen); -int sun4i_ss_des_setkey (struct crypto_ablkcipher *tfm,const u8 *key, +int sun4i_ss_des_setkey (struct crypto_skcipher *tfm,const u8 *key,unsigned int keylen); -int sun4i_ss_des3_setkey (struct crypto_ablkcipher *tfm,const u8 *key, +int sun4i_ss_des3_setkey (struct crypto_skcipher *tfm,const u8 *key,unsigned int keylen);
Signature · 1 line
2.9.4
PATCH v2 10/12 crypto: sun4i-ss: add the CRYPTO_ALG_KERN_DRIVER_ONLY flag
In reply to Antoine TenartThe CRYPTO_ALG_KERN_DRIVER_ONLY flag is set for hardware accelerated ciphers accessible through a kernel driver only. This is the case for ciphers exposed by the sun4i-ss driver. This patch sets this flag.
--- drivers/crypto/sunxi-ss/sun4i-ss-core.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/crypto/sunxi-ss/sun4i-ss-core.c +10 -5
@@ -96,7 +96,8 @@ static struct sun4i_ss_alg_template ss_algs[] = { .cra_driver_name = "cbc-aes-sun4i-ss", .cra_priority = 300, .cra_blocksize = AES_BLOCK_SIZE, - .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER, + .cra_flags =CRYPTO_ALG_TYPE_SKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_ctxsize = sizeof(struct sun4i_tfm_ctx), .cra_module = THIS_MODULE, .cra_alignmask = 3,
@@ -117,7 +118,8 @@ static struct sun4i_ss_alg_template ss_algs[] = { .cra_driver_name = "ecb-aes-sun4i-ss", .cra_priority = 300, .cra_blocksize = AES_BLOCK_SIZE, - .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER, + .cra_flags =CRYPTO_ALG_TYPE_SKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_ctxsize = sizeof(struct sun4i_tfm_ctx), .cra_module = THIS_MODULE, .cra_alignmask = 3,
@@ -138,7 +140,8 @@ static struct sun4i_ss_alg_template ss_algs[] = { .cra_driver_name = "cbc-des-sun4i-ss", .cra_priority = 300, .cra_blocksize = DES_BLOCK_SIZE, - .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER, + .cra_flags =CRYPTO_ALG_TYPE_SKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_ctxsize = sizeof(struct sun4i_req_ctx), .cra_module = THIS_MODULE, .cra_alignmask = 3,
@@ -158,7 +161,8 @@ static struct sun4i_ss_alg_template ss_algs[] = { .cra_driver_name = "ecb-des-sun4i-ss", .cra_priority = 300, .cra_blocksize = DES_BLOCK_SIZE, - .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER, + .cra_flags =CRYPTO_ALG_TYPE_SKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_ctxsize = sizeof(struct sun4i_req_ctx), .cra_module = THIS_MODULE, .cra_alignmask = 3,
@@ -179,7 +183,8 @@ static struct sun4i_ss_alg_template ss_algs[] = { .cra_driver_name = "cbc-des3-sun4i-ss", .cra_priority = 300, .cra_blocksize = DES3_EDE_BLOCK_SIZE, - .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER, + .cra_flags =CRYPTO_ALG_TYPE_SKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_ctxsize = sizeof(struct sun4i_req_ctx), .cra_module = THIS_MODULE, .cra_alignmask = 3,
Signature · 1 line
2.9.4
PATCH v2 11/12 crypto: sun4i-ss: fix large block size support
In reply to Antoine TenartThe 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.
--- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
drivers/crypto/sunxi-ss/sun4i-ss-hash.c +18 -0
@@ -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 @@ 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 ); +/* Get the hash from the device */ if (op->mode ==SS_OP_SHA1 ) {for (i =0 ; i <5 ; i++) {
Signature · 1 line
2.9.4
PATCH v2 12/12 ARM: sun5i: add a cryptographic engine node
In reply to Antoine TenartAdd a node for the cryptographic engine that can be found on sun5i SoCs. This cryptographic engine is compatible with the Allwinner cryptographic accelerator driver.
--- arch/arm/boot/dts/sun5i.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+)
arch/arm/boot/dts/sun5i.dtsi +8 -0
@@ -355,6 +355,14 @@ status = "disabled"; }; + crypto: crypto-engine at 01c15000 { + compatible = "allwinner,sun4i-a10-crypto"; + reg = <0x01c15000 0x1000>; + interrupts = <54>; + clocks = <&ccu CLK_AHB_SS>, <&ccu CLK_SS>; + clock-names = "ahb", "mod"; + }; + spi2: spi at 01c17000 { compatible = "allwinner,sun4i-a10-spi"; reg = <0x01c17000 0x1000>;
Signature · 1 line
2.9.4
PATCH v2 12/12 ARM: sun5i: add a cryptographic engine node
Quoted 14 lines · Antoine Tenart
Add a node for the cryptographic engine that can be found on sun5i SoCs. This cryptographic engine is compatible with the Allwinner cryptographic accelerator driver.
Signed-off-by Antoine Tenart <[email protected]>--- arch/arm/boot/dts/sun5i.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+)arch/arm/boot/dts/sun5i.dtsi +0
-0
arch/arm/boot/dts/sun5i.dtsi line 359
Quoted 5 lines
arch/arm/boot/dts/sun5i.dtsi +2
-0@@ -355,6 +355,14 @@ status = "disabled"; }; + crypto: crypto-engine at 01c15000 { + compatible = "allwinner,sun4i-a10-crypto";
you should add a SoC-specific compatible here, just so that if we ever need to fix something in there we don't have to update our DT.
Thanks!
Maxime
Signature · 10 lines
Maxime Ripard, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 801 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170530/71fee8b8/attachment.sig>
PATCH v2 12/12 ARM: sun5i: add a cryptographic engine node
Hi Maxime,
Quoted 18 lines · Maxime Ripard
Quoted 17 lines · Antoine Tenart
Add a node for the cryptographic engine that can be found on sun5i SoCs. This cryptographic engine is compatible with the Allwinner cryptographic accelerator driver.
Signed-off-by Antoine Tenart <[email protected]>--- arch/arm/boot/dts/sun5i.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+)arch/arm/boot/dts/sun5i.dtsi +0
-0@@ -355,6 +355,14 @@ status = "disabled"; };
Quoted 5 lines
arch/arm/boot/dts/sun5i.dtsi line 359
Quoted 2 lines
arch/arm/boot/dts/sun5i.dtsi +2
-0+ crypto: crypto-engine at 01c15000 { + compatible = "allwinner,sun4i-a10-crypto";you should add a SoC-specific compatible here, just so that if we ever need to fix something in there we don't have to update our DT.
Sure. I'll also make patches for the other sunXi crypto nodes as they do no have SoC-specific compatibles either.
Thanks,
Antoine
Signature · 10 lines
Antoine T?nart, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170530/0ac167d0/attachment.sig>
v2 cover ARM: sun5i: cryptographic engine support
In reply to Antoine TenartQuoted 42 lines · Antoine Tenart
Hello,
This series adds the cryptographic engine support to sun5i SoCs. This is based on top of v4.12-rc1 and was tested on a CHIP. The series begins with fixes and improvements. The series is available at:
https://github.com/atenart/linux v4.12-rc1/sun5i-cryptoThe 8 first patches are reworks and cosmetic improvements.
Patch 9 moves the cipher part of the sun4i-ss driver from the ablkcipher API to the newer skcipher API.
Patch 10 adds the
CRYPTO_ALG_KERN_DRIVER_ONLYflag for ciphers exposed by the sun4i-ss driver.Patch 11 fixes the crypto framework selftests on the CHIP. It might fix other users too.
Patch 12 adds a cryptographic engine node for sun5i SoCs.
Thanks,
AntoineSince v1:
- Fixed a typo.
- Made theCRYPTO_ALG_KERN_DRIVER_ONLYflag addition in a dedicated patch.Antoine Tenart (12):
crypto: sun4i-ss: group variable definitions insun4i_hash()
crypto: sun4i-ss: remove conditional checks against 0
crypto: sun4i-ss: use lower/upper_32_bits helpers
crypto: sun4i-ss: cannot use DMA is the request is 0 length
crypto: sun4i-ss: do not dynamically set parts of the last buffer to 0
crypto: sun4i-ss: simplify the pad length calculation
crypto: sun4i-ss: simplify the appended bit assignment
crypto: sun4i-ss: use GENMASK to generate masks
crypto: sun4i-ss: move from ablkcipher to skcipher API
crypto: sun4i-ss: add theCRYPTO_ALG_KERN_DRIVER_ONLYflag
crypto: sun4i-ss: fix large block size support
ARM: sun5i: add a cryptographic engine node
Quoted 7 lines
arch/arm/boot/dts/sun5i.dtsi | 8 + drivers/crypto/sunxi-ss/sun4i-ss-cipher.c | 213 ++++++++++++++------------- drivers/crypto/sunxi-ss/sun4i-ss-core.c | 237 +++++++++++++++--------------- drivers/crypto/sunxi-ss/sun4i-ss-hash.c | 138 ++++++++--------- drivers/crypto/sunxi-ss/sun4i-ss.h | 34 +++-- 5 files changed, 321 insertions(+), 309 deletions(-)
Hello
Thanks for the work
For the whole serie: