Skip to content

Commit

Permalink
crypto: rsa-pkcs1pad - Handle leading zero for decryption
Browse files Browse the repository at this point in the history
As the software RSA implementation now produces fixed-length
output, we need to eliminate leading zeros in the calling code
instead.

This patch does just that for pkcs1pad decryption while signature
verification was fixed in an earlier patch.

Fixes: 9b45b7b ("crypto: rsa - Generate fixed-length output")
Reported-by: Mat Martineau <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
  • Loading branch information
herbertx committed Sep 22, 2016
1 parent 456bee9 commit 0cf43f5
Showing 1 changed file with 24 additions and 17 deletions.
41 changes: 24 additions & 17 deletions crypto/rsa-pkcs1pad.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,41 +298,48 @@ static int pkcs1pad_decrypt_complete(struct akcipher_request *req, int err)
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
unsigned int dst_len;
unsigned int pos;

if (err == -EOVERFLOW)
/* Decrypted value had no leading 0 byte */
err = -EINVAL;
u8 *out_buf;

if (err)
goto done;

if (req_ctx->child_req.dst_len != ctx->key_size - 1) {
err = -EINVAL;
err = -EINVAL;
dst_len = req_ctx->child_req.dst_len;
if (dst_len < ctx->key_size - 1)
goto done;

out_buf = req_ctx->out_buf;
if (dst_len == ctx->key_size) {
if (out_buf[0] != 0x00)
/* Decrypted value had no leading 0 byte */
goto done;

dst_len--;
out_buf++;
}

if (req_ctx->out_buf[0] != 0x02) {
err = -EINVAL;
if (out_buf[0] != 0x02)
goto done;
}
for (pos = 1; pos < req_ctx->child_req.dst_len; pos++)
if (req_ctx->out_buf[pos] == 0x00)

for (pos = 1; pos < dst_len; pos++)
if (out_buf[pos] == 0x00)
break;
if (pos < 9 || pos == req_ctx->child_req.dst_len) {
err = -EINVAL;
if (pos < 9 || pos == dst_len)
goto done;
}
pos++;

if (req->dst_len < req_ctx->child_req.dst_len - pos)
err = 0;

if (req->dst_len < dst_len - pos)
err = -EOVERFLOW;
req->dst_len = req_ctx->child_req.dst_len - pos;
req->dst_len = dst_len - pos;

if (!err)
sg_copy_from_buffer(req->dst,
sg_nents_for_len(req->dst, req->dst_len),
req_ctx->out_buf + pos, req->dst_len);
out_buf + pos, req->dst_len);

done:
kzfree(req_ctx->out_buf);
Expand Down

0 comments on commit 0cf43f5

Please sign in to comment.