From: Fabio Estevam <fabio.estevam@xxxxxxx> imx6ul and imx7 report the following error: caam_jr 2142000.jr1: 40000789: DECO: desc idx 7: Protocol Size Error - A protocol has seen an error in size. When running RSA, pdb size N < (size of F) when no formatting is used; or pdb size N < (F + 11) when formatting is used. ------------[ cut here ]------------ WARNING: CPU: 0 PID: 1 at crypto/asymmetric_keys/public_key.c:148 public_key_verify_signature+0x27c/0x2b0 This error happens because the signature contains 257 bytes, including a leading zero as the first element. Fix the problem by stripping off the leading zero from input data before feeding it to the CAAM accelerator. Fixes: 8c419778ab57e497b5 ("crypto: caam - add support for RSA algorithm") Cc: <stable@xxxxxxxxxxxxxxx> Reported-by: Martin Townsend <mtownsend1973@xxxxxxxxx> Signed-off-by: Fabio Estevam <fabio.estevam@xxxxxxx> --- Changes since v1: - Use a temp pointer - Assign len to req->src_len , so that more than one leading zero can be taken into account drivers/crypto/caam/caampkc.c | 45 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/drivers/crypto/caam/caampkc.c b/drivers/crypto/caam/caampkc.c index 7a897209..5f3e627 100644 --- a/drivers/crypto/caam/caampkc.c +++ b/drivers/crypto/caam/caampkc.c @@ -166,6 +166,14 @@ static void rsa_priv_f3_done(struct device *dev, u32 *desc, u32 err, akcipher_request_complete(req, err); } +static void caam_rsa_drop_leading_zeros(const u8 **ptr, size_t *nbytes) +{ + while (!**ptr && *nbytes) { + (*ptr)++; + (*nbytes)--; + } +} + static struct rsa_edesc *rsa_edesc_alloc(struct akcipher_request *req, size_t desclen) { @@ -178,7 +186,36 @@ static struct rsa_edesc *rsa_edesc_alloc(struct akcipher_request *req, int sgc; int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes; int src_nents, dst_nents; + const u8 *temp; + void *buffer; + size_t len; + + buffer = kzalloc(req->src_len, GFP_ATOMIC); + if (!buffer) + return ERR_PTR(-ENOMEM); + + sg_copy_to_buffer(req->src, sg_nents(req->src), + buffer, req->src_len); + temp = (u8 *)buffer; + len = req->src_len; + /* + * Check if the buffer contains leading zeros and if + * it does, drop the leading zeros + */ + if (temp[0] == 0) { + caam_rsa_drop_leading_zeros(&temp, &len); + if (!temp) { + kfree(buffer); + return ERR_PTR(-ENOMEM); + } + + req->src_len = len; + sg_copy_from_buffer(req->src, sg_nents(req->src), + (void *)temp, req->src_len); + } + + kfree(buffer); src_nents = sg_nents_for_len(req->src, req->src_len); dst_nents = sg_nents_for_len(req->dst, req->dst_len); @@ -683,14 +720,6 @@ static void caam_rsa_free_key(struct caam_rsa_key *key) memset(key, 0, sizeof(*key)); } -static void caam_rsa_drop_leading_zeros(const u8 **ptr, size_t *nbytes) -{ - while (!**ptr && *nbytes) { - (*ptr)++; - (*nbytes)--; - } -} - /** * caam_read_rsa_crt - Used for reading dP, dQ, qInv CRT members. * dP, dQ and qInv could decode to less than corresponding p, q length, as the -- 2.7.4