summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2023-06-26 18:33:44 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2023-06-27 15:40:24 +0800
commit694db3f4cf6a1389046cfa91bc7ea43a0bec064c (patch)
tree4ad4b906db976b148ba37b9af0ae9994a0a3ee36
parent7a5e3222e87b68db93ee5c4c6bd50eae5f6425ca (diff)
downloadlinux-crypto-694db3f4cf6a1389046cfa91bc7ea43a0bec064c.tar.gz
linux-crypto-694db3f4cf6a1389046cfa91bc7ea43a0bec064c.zip
crypto: sig - Fix verify call
The dst SG list needs to be set to NULL for verify calls. Do this as otherwise the underlying algorithm may fail. Furthermore the digest needs to be copied just like the source. Fixes: 3bac7dc3bfd2 ("crypto: sig - Add interface for sign/verify") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/akcipher.c12
-rw-r--r--crypto/internal.h2
-rw-r--r--crypto/sig.c4
3 files changed, 11 insertions, 7 deletions
diff --git a/crypto/akcipher.c b/crypto/akcipher.c
index 8ffd31c4..e9b6ddcd 100644
--- a/crypto/akcipher.c
+++ b/crypto/akcipher.c
@@ -192,12 +192,17 @@ EXPORT_SYMBOL_GPL(akcipher_register_instance);
int crypto_akcipher_sync_prep(struct crypto_akcipher_sync_data *data)
{
unsigned int reqsize = crypto_akcipher_reqsize(data->tfm);
- unsigned int mlen = max(data->slen, data->dlen);
struct akcipher_request *req;
struct scatterlist *sg;
+ unsigned int mlen;
unsigned int len;
u8 *buf;
+ if (data->dst)
+ mlen = max(data->slen, data->dlen);
+ else
+ mlen = data->slen + data->dlen;
+
len = sizeof(*req) + reqsize + mlen;
if (len < mlen)
return -EOVERFLOW;
@@ -213,9 +218,10 @@ int crypto_akcipher_sync_prep(struct crypto_akcipher_sync_data *data)
data->buf = buf;
memcpy(buf, data->src, data->slen);
- sg = data->sg;
+ sg = &data->sg;
sg_init_one(sg, buf, mlen);
- akcipher_request_set_crypt(req, sg, sg, data->slen, data->dlen);
+ akcipher_request_set_crypt(req, sg, data->dst ? sg : NULL,
+ data->slen, data->dlen);
crypto_init_wait(&data->cwait);
akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP,
diff --git a/crypto/internal.h b/crypto/internal.h
index e3cf5a65..63e59240 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -44,7 +44,7 @@ struct crypto_akcipher_sync_data {
struct akcipher_request *req;
struct crypto_wait cwait;
- struct scatterlist sg[2];
+ struct scatterlist sg;
u8 *buf;
};
diff --git a/crypto/sig.c b/crypto/sig.c
index d812555c..b48c18ec 100644
--- a/crypto/sig.c
+++ b/crypto/sig.c
@@ -128,9 +128,7 @@ int crypto_sig_verify(struct crypto_sig *tfm,
if (err)
return err;
- sg_init_table(data.sg, 2);
- sg_set_buf(&data.sg[0], src, slen);
- sg_set_buf(&data.sg[1], digest, dlen);
+ memcpy(data.buf + slen, digest, dlen);
return crypto_akcipher_sync_post(&data,
crypto_akcipher_verify(data.req));