@@ -103,16 +103,25 @@ int qcrypto_gcrypt_hash_finalize(QCryptoHash *hash,
size_t *result_len,
Error **errp)
{
+ int ret;
unsigned char *digest;
gcry_md_hd_t *ctx = hash->opaque;
- *result_len = gcry_md_get_algo_dlen(qcrypto_hash_alg_map[hash->alg]);
- if (*result_len == 0) {
+ ret = gcry_md_get_algo_dlen(qcrypto_hash_alg_map[hash->alg]);
+ if (ret == 0) {
error_setg(errp, "Unable to get hash length");
return -1;
}
- *result = g_new(uint8_t, *result_len);
+ if (*result_len == 0) {
+ *result_len = ret;
+ *result = g_new(uint8_t, *result_len);
+ } else if (*result_len != ret) {
+ error_setg(errp,
+ "Result buffer size %zu is smaller than hash %d",
+ *result_len, ret);
+ return -1;
+ }
/* Digest is freed by gcry_md_close(), copy it */
digest = gcry_md_read(*ctx, 0);
@@ -99,8 +99,15 @@ int qcrypto_glib_hash_finalize(QCryptoHash *hash,
return -1;
}
- *result_len = ret;
- *result = g_new(uint8_t, *result_len);
+ if (*result_len == 0) {
+ *result_len = ret;
+ *result = g_new(uint8_t, *result_len);
+ } else if (*result_len != ret) {
+ error_setg(errp,
+ "Result buffer size %zu is smaller than hash %d",
+ *result_len, ret);
+ return -1;
+ }
g_checksum_get_digest(ctx, *result, result_len);
return 0;
@@ -115,14 +115,24 @@ int qcrypto_gnutls_hash_finalize(QCryptoHash *hash,
Error **errp)
{
gnutls_hash_hd_t *ctx = hash->opaque;
+ int ret;
- *result_len = gnutls_hash_get_len(qcrypto_hash_alg_map[hash->alg]);
- if (*result_len == 0) {
+ ret = gnutls_hash_get_len(qcrypto_hash_alg_map[hash->alg]);
+ if (ret == 0) {
error_setg(errp, "Unable to get hash length");
return -1;
}
- *result = g_new(uint8_t, *result_len);
+ if (*result_len == 0) {
+ *result_len = ret;
+ *result = g_new(uint8_t, *result_len);
+ } else if (*result_len != ret) {
+ error_setg(errp,
+ "Result buffer size %zu is smaller than hash %d",
+ *result_len, ret);
+ return -1;
+ }
+
gnutls_hash_output(*ctx, *result);
return 0;
}
@@ -150,9 +150,17 @@ int qcrypto_nettle_hash_finalize(QCryptoHash *hash,
Error **errp)
{
union qcrypto_hash_ctx *ctx = hash->opaque;
-
- *result_len = qcrypto_hash_alg_map[hash->alg].len;
- *result = g_new(uint8_t, *result_len);
+ int ret = qcrypto_hash_alg_map[hash->alg].len;
+
+ if (*result_len == 0) {
+ *result_len = ret;
+ *result = g_new(uint8_t, *result_len);
+ } else if (*result_len != ret) {
+ error_setg(errp,
+ "Result buffer size %zu is smaller than hash %d",
+ *result_len, ret);
+ return -1;
+ }
qcrypto_hash_alg_map[hash->alg].result(ctx, *result_len, *result);
If the user provides a pre-allocated buffer for the hash result, we must use that rather than re-allocating a new buffer. Reported-by: Dorjoy Chowdhury <dorjoychy111@gmail.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- crypto/hash-gcrypt.c | 15 ++++++++++++--- crypto/hash-glib.c | 11 +++++++++-- crypto/hash-gnutls.c | 16 +++++++++++++--- crypto/hash-nettle.c | 14 +++++++++++--- 4 files changed, 45 insertions(+), 11 deletions(-)