Skip to content

Commit f8dba31

Browse files
committed
Merge tag 'asym-keys-fix-for-linus-v6.4-rc5' of https://github.com/robertosassu/linux
Pull asymmetric keys fix from Roberto Sassu: "Here is a small fix to make an unconditional copy of the buffer passed to crypto operations, to take into account the case of the stack not in the linear mapping area. It has been tested and verified to fix the bug" Acked-by: Herbert Xu <[email protected]> Acked-by: David Howells <[email protected]> * tag 'asym-keys-fix-for-linus-v6.4-rc5' of https://github.com/robertosassu/linux: KEYS: asymmetric: Copy sig and digest in public_key_verify_signature()
2 parents 9561de3 + c3d03e8 commit f8dba31

File tree

1 file changed

+21
-17
lines changed

1 file changed

+21
-17
lines changed

crypto/asymmetric_keys/public_key.c

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -380,9 +380,10 @@ int public_key_verify_signature(const struct public_key *pkey,
380380
struct crypto_wait cwait;
381381
struct crypto_akcipher *tfm;
382382
struct akcipher_request *req;
383-
struct scatterlist src_sg[2];
383+
struct scatterlist src_sg;
384384
char alg_name[CRYPTO_MAX_ALG_NAME];
385-
char *key, *ptr;
385+
char *buf, *ptr;
386+
size_t buf_len;
386387
int ret;
387388

388389
pr_devel("==>%s()\n", __func__);
@@ -420,43 +421,46 @@ int public_key_verify_signature(const struct public_key *pkey,
420421
if (!req)
421422
goto error_free_tfm;
422423

423-
key = kmalloc(pkey->keylen + sizeof(u32) * 2 + pkey->paramlen,
424-
GFP_KERNEL);
425-
if (!key)
424+
buf_len = max_t(size_t, pkey->keylen + sizeof(u32) * 2 + pkey->paramlen,
425+
sig->s_size + sig->digest_size);
426+
427+
buf = kmalloc(buf_len, GFP_KERNEL);
428+
if (!buf)
426429
goto error_free_req;
427430

428-
memcpy(key, pkey->key, pkey->keylen);
429-
ptr = key + pkey->keylen;
431+
memcpy(buf, pkey->key, pkey->keylen);
432+
ptr = buf + pkey->keylen;
430433
ptr = pkey_pack_u32(ptr, pkey->algo);
431434
ptr = pkey_pack_u32(ptr, pkey->paramlen);
432435
memcpy(ptr, pkey->params, pkey->paramlen);
433436

434437
if (pkey->key_is_private)
435-
ret = crypto_akcipher_set_priv_key(tfm, key, pkey->keylen);
438+
ret = crypto_akcipher_set_priv_key(tfm, buf, pkey->keylen);
436439
else
437-
ret = crypto_akcipher_set_pub_key(tfm, key, pkey->keylen);
440+
ret = crypto_akcipher_set_pub_key(tfm, buf, pkey->keylen);
438441
if (ret)
439-
goto error_free_key;
442+
goto error_free_buf;
440443

441444
if (strcmp(pkey->pkey_algo, "sm2") == 0 && sig->data_size) {
442445
ret = cert_sig_digest_update(sig, tfm);
443446
if (ret)
444-
goto error_free_key;
447+
goto error_free_buf;
445448
}
446449

447-
sg_init_table(src_sg, 2);
448-
sg_set_buf(&src_sg[0], sig->s, sig->s_size);
449-
sg_set_buf(&src_sg[1], sig->digest, sig->digest_size);
450-
akcipher_request_set_crypt(req, src_sg, NULL, sig->s_size,
450+
memcpy(buf, sig->s, sig->s_size);
451+
memcpy(buf + sig->s_size, sig->digest, sig->digest_size);
452+
453+
sg_init_one(&src_sg, buf, sig->s_size + sig->digest_size);
454+
akcipher_request_set_crypt(req, &src_sg, NULL, sig->s_size,
451455
sig->digest_size);
452456
crypto_init_wait(&cwait);
453457
akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
454458
CRYPTO_TFM_REQ_MAY_SLEEP,
455459
crypto_req_done, &cwait);
456460
ret = crypto_wait_req(crypto_akcipher_verify(req), &cwait);
457461

458-
error_free_key:
459-
kfree(key);
462+
error_free_buf:
463+
kfree(buf);
460464
error_free_req:
461465
akcipher_request_free(req);
462466
error_free_tfm:

0 commit comments

Comments
 (0)