From 56442e69cbaf31555a9bb4f3311a0593a0c172cc Mon Sep 17 00:00:00 2001 From: Romuald JEANNE Date: Tue, 16 Mar 2021 08:56:48 +0100 Subject: [PATCH 04/22] ARM 5.10.10-stm32mp1-r1 CRYPTO --- drivers/crypto/stm32/stm32-cryp.c | 300 +++++++++++++++++++++--------- drivers/crypto/stm32/stm32-hash.c | 19 +- 2 files changed, 228 insertions(+), 91 deletions(-) diff --git a/drivers/crypto/stm32/stm32-cryp.c b/drivers/crypto/stm32/stm32-cryp.c index 2670c30332fa..503428bf15cb 100644 --- a/drivers/crypto/stm32/stm32-cryp.c +++ b/drivers/crypto/stm32/stm32-cryp.c @@ -144,10 +144,10 @@ struct stm32_cryp { size_t authsize; size_t hw_blocksize; + size_t remain_in; size_t total_in; - size_t total_in_save; + size_t remain_out; size_t total_out; - size_t total_out_save; struct scatterlist *in_sg; struct scatterlist *out_sg; @@ -157,9 +157,6 @@ struct stm32_cryp { struct scatterlist out_sgl; bool sgs_copied; - int in_sg_len; - int out_sg_len; - struct scatter_walk in_walk; struct scatter_walk out_walk; @@ -322,28 +319,46 @@ static int stm32_cryp_check_io_aligned(struct stm32_cryp *cryp) ret = stm32_cryp_check_aligned(cryp->out_sg, cryp->total_out, cryp->hw_blocksize); + if (ret) + return ret; + + if (is_gcm(cryp) || is_ccm(cryp)) + if (!IS_ALIGNED(cryp->areq->assoclen, sizeof(u32))) + ret = -EINVAL; return ret; } static void sg_copy_buf(void *buf, struct scatterlist *sg, - unsigned int start, unsigned int nbytes, int out) + unsigned int start, unsigned int first_len, + unsigned int zero_len, + unsigned int second_len, + int out) { struct scatter_walk walk; + unsigned int nbytes = first_len + zero_len + second_len; + u32 empty = 0; if (!nbytes) return; scatterwalk_start(&walk, sg); scatterwalk_advance(&walk, start); - scatterwalk_copychunks(buf, &walk, nbytes, out); + if (first_len) + scatterwalk_copychunks(buf, &walk, first_len, out); + if (zero_len) + memcpy(buf+first_len, &empty, zero_len); + if (second_len) + scatterwalk_copychunks(buf + first_len + zero_len, &walk, + second_len, out); + scatterwalk_done(&walk, out, 0); } static int stm32_cryp_copy_sgs(struct stm32_cryp *cryp) { void *buf_in, *buf_out; - int pages, total_in, total_out; + int pages_in, pages_out, total_in, total_out; if (!stm32_cryp_check_io_aligned(cryp)) { cryp->sgs_copied = 0; @@ -351,29 +366,37 @@ static int stm32_cryp_copy_sgs(struct stm32_cryp *cryp) } total_in = ALIGN(cryp->total_in, cryp->hw_blocksize); - pages = total_in ? get_order(total_in) : 1; - buf_in = (void *)__get_free_pages(GFP_ATOMIC, pages); + pages_in = total_in ? get_order(total_in) : 1; + buf_in = (void *)__get_free_pages(GFP_ATOMIC, pages_in); total_out = ALIGN(cryp->total_out, cryp->hw_blocksize); - pages = total_out ? get_order(total_out) : 1; - buf_out = (void *)__get_free_pages(GFP_ATOMIC, pages); + pages_out = total_out ? get_order(total_out) : 1; + buf_out = (void *)__get_free_pages(GFP_ATOMIC, pages_out); if (!buf_in || !buf_out) { dev_err(cryp->dev, "Can't allocate pages when unaligned\n"); + if (buf_in) + free_pages((unsigned long)buf_in, pages_in); cryp->sgs_copied = 0; return -EFAULT; } - sg_copy_buf(buf_in, cryp->in_sg, 0, cryp->total_in, 0); + + if ((is_gcm(cryp) || is_ccm(cryp)) && (!IS_ALIGNED(cryp->areq->assoclen, + sizeof(u32)))) { + sg_copy_buf(buf_in, cryp->in_sg, 0, cryp->areq->assoclen, + ALIGN(cryp->areq->assoclen, sizeof(u32)) + - cryp->areq->assoclen, + cryp->areq->cryptlen, 0); + } else + sg_copy_buf(buf_in, cryp->in_sg, 0, cryp->total_in, 0, 0, 0); sg_init_one(&cryp->in_sgl, buf_in, total_in); cryp->in_sg = &cryp->in_sgl; - cryp->in_sg_len = 1; sg_init_one(&cryp->out_sgl, buf_out, total_out); cryp->out_sg_save = cryp->out_sg; cryp->out_sg = &cryp->out_sgl; - cryp->out_sg_len = 1; cryp->sgs_copied = 1; @@ -654,14 +677,14 @@ static void stm32_cryp_finish_req(struct stm32_cryp *cryp, int err) buf_in = sg_virt(&cryp->in_sgl); buf_out = sg_virt(&cryp->out_sgl); - sg_copy_buf(buf_out, cryp->out_sg_save, 0, - cryp->total_out_save, 1); + sg_copy_buf(buf_out, cryp->out_sg_save, 0, 0, 0, + cryp->total_out, 1); - len = ALIGN(cryp->total_in_save, cryp->hw_blocksize); + len = ALIGN(cryp->total_in, cryp->hw_blocksize); pages = len ? get_order(len) : 1; free_pages((unsigned long)buf_in, pages); - len = ALIGN(cryp->total_out_save, cryp->hw_blocksize); + len = ALIGN(cryp->total_out, cryp->hw_blocksize); pages = len ? get_order(len) : 1; free_pages((unsigned long)buf_out, pages); } @@ -801,7 +824,20 @@ static int stm32_cryp_aes_aead_setkey(struct crypto_aead *tfm, const u8 *key, static int stm32_cryp_aes_gcm_setauthsize(struct crypto_aead *tfm, unsigned int authsize) { - return authsize == AES_BLOCK_SIZE ? 0 : -EINVAL; + switch (authsize) { + case 4: + case 8: + case 12: + case 13: + case 14: + case 15: + case 16: + break; + default: + return -EINVAL; + } + + return 0; } static int stm32_cryp_aes_ccm_setauthsize(struct crypto_aead *tfm, @@ -825,31 +861,61 @@ static int stm32_cryp_aes_ccm_setauthsize(struct crypto_aead *tfm, static int stm32_cryp_aes_ecb_encrypt(struct skcipher_request *req) { + if (req->cryptlen % AES_BLOCK_SIZE) + return -EINVAL; + + if (req->cryptlen == 0) + return 0; + return stm32_cryp_crypt(req, FLG_AES | FLG_ECB | FLG_ENCRYPT); } static int stm32_cryp_aes_ecb_decrypt(struct skcipher_request *req) { + if (req->cryptlen % AES_BLOCK_SIZE) + return -EINVAL; + + if (req->cryptlen == 0) + return 0; + return stm32_cryp_crypt(req, FLG_AES | FLG_ECB); } static int stm32_cryp_aes_cbc_encrypt(struct skcipher_request *req) { + if (req->cryptlen % AES_BLOCK_SIZE) + return -EINVAL; + + if (req->cryptlen == 0) + return 0; + return stm32_cryp_crypt(req, FLG_AES | FLG_CBC | FLG_ENCRYPT); } static int stm32_cryp_aes_cbc_decrypt(struct skcipher_request *req) { + if (req->cryptlen % AES_BLOCK_SIZE) + return -EINVAL; + + if (req->cryptlen == 0) + return 0; + return stm32_cryp_crypt(req, FLG_AES | FLG_CBC); } static int stm32_cryp_aes_ctr_encrypt(struct skcipher_request *req) { + if (req->cryptlen == 0) + return 0; + return stm32_cryp_crypt(req, FLG_AES | FLG_CTR | FLG_ENCRYPT); } static int stm32_cryp_aes_ctr_decrypt(struct skcipher_request *req) { + if (req->cryptlen == 0) + return 0; + return stm32_cryp_crypt(req, FLG_AES | FLG_CTR); } @@ -863,53 +929,122 @@ static int stm32_cryp_aes_gcm_decrypt(struct aead_request *req) return stm32_cryp_aead_crypt(req, FLG_AES | FLG_GCM); } +static inline int crypto_ccm_check_iv(const u8 *iv) +{ + /* 2 <= L <= 8, so 1 <= L' <= 7. */ + if (iv[0] < 1 || iv[0] > 7) + return -EINVAL; + + return 0; +} + static int stm32_cryp_aes_ccm_encrypt(struct aead_request *req) { + int err; + + err = crypto_ccm_check_iv(req->iv); + if (err) + return err; + return stm32_cryp_aead_crypt(req, FLG_AES | FLG_CCM | FLG_ENCRYPT); } static int stm32_cryp_aes_ccm_decrypt(struct aead_request *req) { + int err; + + err = crypto_ccm_check_iv(req->iv); + if (err) + return err; + return stm32_cryp_aead_crypt(req, FLG_AES | FLG_CCM); } static int stm32_cryp_des_ecb_encrypt(struct skcipher_request *req) { + if (req->cryptlen % DES_BLOCK_SIZE) + return -EINVAL; + + if (req->cryptlen == 0) + return 0; + return stm32_cryp_crypt(req, FLG_DES | FLG_ECB | FLG_ENCRYPT); } static int stm32_cryp_des_ecb_decrypt(struct skcipher_request *req) { + if (req->cryptlen % DES_BLOCK_SIZE) + return -EINVAL; + + if (req->cryptlen == 0) + return 0; + return stm32_cryp_crypt(req, FLG_DES | FLG_ECB); } static int stm32_cryp_des_cbc_encrypt(struct skcipher_request *req) { + if (req->cryptlen % DES_BLOCK_SIZE) + return -EINVAL; + + if (req->cryptlen == 0) + return 0; + return stm32_cryp_crypt(req, FLG_DES | FLG_CBC | FLG_ENCRYPT); } static int stm32_cryp_des_cbc_decrypt(struct skcipher_request *req) { + if (req->cryptlen % DES_BLOCK_SIZE) + return -EINVAL; + + if (req->cryptlen == 0) + return 0; + return stm32_cryp_crypt(req, FLG_DES | FLG_CBC); } static int stm32_cryp_tdes_ecb_encrypt(struct skcipher_request *req) { + if (req->cryptlen % DES_BLOCK_SIZE) + return -EINVAL; + + if (req->cryptlen == 0) + return 0; + return stm32_cryp_crypt(req, FLG_TDES | FLG_ECB | FLG_ENCRYPT); } static int stm32_cryp_tdes_ecb_decrypt(struct skcipher_request *req) { + if (req->cryptlen % DES_BLOCK_SIZE) + return -EINVAL; + + if (req->cryptlen == 0) + return 0; + return stm32_cryp_crypt(req, FLG_TDES | FLG_ECB); } static int stm32_cryp_tdes_cbc_encrypt(struct skcipher_request *req) { + if (req->cryptlen % DES_BLOCK_SIZE) + return -EINVAL; + + if (req->cryptlen == 0) + return 0; + return stm32_cryp_crypt(req, FLG_TDES | FLG_CBC | FLG_ENCRYPT); } static int stm32_cryp_tdes_cbc_decrypt(struct skcipher_request *req) { + if (req->cryptlen % DES_BLOCK_SIZE) + return -EINVAL; + + if (req->cryptlen == 0) + return 0; + return stm32_cryp_crypt(req, FLG_TDES | FLG_CBC); } @@ -971,36 +1106,25 @@ static int stm32_cryp_prepare_req(struct skcipher_request *req, cryp->areq = areq; cryp->req = NULL; cryp->authsize = crypto_aead_authsize(crypto_aead_reqtfm(areq)); - cryp->total_in = areq->assoclen + areq->cryptlen; + cryp->total_in = ALIGN(areq->assoclen, sizeof(u32)) + + areq->cryptlen; if (is_encrypt(cryp)) /* Append auth tag to output */ - cryp->total_out = cryp->total_in + cryp->authsize; + cryp->total_out = areq->assoclen + areq->cryptlen + + cryp->authsize; else /* No auth tag in output */ - cryp->total_out = cryp->total_in - cryp->authsize; + cryp->total_out = areq->assoclen + areq->cryptlen + - cryp->authsize; } - cryp->total_in_save = cryp->total_in; - cryp->total_out_save = cryp->total_out; + cryp->remain_in = cryp->total_in; + cryp->remain_out = cryp->total_out; cryp->in_sg = req ? req->src : areq->src; cryp->out_sg = req ? req->dst : areq->dst; cryp->out_sg_save = cryp->out_sg; - cryp->in_sg_len = sg_nents_for_len(cryp->in_sg, cryp->total_in); - if (cryp->in_sg_len < 0) { - dev_err(cryp->dev, "Cannot get in_sg_len\n"); - ret = cryp->in_sg_len; - return ret; - } - - cryp->out_sg_len = sg_nents_for_len(cryp->out_sg, cryp->total_out); - if (cryp->out_sg_len < 0) { - dev_err(cryp->dev, "Cannot get out_sg_len\n"); - ret = cryp->out_sg_len; - return ret; - } - ret = stm32_cryp_copy_sgs(cryp); if (ret) return ret; @@ -1011,7 +1135,7 @@ static int stm32_cryp_prepare_req(struct skcipher_request *req, if (is_gcm(cryp) || is_ccm(cryp)) { /* In output, jump after assoc data */ scatterwalk_advance(&cryp->out_walk, cryp->areq->assoclen); - cryp->total_out -= cryp->areq->assoclen; + cryp->remain_out -= cryp->areq->assoclen; } ret = stm32_cryp_hw_init(cryp); @@ -1130,7 +1254,7 @@ static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp) stm32_cryp_write(cryp, CRYP_DIN, size_bit); size_bit = is_encrypt(cryp) ? cryp->areq->cryptlen : - cryp->areq->cryptlen - AES_BLOCK_SIZE; + cryp->areq->cryptlen - cryp->authsize; size_bit *= 8; if (cryp->caps->swap_final) size_bit = (__force u32)cpu_to_be32(size_bit); @@ -1169,14 +1293,14 @@ static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp) dst = sg_virt(cryp->out_sg) + _walked_out; for (i = 0; i < AES_BLOCK_32; i++) { - if (cryp->total_out >= sizeof(u32)) { + if (cryp->remain_out >= sizeof(u32)) { /* Read a full u32 */ *dst = stm32_cryp_read(cryp, CRYP_DOUT); dst = stm32_cryp_next_out(cryp, dst, sizeof(u32)); - cryp->total_out -= sizeof(u32); - } else if (!cryp->total_out) { + cryp->remain_out -= sizeof(u32); + } else if (!cryp->remain_out) { /* Empty fifo out (data from input padding) */ stm32_cryp_read(cryp, CRYP_DOUT); } else { @@ -1184,11 +1308,11 @@ static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp) d32 = stm32_cryp_read(cryp, CRYP_DOUT); d8 = (u8 *)&d32; - for (j = 0; j < cryp->total_out; j++) { + for (j = 0; j < cryp->remain_out; j++) { *((u8 *)dst) = *(d8++); dst = stm32_cryp_next_out(cryp, dst, 1); } - cryp->total_out = 0; + cryp->remain_out = 0; } } } else { @@ -1196,7 +1320,7 @@ static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp) u32 in_tag[AES_BLOCK_32], out_tag[AES_BLOCK_32]; scatterwalk_map_and_copy(in_tag, cryp->in_sg, - cryp->total_in_save - cryp->authsize, + cryp->total_in - cryp->authsize, cryp->authsize, 0); for (i = 0; i < AES_BLOCK_32; i++) @@ -1256,13 +1380,13 @@ static bool stm32_cryp_irq_read_data(struct stm32_cryp *cryp) dst = sg_virt(cryp->out_sg) + _walked_out; for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) { - if (likely(cryp->total_out - tag_size >= sizeof(u32))) { + if (likely(cryp->remain_out - tag_size >= sizeof(u32))) { /* Read a full u32 */ *dst = stm32_cryp_read(cryp, CRYP_DOUT); dst = stm32_cryp_next_out(cryp, dst, sizeof(u32)); - cryp->total_out -= sizeof(u32); - } else if (cryp->total_out == tag_size) { + cryp->remain_out -= sizeof(u32); + } else if (cryp->remain_out == tag_size) { /* Empty fifo out (data from input padding) */ d32 = stm32_cryp_read(cryp, CRYP_DOUT); } else { @@ -1270,15 +1394,15 @@ static bool stm32_cryp_irq_read_data(struct stm32_cryp *cryp) d32 = stm32_cryp_read(cryp, CRYP_DOUT); d8 = (u8 *)&d32; - for (j = 0; j < cryp->total_out - tag_size; j++) { + for (j = 0; j < cryp->remain_out - tag_size; j++) { *((u8 *)dst) = *(d8++); dst = stm32_cryp_next_out(cryp, dst, 1); } - cryp->total_out = tag_size; + cryp->remain_out = tag_size; } } - return !(cryp->total_out - tag_size) || !cryp->total_in; + return !(cryp->remain_out - tag_size) || !cryp->remain_in; } static void stm32_cryp_irq_write_block(struct stm32_cryp *cryp) @@ -1297,25 +1421,25 @@ static void stm32_cryp_irq_write_block(struct stm32_cryp *cryp) src = sg_virt(cryp->in_sg) + _walked_in; for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) { - if (likely(cryp->total_in - tag_size >= sizeof(u32))) { + if (likely(cryp->remain_in - tag_size >= sizeof(u32))) { /* Write a full u32 */ stm32_cryp_write(cryp, CRYP_DIN, *src); src = stm32_cryp_next_in(cryp, src, sizeof(u32)); - cryp->total_in -= sizeof(u32); - } else if (cryp->total_in == tag_size) { + cryp->remain_in -= sizeof(u32); + } else if (cryp->remain_in == tag_size) { /* Write padding data */ stm32_cryp_write(cryp, CRYP_DIN, 0); } else { /* Write less than an u32 */ memset(d8, 0, sizeof(u32)); - for (j = 0; j < cryp->total_in - tag_size; j++) { + for (j = 0; j < cryp->remain_in - tag_size; j++) { d8[j] = *((u8 *)src); src = stm32_cryp_next_in(cryp, src, 1); } stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); - cryp->total_in = tag_size; + cryp->remain_in = tag_size; } } } @@ -1324,7 +1448,7 @@ static void stm32_cryp_irq_write_gcm_padded_data(struct stm32_cryp *cryp) { int err; u32 cfg, tmp[AES_BLOCK_32]; - size_t total_in_ori = cryp->total_in; + size_t remain_in_ori = cryp->remain_in; struct scatterlist *out_sg_ori = cryp->out_sg; unsigned int i; @@ -1350,7 +1474,7 @@ static void stm32_cryp_irq_write_gcm_padded_data(struct stm32_cryp *cryp) /* b) pad and write the last block */ stm32_cryp_irq_write_block(cryp); - cryp->total_in = total_in_ori; + cryp->remain_in = remain_in_ori; err = stm32_cryp_wait_output(cryp); if (err) { dev_err(cryp->dev, "Timeout (write gcm header)\n"); @@ -1360,8 +1484,8 @@ static void stm32_cryp_irq_write_gcm_padded_data(struct stm32_cryp *cryp) /* c) get and store encrypted data */ stm32_cryp_irq_read_data(cryp); scatterwalk_map_and_copy(tmp, out_sg_ori, - cryp->total_in_save - total_in_ori, - total_in_ori, 0); + cryp->total_in - remain_in_ori, + remain_in_ori, 0); /* d) change mode back to AES GCM */ cfg &= ~CR_ALGO_MASK; @@ -1375,12 +1499,12 @@ static void stm32_cryp_irq_write_gcm_padded_data(struct stm32_cryp *cryp) /* f) write padded data */ for (i = 0; i < AES_BLOCK_32; i++) { - if (cryp->total_in) + if (cryp->remain_in) stm32_cryp_write(cryp, CRYP_DIN, tmp[i]); else stm32_cryp_write(cryp, CRYP_DIN, 0); - cryp->total_in -= min_t(size_t, sizeof(u32), cryp->total_in); + cryp->remain_in -= min_t(size_t, sizeof(u32), cryp->remain_in); } /* g) Empty fifo out */ @@ -1406,8 +1530,8 @@ static void stm32_cryp_irq_set_npblb(struct stm32_cryp *cryp) cfg &= ~CR_CRYPEN; stm32_cryp_write(cryp, CRYP_CR, cfg); - payload_bytes = is_decrypt(cryp) ? cryp->total_in - cryp->authsize : - cryp->total_in; + payload_bytes = is_decrypt(cryp) ? cryp->remain_in - cryp->authsize : + cryp->remain_in; cfg |= (cryp->hw_blocksize - payload_bytes) << CR_NBPBL_SHIFT; cfg |= CR_CRYPEN; stm32_cryp_write(cryp, CRYP_CR, cfg); @@ -1418,7 +1542,7 @@ static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp) int err = 0; u32 cfg, iv1tmp; u32 cstmp1[AES_BLOCK_32], cstmp2[AES_BLOCK_32], tmp[AES_BLOCK_32]; - size_t last_total_out, total_in_ori = cryp->total_in; + size_t last_remain_out, remain_in_ori = cryp->remain_in; struct scatterlist *out_sg_ori = cryp->out_sg; unsigned int i; @@ -1453,7 +1577,7 @@ static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp) /* b) pad and write the last block */ stm32_cryp_irq_write_block(cryp); - cryp->total_in = total_in_ori; + cryp->remain_in = remain_in_ori; err = stm32_cryp_wait_output(cryp); if (err) { dev_err(cryp->dev, "Timeout (wite ccm padded data)\n"); @@ -1461,13 +1585,13 @@ static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp) } /* c) get and store decrypted data */ - last_total_out = cryp->total_out; + last_remain_out = cryp->remain_out; stm32_cryp_irq_read_data(cryp); memset(tmp, 0, sizeof(tmp)); scatterwalk_map_and_copy(tmp, out_sg_ori, - cryp->total_out_save - last_total_out, - last_total_out, 0); + cryp->total_out - last_remain_out, + last_remain_out, 0); /* d) Load again CRYP_CSGCMCCMxR */ for (i = 0; i < ARRAY_SIZE(cstmp2); i++) @@ -1501,12 +1625,12 @@ static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp) static void stm32_cryp_irq_write_data(struct stm32_cryp *cryp) { - if (unlikely(!cryp->total_in)) { + if (unlikely(!cryp->remain_in)) { dev_warn(cryp->dev, "No more data to process\n"); return; } - if (unlikely(cryp->total_in < AES_BLOCK_SIZE && + if (unlikely(cryp->remain_in < AES_BLOCK_SIZE && (stm32_cryp_get_hw_mode(cryp) == CR_AES_GCM) && is_encrypt(cryp))) { /* Padding for AES GCM encryption */ @@ -1518,7 +1642,7 @@ static void stm32_cryp_irq_write_data(struct stm32_cryp *cryp) stm32_cryp_irq_set_npblb(cryp); } - if (unlikely((cryp->total_in - cryp->authsize < AES_BLOCK_SIZE) && + if (unlikely((cryp->remain_in - cryp->authsize < AES_BLOCK_SIZE) && (stm32_cryp_get_hw_mode(cryp) == CR_AES_CCM) && is_decrypt(cryp))) { /* Padding for AES CCM decryption */ @@ -1548,10 +1672,10 @@ static void stm32_cryp_irq_write_gcm_header(struct stm32_cryp *cryp) stm32_cryp_write(cryp, CRYP_DIN, *src); src = stm32_cryp_next_in(cryp, src, sizeof(u32)); - cryp->total_in -= min_t(size_t, sizeof(u32), cryp->total_in); + cryp->remain_in -= min_t(size_t, sizeof(u32), cryp->remain_in); /* Check if whole header written */ - if ((cryp->total_in_save - cryp->total_in) == + if ((cryp->total_in - cryp->remain_in) >= cryp->areq->assoclen) { /* Write padding if needed */ for (j = i + 1; j < AES_BLOCK_32; j++) @@ -1583,7 +1707,7 @@ static void stm32_cryp_irq_write_gcm_header(struct stm32_cryp *cryp) break; } - if (!cryp->total_in) + if (!cryp->remain_in) break; } } @@ -1611,7 +1735,7 @@ static void stm32_cryp_irq_write_ccm_header(struct stm32_cryp *cryp) stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); i++; - cryp->total_in -= min_t(size_t, 2, cryp->total_in); + cryp->remain_in -= min_t(size_t, 2, cryp->remain_in); } else { /* Build the two first u32 of B1 */ d8[0] = 0xFF; @@ -1632,7 +1756,7 @@ static void stm32_cryp_irq_write_ccm_header(struct stm32_cryp *cryp) stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); i++; - cryp->total_in -= min_t(size_t, 2, cryp->total_in); + cryp->remain_in -= min_t(size_t, 2, cryp->remain_in); } } @@ -1644,14 +1768,14 @@ static void stm32_cryp_irq_write_ccm_header(struct stm32_cryp *cryp) d8[k] = *((u8 *)src); src = stm32_cryp_next_in(cryp, src, 1); - cryp->total_in -= min_t(size_t, 1, cryp->total_in); - if ((cryp->total_in_save - cryp->total_in) == alen) + cryp->remain_in -= min_t(size_t, 1, cryp->remain_in); + if ((cryp->total_in - cryp->remain_in) == alen) break; } stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); - if ((cryp->total_in_save - cryp->total_in) == alen) { + if ((cryp->total_in - cryp->remain_in) == alen) { /* Write padding if needed */ for (j = i + 1; j < AES_BLOCK_32; j++) stm32_cryp_write(cryp, CRYP_DIN, 0); @@ -1955,7 +2079,9 @@ static int stm32_cryp_probe(struct platform_device *pdev) cryp->clk = devm_clk_get(dev, NULL); if (IS_ERR(cryp->clk)) { - dev_err(dev, "Could not get clock\n"); + if (PTR_ERR(cryp->clk) != -EPROBE_DEFER) + dev_err(dev, "Could not get clock\n"); + return PTR_ERR(cryp->clk); } @@ -1973,7 +2099,11 @@ static int stm32_cryp_probe(struct platform_device *pdev) pm_runtime_enable(dev); rst = devm_reset_control_get(dev, NULL); - if (!IS_ERR(rst)) { + if (IS_ERR(rst)) { + ret = PTR_ERR(rst); + if (ret == -EPROBE_DEFER) + goto err_rst; + } else { reset_control_assert(rst); udelay(2); reset_control_deassert(rst); @@ -2024,7 +2154,7 @@ static int stm32_cryp_probe(struct platform_device *pdev) spin_lock(&cryp_list.lock); list_del(&cryp->list); spin_unlock(&cryp_list.lock); - +err_rst: pm_runtime_disable(dev); pm_runtime_put_noidle(dev); pm_runtime_disable(dev); diff --git a/drivers/crypto/stm32/stm32-hash.c b/drivers/crypto/stm32/stm32-hash.c index e3e25278a970..da9c3e913e55 100644 --- a/drivers/crypto/stm32/stm32-hash.c +++ b/drivers/crypto/stm32/stm32-hash.c @@ -925,15 +925,10 @@ static int stm32_hash_final(struct ahash_request *req) static int stm32_hash_finup(struct ahash_request *req) { struct stm32_hash_request_ctx *rctx = ahash_request_ctx(req); - struct stm32_hash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); - struct stm32_hash_dev *hdev = stm32_hash_find_dev(ctx); int err1, err2; rctx->flags |= HASH_FLAGS_FINUP; - if (hdev->dma_lch && stm32_hash_dma_aligned_data(req)) - rctx->flags &= ~HASH_FLAGS_CPU; - err1 = stm32_hash_update(req); if (err1 == -EINPROGRESS || err1 == -EBUSY) @@ -950,7 +945,19 @@ static int stm32_hash_finup(struct ahash_request *req) static int stm32_hash_digest(struct ahash_request *req) { - return stm32_hash_init(req) ?: stm32_hash_finup(req); + int ret; + struct stm32_hash_request_ctx *rctx = ahash_request_ctx(req); + struct stm32_hash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); + struct stm32_hash_dev *hdev = stm32_hash_find_dev(ctx); + + ret = stm32_hash_init(req); + if (ret) + return ret; + + if (hdev->dma_lch && stm32_hash_dma_aligned_data(req)) + rctx->flags &= ~HASH_FLAGS_CPU; + + return stm32_hash_finup(req); } static int stm32_hash_export(struct ahash_request *req, void *out) -- 2.17.1