Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 21 additions & 17 deletions crypto/asymmetric_keys/public_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,9 +380,10 @@ int public_key_verify_signature(const struct public_key *pkey,
struct crypto_wait cwait;
struct crypto_akcipher *tfm;
struct akcipher_request *req;
struct scatterlist src_sg[2];
struct scatterlist src_sg;
char alg_name[CRYPTO_MAX_ALG_NAME];
char *key, *ptr;
char *buf, *ptr;
size_t buf_len;
int ret;

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

key = kmalloc(pkey->keylen + sizeof(u32) * 2 + pkey->paramlen,
GFP_KERNEL);
if (!key)
buf_len = max_t(size_t, pkey->keylen + sizeof(u32) * 2 + pkey->paramlen,
sig->s_size + sig->digest_size);

buf = kmalloc(buf_len, GFP_KERNEL);
if (!buf)
goto error_free_req;

memcpy(key, pkey->key, pkey->keylen);
ptr = key + pkey->keylen;
memcpy(buf, pkey->key, pkey->keylen);
ptr = buf + pkey->keylen;
ptr = pkey_pack_u32(ptr, pkey->algo);
ptr = pkey_pack_u32(ptr, pkey->paramlen);
memcpy(ptr, pkey->params, pkey->paramlen);

if (pkey->key_is_private)
ret = crypto_akcipher_set_priv_key(tfm, key, pkey->keylen);
ret = crypto_akcipher_set_priv_key(tfm, buf, pkey->keylen);
else
ret = crypto_akcipher_set_pub_key(tfm, key, pkey->keylen);
ret = crypto_akcipher_set_pub_key(tfm, buf, pkey->keylen);
if (ret)
goto error_free_key;
goto error_free_buf;

if (strcmp(pkey->pkey_algo, "sm2") == 0 && sig->data_size) {
ret = cert_sig_digest_update(sig, tfm);
if (ret)
goto error_free_key;
goto error_free_buf;
}

sg_init_table(src_sg, 2);
sg_set_buf(&src_sg[0], sig->s, sig->s_size);
sg_set_buf(&src_sg[1], sig->digest, sig->digest_size);
akcipher_request_set_crypt(req, src_sg, NULL, sig->s_size,
memcpy(buf, sig->s, sig->s_size);
memcpy(buf + sig->s_size, sig->digest, sig->digest_size);

sg_init_one(&src_sg, buf, sig->s_size + sig->digest_size);
akcipher_request_set_crypt(req, &src_sg, NULL, sig->s_size,
sig->digest_size);
crypto_init_wait(&cwait);
akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
CRYPTO_TFM_REQ_MAY_SLEEP,
crypto_req_done, &cwait);
ret = crypto_wait_req(crypto_akcipher_verify(req), &cwait);

error_free_key:
kfree(key);
error_free_buf:
kfree(buf);
error_free_req:
akcipher_request_free(req);
error_free_tfm:
Expand Down