summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2023-06-26 12:33:44 +0200
committerHerbert Xu <herbert@gondor.apana.org.au>2023-06-27 09:40:24 +0200
commit891ebfdfa3d08bf55ebec523c99bb68ac9c34cf7 (patch)
tree8f660671f3ce35b37a746dd3a624273b503389fa
parentcrypto: akcipher - Set request tfm on sync path (diff)
downloadlinux-891ebfdfa3d08bf55ebec523c99bb68ac9c34cf7.tar.xz
linux-891ebfdfa3d08bf55ebec523c99bb68ac9c34cf7.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: 6cb8815f41a9 ("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 8ffd31c44cf6..e9b6ddcdf124 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 e3cf5a658d51..63e59240d5fb 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 d812555c88af..b48c18ec65cd 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));