* [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations
@ 2024-08-05 15:50 Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 01/12] crypto: accumulative hashing API Alejandro Zeise
` (12 more replies)
0 siblings, 13 replies; 16+ messages in thread
From: Alejandro Zeise @ 2024-08-05 15:50 UTC (permalink / raw)
To: qemu-arm
Cc: alejandro.zeise, kris.conklin, jonathan.henze, evan.burgess, clg,
peter.maydell, berrange, qemu-devel
The goal of this patch series is to fix accumulative hashing support in the
Aspeed HACE module. The issue that stemmed this patch was a failure to boot an
OpenBMC image using the "ast2600-evb" machine. The U-boot
2019.04 loader failed to verify image hashes.
These incorrect image hashes given by the HACE to the U-boot guest are due to
an oversight in the HACE module. Previously when operating in
scatter-gather accumulative mode, the HACE would cache the address provided by
the guest which contained the source data. However, there was no deep copy,
so when HACE generated the digest upon the reception of the final accumulative chunk
the digest was incorrect, as the addresses provided had their regions overwritten
by that time.
This fix consists of two main steps:
* Add an accumulative hashing function to the qcrypto library
* Modify the HACE module to use the accumulative hashing functions
All the crypto library backends (nettle, gnutls, etc.) support accumulative hashing,
so it was trivial to create wrappers for those functions.
Changes in V3:
* Reworked crypto hash API with comments from Daniel
* Creation/Deletion of contexts, updating, and finalizing
* Modified existing API functions to use the new 4 main core functions
* Added test for accumulative hashing
* Added afalg driver implementation
* Fixed bug in HACE module where hash context fails to allocate,
causing the HACE internal state to be incorrect and segfault.
Changes in V2:
* Fixed error checking bug in libgcrypt crypto backend of
accumulate_bytesv
Alejandro Zeise (12):
crypto: accumulative hashing API
crypto/hash-glib: Remove old hash API implementation
crypto/hash-glib: Implement new hash API
crypto/hash-gcrypt: Remove old hash API implementation
crypto/hash-gcrypt: Implement new hash API
crypto/hash-gnutls: Remove old hash API
crypto/hash-gnutls: Implement new hash API
crypto/hash-nettle: Remove old hash API
crypto/hash-nettle: Implement new hash API
crypto/hash-afalg: Update to new API
tests/unit/test-crypto-hash: accumulative hashing
hw/misc/aspeed_hace: Fix SG Accumulative hashing
crypto/hash-afalg.c | 154 +++++++++++++++++++++++-----------
crypto/hash-gcrypt.c | 112 ++++++++++++++-----------
crypto/hash-glib.c | 96 +++++++++++++--------
crypto/hash-gnutls.c | 94 ++++++++++++++-------
crypto/hash-nettle.c | 79 +++++++++++------
crypto/hash.c | 136 ++++++++++++++++++++++--------
crypto/hashpriv.h | 19 +++--
hw/misc/aspeed_hace.c | 92 ++++++++++----------
include/crypto/hash.h | 106 +++++++++++++++++++++++
include/hw/misc/aspeed_hace.h | 4 +
tests/unit/test-crypto-hash.c | 50 +++++++++++
11 files changed, 667 insertions(+), 275 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v3 01/12] crypto: accumulative hashing API
2024-08-05 15:50 [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations Alejandro Zeise
@ 2024-08-05 15:50 ` Alejandro Zeise
2024-08-06 15:45 ` Daniel P. Berrangé
2024-08-05 15:50 ` [PATCH v3 02/12] crypto/hash-glib: Remove old hash API implementation Alejandro Zeise
` (11 subsequent siblings)
12 siblings, 1 reply; 16+ messages in thread
From: Alejandro Zeise @ 2024-08-05 15:50 UTC (permalink / raw)
To: qemu-arm
Cc: alejandro.zeise, kris.conklin, jonathan.henze, evan.burgess, clg,
peter.maydell, berrange, qemu-devel
Changes the hash API to support accumulative hashing.
Hash objects are created with "qcrypto_hash_new",
updated with data with "qcrypto_hash_update", and
the hash obtained with "qcrypto_hash_finalize".
These changes bring the hashing API more in line with the
hmac API.
Signed-off-by: Alejandro Zeise <alejandro.zeise@seagate.com>
---
crypto/hash.c | 136 +++++++++++++++++++++++++++++++-----------
crypto/hashpriv.h | 19 ++++--
include/crypto/hash.h | 106 ++++++++++++++++++++++++++++++++
3 files changed, 220 insertions(+), 41 deletions(-)
diff --git a/crypto/hash.c b/crypto/hash.c
index b0f8228bdc..5c60973bde 100644
--- a/crypto/hash.c
+++ b/crypto/hash.c
@@ -1,6 +1,7 @@
/*
* QEMU Crypto hash algorithms
*
+ * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates
* Copyright (c) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -45,23 +46,20 @@ int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
size_t *resultlen,
Error **errp)
{
-#ifdef CONFIG_AF_ALG
- int ret;
- /*
- * TODO:
- * Maybe we should treat some afalg errors as fatal
- */
- ret = qcrypto_hash_afalg_driver.hash_bytesv(alg, iov, niov,
- result, resultlen,
- NULL);
- if (ret == 0) {
- return ret;
+ int fail;
+ QCryptoHash *ctx = qcrypto_hash_new(alg, errp);
+
+ if (ctx) {
+ fail = qcrypto_hash_update(ctx, iov, niov, errp) ||
+ qcrypto_hash_finalize_bytes(ctx, result, resultlen, errp);
+
+ /* Ensure context is always freed regardless of error */
+ fail = qcrypto_hash_free(ctx) || fail;
+ } else {
+ fail = -1;
}
-#endif
- return qcrypto_hash_lib_driver.hash_bytesv(alg, iov, niov,
- result, resultlen,
- errp);
+ return fail;
}
@@ -77,30 +75,94 @@ int qcrypto_hash_bytes(QCryptoHashAlgorithm alg,
return qcrypto_hash_bytesv(alg, &iov, 1, result, resultlen, errp);
}
+int qcrypto_hash_update(QCryptoHash *hash,
+ const struct iovec *iov,
+ size_t niov,
+ Error **errp)
+{
+ return qcrypto_hash_lib_driver.hash_update(hash, iov, niov, errp);
+}
+
+QCryptoHash *qcrypto_hash_new(QCryptoHashAlgorithm alg, Error **errp)
+{
+ return qcrypto_hash_lib_driver.hash_new(alg, errp);
+}
+
+int qcrypto_hash_free(QCryptoHash *hash)
+{
+ return qcrypto_hash_lib_driver.hash_free(hash);
+}
+
+int qcrypto_hash_finalize_bytes(QCryptoHash *hash,
+ uint8_t **result,
+ size_t *result_len,
+ Error **errp)
+{
+ return qcrypto_hash_lib_driver.hash_finalize(hash, result, result_len, errp);
+}
+
static const char hex[] = "0123456789abcdef";
+int qcrypto_hash_finalize_digest(QCryptoHash *hash,
+ char **digest,
+ Error **errp)
+{
+ int ret;
+ uint8_t *result = NULL;
+ size_t resultlen = 0;
+ size_t i;
+
+ ret = qcrypto_hash_finalize_bytes(hash, &result, &resultlen, errp);
+ if (ret == 0) {
+ *digest = g_new0(char, (resultlen * 2) + 1);
+ for (i = 0 ; i < resultlen ; i++) {
+ (*digest)[(i * 2)] = hex[(result[i] >> 4) & 0xf];
+ (*digest)[(i * 2) + 1] = hex[result[i] & 0xf];
+ }
+ (*digest)[resultlen * 2] = '\0';
+ g_free(result);
+ }
+
+ return ret;
+}
+
+int qcrypto_hash_finalize_base64(QCryptoHash *hash,
+ char **base64,
+ Error **errp)
+{
+ int ret;
+ uint8_t *result = NULL;
+ size_t resultlen = 0;
+
+ ret = qcrypto_hash_finalize_bytes(hash, &result, &resultlen, errp);
+ if (ret == 0) {
+ *base64 = g_base64_encode(result, resultlen);
+ g_free(result);
+ }
+
+ return ret;
+}
+
int qcrypto_hash_digestv(QCryptoHashAlgorithm alg,
const struct iovec *iov,
size_t niov,
char **digest,
Error **errp)
{
- uint8_t *result = NULL;
- size_t resultlen = 0;
- size_t i;
+ bool fail;
+ QCryptoHash *ctx = qcrypto_hash_new(alg, errp);
- if (qcrypto_hash_bytesv(alg, iov, niov, &result, &resultlen, errp) < 0) {
- return -1;
- }
+ if (ctx) {
+ fail = qcrypto_hash_update(ctx, iov, niov, errp) ||
+ qcrypto_hash_finalize_digest(ctx, digest, errp);
- *digest = g_new0(char, (resultlen * 2) + 1);
- for (i = 0 ; i < resultlen ; i++) {
- (*digest)[(i * 2)] = hex[(result[i] >> 4) & 0xf];
- (*digest)[(i * 2) + 1] = hex[result[i] & 0xf];
+ /* Ensure context is always freed regardless of error */
+ fail = qcrypto_hash_free(ctx) || fail;
+ } else {
+ fail = false;
}
- (*digest)[resultlen * 2] = '\0';
- g_free(result);
- return 0;
+
+ return fail;
}
int qcrypto_hash_digest(QCryptoHashAlgorithm alg,
@@ -120,16 +182,20 @@ int qcrypto_hash_base64v(QCryptoHashAlgorithm alg,
char **base64,
Error **errp)
{
- uint8_t *result = NULL;
- size_t resultlen = 0;
+ bool fail;
+ QCryptoHash *ctx = qcrypto_hash_new(alg, errp);
+
+ if (ctx) {
+ fail = qcrypto_hash_update(ctx, iov, niov, errp) ||
+ qcrypto_hash_finalize_base64(ctx, base64, errp);
- if (qcrypto_hash_bytesv(alg, iov, niov, &result, &resultlen, errp) < 0) {
- return -1;
+ /* Ensure context is always freed regardless of error */
+ fail = qcrypto_hash_free(ctx) || fail;
+ } else {
+ fail = 1;
}
- *base64 = g_base64_encode(result, resultlen);
- g_free(result);
- return 0;
+ return fail;
}
int qcrypto_hash_base64(QCryptoHashAlgorithm alg,
diff --git a/crypto/hashpriv.h b/crypto/hashpriv.h
index cee26ccb47..8a7d80619e 100644
--- a/crypto/hashpriv.h
+++ b/crypto/hashpriv.h
@@ -1,6 +1,7 @@
/*
* QEMU Crypto hash driver supports
*
+ * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates
* Copyright (c) 2017 HUAWEI TECHNOLOGIES CO., LTD.
*
* Authors:
@@ -15,15 +16,21 @@
#ifndef QCRYPTO_HASHPRIV_H
#define QCRYPTO_HASHPRIV_H
+#include "crypto/hash.h"
+
typedef struct QCryptoHashDriver QCryptoHashDriver;
struct QCryptoHashDriver {
- int (*hash_bytesv)(QCryptoHashAlgorithm alg,
- const struct iovec *iov,
- size_t niov,
- uint8_t **result,
- size_t *resultlen,
- Error **errp);
+ QCryptoHash *(*hash_new)(QCryptoHashAlgorithm alg, Error **errp);
+ int (*hash_update)(QCryptoHash *hash,
+ const struct iovec *iov,
+ size_t niov,
+ Error **errp);
+ int (*hash_finalize)(QCryptoHash *hash,
+ uint8_t **result,
+ size_t *resultlen,
+ Error **errp);
+ int (*hash_free)(QCryptoHash *hash);
};
extern QCryptoHashDriver qcrypto_hash_lib_driver;
diff --git a/include/crypto/hash.h b/include/crypto/hash.h
index 54d87aa2a1..96d080eeb5 100644
--- a/include/crypto/hash.h
+++ b/include/crypto/hash.h
@@ -1,6 +1,7 @@
/*
* QEMU Crypto hash algorithms
*
+ * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates
* Copyright (c) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -25,6 +26,13 @@
/* See also "QCryptoHashAlgorithm" defined in qapi/crypto.json */
+typedef struct QCryptoHash QCryptoHash;
+struct QCryptoHash {
+ QCryptoHashAlgorithm alg;
+ void *opaque;
+ void *driver;
+};
+
/**
* qcrypto_hash_supports:
* @alg: the hash algorithm
@@ -120,6 +128,102 @@ int qcrypto_hash_digestv(QCryptoHashAlgorithm alg,
char **digest,
Error **errp);
+/**
+ * qcrypto_hash_update:
+ * @hash: hash object from qcrypto_hash_new
+ * @iov: the array of memory regions to hash
+ * @niov: the length of @iov
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Updates the given hash object with all the memory regions
+ * present in @iov.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+int qcrypto_hash_update(QCryptoHash *hash,
+ const struct iovec *iov,
+ size_t niov,
+ Error **errp);
+
+/**
+ * qcrypto_hash_finalize_digest:
+ * @hash: the hash object to finalize
+ * @digest: pointer to hold output hash
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Computes the hash from the given hash object. Hash object
+ * is expected to have its data updated from the qcrypto_hash_update function.
+ * The @digest pointer will be filled with the printable hex digest of the
+ * computed hash, which will be terminated by '\0'. The memory pointer
+ * in @digest must be released with a call to g_free() when
+ * no longer required.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+int qcrypto_hash_finalize_digest(QCryptoHash *hash,
+ char **digest,
+ Error **errp);
+
+/**
+ * qcrypto_hash_finalize_base64:
+ * @hash_ctx: hash object to finalize
+ * @base64: pointer to store the hash result in
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Computes the hash from the given hash object. Hash object
+ * is expected to have it's data updated from the qcrypto_hash_update function.
+ * The @base64 pointer will be filled with the base64 encoding of the computed
+ * hash, which will be terminated by '\0'. The memory pointer in @base64
+ * must be released with a call to g_free() when no longer required.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+int qcrypto_hash_finalize_base64(QCryptoHash *hash,
+ char **base64,
+ Error **errp);
+
+/**
+ * qcrypto_hash_finalize_bytes:
+ * @hash_ctx: hash object to finalize
+ * @result: pointer to store the hash result in
+ * @result_len: Pointer to store the length of the result in
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Computes the hash from the given hash object. Hash object
+ * is expected to have it's data updated from the qcrypto_hash_update function.
+ * The memory pointer in @result must be released with a call to g_free()
+ * when no longer required.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+int qcrypto_hash_finalize_bytes(QCryptoHash *hash,
+ uint8_t **result,
+ size_t *result_len,
+ Error **errp);
+
+/**
+ * qcrypto_hash_new:
+ * @alg: the hash algorithm
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Creates a new hashing context for the chosen algorithm for
+ * usage with qcrypto_hash_update.
+ *
+ * Returns: New hash object with the given algorithm
+ */
+QCryptoHash *qcrypto_hash_new(QCryptoHashAlgorithm alg,
+ Error **errp);
+
+/**
+ * qcrypto_hash_free:
+ * @hash: hash object to free
+ *
+ * Frees a hashing context for the chosen algorithm.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+int qcrypto_hash_free(QCryptoHash *hash);
+
/**
* qcrypto_hash_digest:
* @alg: the hash algorithm
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 02/12] crypto/hash-glib: Remove old hash API implementation
2024-08-05 15:50 [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 01/12] crypto: accumulative hashing API Alejandro Zeise
@ 2024-08-05 15:50 ` Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 03/12] crypto/hash-glib: Implement new hash API Alejandro Zeise
` (10 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Alejandro Zeise @ 2024-08-05 15:50 UTC (permalink / raw)
To: qemu-arm
Cc: alejandro.zeise, kris.conklin, jonathan.henze, evan.burgess, clg,
peter.maydell, berrange, qemu-devel
Removes old implemention in the GLib hash driver. Will
be replaced with a new implementation in accordance
with the accumulative hashing changes in the patch series.
Signed-off-by: Alejandro Zeise <alejandro.zeise@seagate.com>
---
crypto/hash-glib.c | 53 ++--------------------------------------------
1 file changed, 2 insertions(+), 51 deletions(-)
diff --git a/crypto/hash-glib.c b/crypto/hash-glib.c
index 82de9db705..ceaf346bf4 100644
--- a/crypto/hash-glib.c
+++ b/crypto/hash-glib.c
@@ -1,6 +1,7 @@
/*
* QEMU Crypto hash algorithms
*
+ * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates
* Copyright (c) 2016 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -44,57 +45,7 @@ gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
}
-static int
-qcrypto_glib_hash_bytesv(QCryptoHashAlgorithm alg,
- const struct iovec *iov,
- size_t niov,
- uint8_t **result,
- size_t *resultlen,
- Error **errp)
-{
- int i, ret;
- GChecksum *cs;
-
- if (!qcrypto_hash_supports(alg)) {
- error_setg(errp,
- "Unknown hash algorithm %d",
- alg);
- return -1;
- }
-
- cs = g_checksum_new(qcrypto_hash_alg_map[alg]);
-
- for (i = 0; i < niov; i++) {
- g_checksum_update(cs, iov[i].iov_base, iov[i].iov_len);
- }
-
- ret = g_checksum_type_get_length(qcrypto_hash_alg_map[alg]);
- if (ret < 0) {
- error_setg(errp, "%s",
- "Unable to get hash length");
- goto error;
- }
- if (*resultlen == 0) {
- *resultlen = ret;
- *result = g_new0(uint8_t, *resultlen);
- } else if (*resultlen != ret) {
- error_setg(errp,
- "Result buffer size %zu is smaller than hash %d",
- *resultlen, ret);
- goto error;
- }
-
- g_checksum_get_digest(cs, *result, resultlen);
-
- g_checksum_free(cs);
- return 0;
-
- error:
- g_checksum_free(cs);
- return -1;
-}
-
QCryptoHashDriver qcrypto_hash_lib_driver = {
- .hash_bytesv = qcrypto_glib_hash_bytesv,
+
};
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 03/12] crypto/hash-glib: Implement new hash API
2024-08-05 15:50 [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 01/12] crypto: accumulative hashing API Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 02/12] crypto/hash-glib: Remove old hash API implementation Alejandro Zeise
@ 2024-08-05 15:50 ` Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 04/12] crypto/hash-gcrypt: Remove old hash API implementation Alejandro Zeise
` (9 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Alejandro Zeise @ 2024-08-05 15:50 UTC (permalink / raw)
To: qemu-arm
Cc: alejandro.zeise, kris.conklin, jonathan.henze, evan.burgess, clg,
peter.maydell, berrange, qemu-devel
Implements the new hashing API in the GLib hash driver.
Supports creating/destroying a context, updating the context
with input data and obtaining an output hash.
Signed-off-by: Alejandro Zeise <alejandro.zeise@seagate.com>
---
crypto/hash-glib.c | 77 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 76 insertions(+), 1 deletion(-)
diff --git a/crypto/hash-glib.c b/crypto/hash-glib.c
index ceaf346bf4..4f343e7d61 100644
--- a/crypto/hash-glib.c
+++ b/crypto/hash-glib.c
@@ -44,8 +44,83 @@ gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
return false;
}
+static
+QCryptoHash *qcrypto_glib_hash_new(QCryptoHashAlgorithm alg,
+ Error **errp)
+{
+ QCryptoHash *hash = NULL;
+ if (!qcrypto_hash_supports(alg)) {
+ error_setg(errp,
+ "Unknown hash algorithm %d",
+ alg);
+ } else {
+ hash = g_new(QCryptoHash, 1);
+ hash->alg = alg;
+ hash->opaque = g_checksum_new(qcrypto_hash_alg_map[alg]);
+ }
-QCryptoHashDriver qcrypto_hash_lib_driver = {
+ return hash;
+}
+
+static
+int qcrypto_glib_hash_free(QCryptoHash *hash)
+{
+ if (hash->opaque) {
+ g_checksum_free((GChecksum *) hash->opaque);
+ }
+
+ g_free(hash);
+
+ return 0;
+}
+
+
+static
+int qcrypto_glib_hash_update(QCryptoHash *hash,
+ const struct iovec *iov,
+ size_t niov,
+ Error **errp)
+{
+ GChecksum *ctx = hash->opaque;
+ for (int i = 0; i < niov; i++) {
+ g_checksum_update(ctx, iov[i].iov_base, iov[i].iov_len);
+ }
+
+ return 0;
+}
+
+static
+int qcrypto_glib_hash_finalize(QCryptoHash *hash,
+ uint8_t **result,
+ size_t *result_len,
+ Error **errp)
+{
+ int ret;
+ GChecksum *ctx = hash->opaque;
+
+ ret = g_checksum_type_get_length(qcrypto_hash_alg_map[hash->alg]);
+ printf("Hash length is %i\n", ret);
+ if (ret < 0) {
+ error_setg(errp, "%s",
+ "Unable to get hash length");
+ *result_len = 0;
+ ret = -1;
+ } else {
+ *result_len = ret;
+ *result = g_new(uint8_t, *result_len);
+
+ g_checksum_get_digest(ctx, *result, result_len);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+QCryptoHashDriver qcrypto_hash_lib_driver = {
+ .hash_new = qcrypto_glib_hash_new,
+ .hash_free = qcrypto_glib_hash_free,
+ .hash_update = qcrypto_glib_hash_update,
+ .hash_finalize = qcrypto_glib_hash_finalize
};
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 04/12] crypto/hash-gcrypt: Remove old hash API implementation
2024-08-05 15:50 [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations Alejandro Zeise
` (2 preceding siblings ...)
2024-08-05 15:50 ` [PATCH v3 03/12] crypto/hash-glib: Implement new hash API Alejandro Zeise
@ 2024-08-05 15:50 ` Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 05/12] crypto/hash-gcrypt: Implement new hash API Alejandro Zeise
` (8 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Alejandro Zeise @ 2024-08-05 15:50 UTC (permalink / raw)
To: qemu-arm
Cc: alejandro.zeise, kris.conklin, jonathan.henze, evan.burgess, clg,
peter.maydell, berrange, qemu-devel
Removes old implemention in the gcrypt hash driver. Will
be replaced with a new implementation in accordance
with the accumulative hashing changes in the patch series.
Signed-off-by: Alejandro Zeise <alejandro.zeise@seagate.com>
---
crypto/hash-gcrypt.c | 66 +-------------------------------------------
1 file changed, 1 insertion(+), 65 deletions(-)
diff --git a/crypto/hash-gcrypt.c b/crypto/hash-gcrypt.c
index 829e48258d..6378879072 100644
--- a/crypto/hash-gcrypt.c
+++ b/crypto/hash-gcrypt.c
@@ -1,6 +1,7 @@
/*
* QEMU Crypto hash algorithms
*
+ * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates
* Copyright (c) 2016 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -45,72 +46,7 @@ gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
}
-static int
-qcrypto_gcrypt_hash_bytesv(QCryptoHashAlgorithm alg,
- const struct iovec *iov,
- size_t niov,
- uint8_t **result,
- size_t *resultlen,
- Error **errp)
-{
- int i, ret;
- gcry_md_hd_t md;
- unsigned char *digest;
-
- if (!qcrypto_hash_supports(alg)) {
- error_setg(errp,
- "Unknown hash algorithm %d",
- alg);
- return -1;
- }
-
- ret = gcry_md_open(&md, qcrypto_hash_alg_map[alg], 0);
-
- if (ret < 0) {
- error_setg(errp,
- "Unable to initialize hash algorithm: %s",
- gcry_strerror(ret));
- return -1;
- }
-
- for (i = 0; i < niov; i++) {
- gcry_md_write(md, iov[i].iov_base, iov[i].iov_len);
- }
-
- ret = gcry_md_get_algo_dlen(qcrypto_hash_alg_map[alg]);
- if (ret <= 0) {
- error_setg(errp,
- "Unable to get hash length: %s",
- gcry_strerror(ret));
- goto error;
- }
- if (*resultlen == 0) {
- *resultlen = ret;
- *result = g_new0(uint8_t, *resultlen);
- } else if (*resultlen != ret) {
- error_setg(errp,
- "Result buffer size %zu is smaller than hash %d",
- *resultlen, ret);
- goto error;
- }
-
- digest = gcry_md_read(md, 0);
- if (!digest) {
- error_setg(errp,
- "No digest produced");
- goto error;
- }
- memcpy(*result, digest, *resultlen);
-
- gcry_md_close(md);
- return 0;
-
- error:
- gcry_md_close(md);
- return -1;
-}
QCryptoHashDriver qcrypto_hash_lib_driver = {
- .hash_bytesv = qcrypto_gcrypt_hash_bytesv,
};
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 05/12] crypto/hash-gcrypt: Implement new hash API
2024-08-05 15:50 [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations Alejandro Zeise
` (3 preceding siblings ...)
2024-08-05 15:50 ` [PATCH v3 04/12] crypto/hash-gcrypt: Remove old hash API implementation Alejandro Zeise
@ 2024-08-05 15:50 ` Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 06/12] crypto/hash-gnutls: Remove old " Alejandro Zeise
` (7 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Alejandro Zeise @ 2024-08-05 15:50 UTC (permalink / raw)
To: qemu-arm
Cc: alejandro.zeise, kris.conklin, jonathan.henze, evan.burgess, clg,
peter.maydell, berrange, qemu-devel
Implements the new hashing API in the gcrypt hash driver.
Supports creating/destroying a context, updating the context
with input data and obtaining an output hash.
Signed-off-by: Alejandro Zeise <alejandro.zeise@seagate.com>
---
crypto/hash-gcrypt.c | 78 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 78 insertions(+)
diff --git a/crypto/hash-gcrypt.c b/crypto/hash-gcrypt.c
index 6378879072..830ae642b9 100644
--- a/crypto/hash-gcrypt.c
+++ b/crypto/hash-gcrypt.c
@@ -45,8 +45,86 @@ gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
return false;
}
+static
+QCryptoHash *qcrypto_gcrypt_hash_new(QCryptoHashAlgorithm alg, Error **errp)
+{
+ QCryptoHash *hash = NULL;
+
+ if (!qcrypto_hash_supports(alg)) {
+ error_setg(errp,
+ "Unknown hash algorithm %d",
+ alg);
+ } else {
+ hash = g_new(QCryptoHash, 1);
+ hash->alg = alg;
+ hash->opaque = g_new(gcry_md_hd_t, 1);
+
+ gcry_md_open((gcry_md_hd_t *) hash->opaque, qcrypto_hash_alg_map[alg], 0);
+ }
+
+ return hash;
+}
+
+static
+int qcrypto_gcrypt_hash_free(QCryptoHash *hash)
+{
+ gcry_md_hd_t *ctx = hash->opaque;
+
+ if (ctx) {
+ gcry_md_close(*ctx);
+ g_free(ctx);
+ }
+
+ g_free(hash);
+
+ return 0;
+}
+static
+int qcrypto_gcrypt_hash_update(QCryptoHash *hash,
+ const struct iovec *iov,
+ size_t niov,
+ Error **errp)
+{
+ gcry_md_hd_t *ctx = hash->opaque;
+
+ for (int i = 0; i < niov; i++) {
+ gcry_md_write(*ctx, iov[i].iov_base, iov[i].iov_len);
+ }
+
+ return 0;
+}
+
+static
+int qcrypto_gcrypt_hash_finalize(QCryptoHash *hash,
+ uint8_t **result,
+ size_t *result_len,
+ Error **errp)
+{
+ unsigned char *digest;
+ int ret = 0;
+ gcry_md_hd_t *ctx = hash->opaque;
+
+ *result_len = gcry_md_get_algo_dlen(qcrypto_hash_alg_map[hash->alg]);
+ if (*result_len == 0) {
+ error_setg(errp, "%s",
+ "Unable to get hash length");
+ ret = -1;
+ } else {
+ *result = g_new(uint8_t, *result_len);
+
+ /* Digest is freed by gcry_md_close(), copy it */
+ digest = gcry_md_read(*ctx, 0);
+ memcpy(*result, digest, *result_len);
+ }
+
+ return ret;
+}
QCryptoHashDriver qcrypto_hash_lib_driver = {
+ .hash_new = qcrypto_gcrypt_hash_new,
+ .hash_free = qcrypto_gcrypt_hash_free,
+ .hash_update = qcrypto_gcrypt_hash_update,
+ .hash_finalize = qcrypto_gcrypt_hash_finalize
};
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 06/12] crypto/hash-gnutls: Remove old hash API
2024-08-05 15:50 [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations Alejandro Zeise
` (4 preceding siblings ...)
2024-08-05 15:50 ` [PATCH v3 05/12] crypto/hash-gcrypt: Implement new hash API Alejandro Zeise
@ 2024-08-05 15:50 ` Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 07/12] crypto/hash-gnutls: Implement new " Alejandro Zeise
` (6 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Alejandro Zeise @ 2024-08-05 15:50 UTC (permalink / raw)
To: qemu-arm
Cc: alejandro.zeise, kris.conklin, jonathan.henze, evan.burgess, clg,
peter.maydell, berrange, qemu-devel
Removes old implemention in the gnutls hash driver. Will
be replaced with a new implementation in accordance
with the accumulative hashing changes in the patch series.
Signed-off-by: Alejandro Zeise <alejandro.zeise@seagate.com>
---
crypto/hash-gnutls.c | 46 +-------------------------------------------
1 file changed, 1 insertion(+), 45 deletions(-)
diff --git a/crypto/hash-gnutls.c b/crypto/hash-gnutls.c
index 17911ac5d1..84ce7073f5 100644
--- a/crypto/hash-gnutls.c
+++ b/crypto/hash-gnutls.c
@@ -1,6 +1,7 @@
/*
* QEMU Crypto hash algorithms
*
+ * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates
* Copyright (c) 2021 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -53,52 +54,7 @@ gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
}
-static int
-qcrypto_gnutls_hash_bytesv(QCryptoHashAlgorithm alg,
- const struct iovec *iov,
- size_t niov,
- uint8_t **result,
- size_t *resultlen,
- Error **errp)
-{
- int i, ret;
- gnutls_hash_hd_t hash;
-
- if (!qcrypto_hash_supports(alg)) {
- error_setg(errp,
- "Unknown hash algorithm %d",
- alg);
- return -1;
- }
-
- ret = gnutls_hash_get_len(qcrypto_hash_alg_map[alg]);
- if (*resultlen == 0) {
- *resultlen = ret;
- *result = g_new0(uint8_t, *resultlen);
- } else if (*resultlen != ret) {
- error_setg(errp,
- "Result buffer size %zu is smaller than hash %d",
- *resultlen, ret);
- return -1;
- }
-
- ret = gnutls_hash_init(&hash, qcrypto_hash_alg_map[alg]);
- if (ret < 0) {
- error_setg(errp,
- "Unable to initialize hash algorithm: %s",
- gnutls_strerror(ret));
- return -1;
- }
-
- for (i = 0; i < niov; i++) {
- gnutls_hash(hash, iov[i].iov_base, iov[i].iov_len);
- }
-
- gnutls_hash_deinit(hash, *result);
- return 0;
-}
QCryptoHashDriver qcrypto_hash_lib_driver = {
- .hash_bytesv = qcrypto_gnutls_hash_bytesv,
};
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 07/12] crypto/hash-gnutls: Implement new hash API
2024-08-05 15:50 [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations Alejandro Zeise
` (5 preceding siblings ...)
2024-08-05 15:50 ` [PATCH v3 06/12] crypto/hash-gnutls: Remove old " Alejandro Zeise
@ 2024-08-05 15:50 ` Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 08/12] crypto/hash-nettle: Remove old " Alejandro Zeise
` (5 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Alejandro Zeise @ 2024-08-05 15:50 UTC (permalink / raw)
To: qemu-arm
Cc: alejandro.zeise, kris.conklin, jonathan.henze, evan.burgess, clg,
peter.maydell, berrange, qemu-devel
Implements the new hashing API in the gnutls hash driver.
Supports creating/destroying a context, updating the context
with input data and obtaining an output hash.
Signed-off-by: Alejandro Zeise <alejandro.zeise@seagate.com>
---
crypto/hash-gnutls.c | 76 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/crypto/hash-gnutls.c b/crypto/hash-gnutls.c
index 84ce7073f5..a2ccd257c7 100644
--- a/crypto/hash-gnutls.c
+++ b/crypto/hash-gnutls.c
@@ -53,8 +53,81 @@ gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
return false;
}
+static
+QCryptoHash *qcrypto_gnutls_hash_new(QCryptoHashAlgorithm alg, Error **errp)
+{
+ QCryptoHash *hash = NULL;
+
+ if (!qcrypto_hash_supports(alg)) {
+ error_setg(errp,
+ "Unknown hash algorithm %d",
+ alg);
+ } else {
+ hash = g_new(QCryptoHash, 1);
+ hash->alg = alg;
+ hash->opaque = g_new(gnutls_hash_hd_t, 1);
+
+ gnutls_hash_init(hash->opaque, qcrypto_hash_alg_map[alg]);
+ }
+
+ return hash;
+}
+
+static
+int qcrypto_gnutls_hash_free(QCryptoHash *hash)
+{
+ gnutls_hash_hd_t *ctx = hash->opaque;
+
+ g_free(ctx);
+ g_free(hash);
+
+ return 0;
+}
+static
+int qcrypto_gnutls_hash_update(QCryptoHash *hash,
+ const struct iovec *iov,
+ size_t niov,
+ Error **errp)
+{
+ int fail = 0;
+ gnutls_hash_hd_t *ctx = hash->opaque;
+
+ for (int i = 0; i < niov; i++) {
+ fail = gnutls_hash(*ctx, iov[i].iov_base, iov[i].iov_len) || fail;
+ }
+
+ return fail;
+}
+
+static
+int qcrypto_gnutls_hash_finalize(QCryptoHash *hash,
+ uint8_t **result,
+ size_t *result_len,
+ Error **errp)
+{
+ int ret = 0;
+ gnutls_hash_hd_t *ctx = hash->opaque;
+
+ *result_len = gnutls_hash_get_len(qcrypto_hash_alg_map[hash->alg]);
+ if (*result_len == 0) {
+ error_setg(errp, "%s",
+ "Unable to get hash length");
+ ret = -1;
+ } else {
+ *result = g_new(uint8_t, *result_len);
+
+ gnutls_hash_deinit(*ctx, *result);
+ }
+
+ return ret;
+}
+
QCryptoHashDriver qcrypto_hash_lib_driver = {
+ .hash_new = qcrypto_gnutls_hash_new,
+ .hash_free = qcrypto_gnutls_hash_free,
+ .hash_update = qcrypto_gnutls_hash_update,
+ .hash_finalize = qcrypto_gnutls_hash_finalize
};
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 08/12] crypto/hash-nettle: Remove old hash API
2024-08-05 15:50 [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations Alejandro Zeise
` (6 preceding siblings ...)
2024-08-05 15:50 ` [PATCH v3 07/12] crypto/hash-gnutls: Implement new " Alejandro Zeise
@ 2024-08-05 15:50 ` Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 09/12] crypto/hash-nettle: Implement new " Alejandro Zeise
` (4 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Alejandro Zeise @ 2024-08-05 15:50 UTC (permalink / raw)
To: qemu-arm
Cc: alejandro.zeise, kris.conklin, jonathan.henze, evan.burgess, clg,
peter.maydell, berrange, qemu-devel
Removes old implemention in the nettle hash driver. Will
be replaced with a new implementation in accordance
with the accumulative hashing changes in the patch series.
Signed-off-by: Alejandro Zeise <alejandro.zeise@seagate.com>
---
crypto/hash-nettle.c | 52 +-------------------------------------------
1 file changed, 1 insertion(+), 51 deletions(-)
diff --git a/crypto/hash-nettle.c b/crypto/hash-nettle.c
index 1ca1a41062..dbf1d96dfe 100644
--- a/crypto/hash-nettle.c
+++ b/crypto/hash-nettle.c
@@ -1,6 +1,7 @@
/*
* QEMU Crypto hash algorithms
*
+ * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates
* Copyright (c) 2016 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -104,58 +105,7 @@ gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
}
-static int
-qcrypto_nettle_hash_bytesv(QCryptoHashAlgorithm alg,
- const struct iovec *iov,
- size_t niov,
- uint8_t **result,
- size_t *resultlen,
- Error **errp)
-{
- size_t i;
- union qcrypto_hash_ctx ctx;
-
- if (!qcrypto_hash_supports(alg)) {
- error_setg(errp,
- "Unknown hash algorithm %d",
- alg);
- return -1;
- }
-
- qcrypto_hash_alg_map[alg].init(&ctx);
-
- for (i = 0; i < niov; i++) {
- /* Some versions of nettle have functions
- * declared with 'int' instead of 'size_t'
- * so to be safe avoid writing more than
- * UINT_MAX bytes at a time
- */
- size_t len = iov[i].iov_len;
- uint8_t *base = iov[i].iov_base;
- while (len) {
- size_t shortlen = MIN(len, UINT_MAX);
- qcrypto_hash_alg_map[alg].write(&ctx, len, base);
- len -= shortlen;
- base += len;
- }
- }
-
- if (*resultlen == 0) {
- *resultlen = qcrypto_hash_alg_map[alg].len;
- *result = g_new0(uint8_t, *resultlen);
- } else if (*resultlen != qcrypto_hash_alg_map[alg].len) {
- error_setg(errp,
- "Result buffer size %zu is smaller than hash %zu",
- *resultlen, qcrypto_hash_alg_map[alg].len);
- return -1;
- }
-
- qcrypto_hash_alg_map[alg].result(&ctx, *resultlen, *result);
-
- return 0;
-}
QCryptoHashDriver qcrypto_hash_lib_driver = {
- .hash_bytesv = qcrypto_nettle_hash_bytesv,
};
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 09/12] crypto/hash-nettle: Implement new hash API
2024-08-05 15:50 [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations Alejandro Zeise
` (7 preceding siblings ...)
2024-08-05 15:50 ` [PATCH v3 08/12] crypto/hash-nettle: Remove old " Alejandro Zeise
@ 2024-08-05 15:50 ` Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 10/12] crypto/hash-afalg: Update to new API Alejandro Zeise
` (3 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Alejandro Zeise @ 2024-08-05 15:50 UTC (permalink / raw)
To: qemu-arm
Cc: alejandro.zeise, kris.conklin, jonathan.henze, evan.burgess, clg,
peter.maydell, berrange, qemu-devel
Implements the new hashing API in the nettle hash driver.
Supports creating/destroying a context, updating the context
with input data and obtaining an output hash.
Signed-off-by: Alejandro Zeise <alejandro.zeise@seagate.com>
---
crypto/hash-nettle.c | 81 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/crypto/hash-nettle.c b/crypto/hash-nettle.c
index dbf1d96dfe..643f3d68b8 100644
--- a/crypto/hash-nettle.c
+++ b/crypto/hash-nettle.c
@@ -23,6 +23,7 @@
#include "qapi/error.h"
#include "crypto/hash.h"
#include "hashpriv.h"
+#include <gnutls/crypto.h>
#include <nettle/md5.h>
#include <nettle/sha.h>
#include <nettle/ripemd160.h>
@@ -105,7 +106,85 @@ gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
}
+static
+QCryptoHash *qcrypto_nettle_hash_new(QCryptoHashAlgorithm alg, Error **errp)
+{
+ QCryptoHash *hash = NULL;
+
+ if (!qcrypto_hash_supports(alg)) {
+ error_setg(errp,
+ "Unknown hash algorithm %d",
+ alg);
+ } else {
+ hash = g_new(QCryptoHash, 1);
+ hash->alg = alg;
+ hash->opaque = g_new(union qcrypto_hash_ctx, 1);
+
+ qcrypto_hash_alg_map[alg].init(hash->opaque);
+ }
+
+ return hash;
+}
+
+static
+int qcrypto_nettle_hash_free(QCryptoHash *hash)
+{
+ union qcrypto_hash_ctx *ctx = hash->opaque;
+
+ g_free(ctx);
+ g_free(hash);
+
+ return 0;
+}
+
+static
+int qcrypto_nettle_hash_update(QCryptoHash *hash,
+ const struct iovec *iov,
+ size_t niov,
+ Error **errp)
+{
+ union qcrypto_hash_ctx *ctx = hash->opaque;
+
+ for (int i = 0; i < niov; i++) {
+ /*
+ * Some versions of nettle have functions
+ * declared with 'int' instead of 'size_t'
+ * so to be safe avoid writing more than
+ * UINT_MAX bytes at a time
+ */
+ size_t len = iov[i].iov_len;
+ uint8_t *base = iov[i].iov_base;
+ while (len) {
+ size_t shortlen = MIN(len, UINT_MAX);
+ qcrypto_hash_alg_map[hash->alg].write(ctx, len, base);
+ len -= shortlen;
+ base += len;
+ }
+ }
+
+ return 0;
+}
+
+static
+int qcrypto_nettle_hash_finalize(QCryptoHash *hash,
+ uint8_t **result,
+ size_t *result_len,
+ 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);
+
+ qcrypto_hash_alg_map[hash->alg].result(ctx, *result_len, *result);
+
+ return 0;
+}
QCryptoHashDriver qcrypto_hash_lib_driver = {
+ .hash_new = qcrypto_nettle_hash_new,
+ .hash_free = qcrypto_nettle_hash_free,
+ .hash_update = qcrypto_nettle_hash_update,
+ .hash_finalize = qcrypto_nettle_hash_finalize
};
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 10/12] crypto/hash-afalg: Update to new API
2024-08-05 15:50 [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations Alejandro Zeise
` (8 preceding siblings ...)
2024-08-05 15:50 ` [PATCH v3 09/12] crypto/hash-nettle: Implement new " Alejandro Zeise
@ 2024-08-05 15:50 ` Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 11/12] tests/unit/test-crypto-hash: accumulative hashing Alejandro Zeise
` (2 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Alejandro Zeise @ 2024-08-05 15:50 UTC (permalink / raw)
To: qemu-arm
Cc: alejandro.zeise, kris.conklin, jonathan.henze, evan.burgess, clg,
peter.maydell, berrange, qemu-devel
Updates the AFAlg hash driver to support the new accumulative
hashing changes as part of the patch series.
Implements opening/closing of contexts, updating hash data
and finalizing the hash digest.
Signed-off-by: Alejandro Zeise <alejandro.zeise@seagate.com>
---
crypto/hash-afalg.c | 154 +++++++++++++++++++++++++++++---------------
1 file changed, 103 insertions(+), 51 deletions(-)
diff --git a/crypto/hash-afalg.c b/crypto/hash-afalg.c
index 3ebea39292..6cf222fb3b 100644
--- a/crypto/hash-afalg.c
+++ b/crypto/hash-afalg.c
@@ -1,6 +1,7 @@
/*
* QEMU Crypto af_alg-backend hash/hmac support
*
+ * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates
* Copyright (c) 2017 HUAWEI TECHNOLOGIES CO., LTD.
*
* Authors:
@@ -113,74 +114,116 @@ qcrypto_afalg_hmac_ctx_new(QCryptoHashAlgorithm alg,
return qcrypto_afalg_hash_hmac_ctx_new(alg, key, nkey, true, errp);
}
-static int
-qcrypto_afalg_hash_hmac_bytesv(QCryptoAFAlg *hmac,
- QCryptoHashAlgorithm alg,
- const struct iovec *iov,
- size_t niov, uint8_t **result,
- size_t *resultlen,
- Error **errp)
+static
+QCryptoHash *qcrypto_afalg_hash_new(QCryptoHashAlgorithm alg, Error **errp)
{
- QCryptoAFAlg *afalg;
- struct iovec outv;
- int ret = 0;
- bool is_hmac = (hmac != NULL) ? true : false;
- const int expect_len = qcrypto_hash_digest_len(alg);
+ /* Check if hash algorithm is supported */
+ char *alg_name = qcrypto_afalg_hash_format_name(alg, false, NULL);
+ QCryptoHash *hash = NULL;
- if (*resultlen == 0) {
- *resultlen = expect_len;
- *result = g_new0(uint8_t, *resultlen);
- } else if (*resultlen != expect_len) {
+ if (alg_name == NULL) {
error_setg(errp,
- "Result buffer size %zu is not match hash %d",
- *resultlen, expect_len);
- return -1;
+ "Unknown hash algorithm %d",
+ alg);
+ } else {
+ hash = g_new(QCryptoHash, 1);
+ hash->alg = alg;
+ hash->opaque = qcrypto_afalg_hash_ctx_new(alg, errp);
}
- if (is_hmac) {
- afalg = hmac;
- } else {
- afalg = qcrypto_afalg_hash_ctx_new(alg, errp);
- if (!afalg) {
- return -1;
- }
+ return hash;
+}
+
+static
+int qcrypto_afalg_hash_free(QCryptoHash *hash)
+{
+ QCryptoAFAlg *ctx = hash->opaque;
+
+ if (ctx) {
+ qcrypto_afalg_comm_free(ctx);
}
+ g_free(hash);
+
+ return 0;
+}
+
+static
+int qcrypto_afalg_send_to_kernel(QCryptoAFAlg *afalg,
+ const struct iovec *iov,
+ size_t niov,
+ Error **errp)
+{
+ int ret = 0;
+
/* send data to kernel's crypto core */
ret = iov_send_recv(afalg->opfd, iov, niov,
0, iov_size(iov, niov), true);
if (ret < 0) {
error_setg_errno(errp, errno, "Send data to afalg-core failed");
- goto out;
- }
-
- /* hash && get result */
- outv.iov_base = *result;
- outv.iov_len = *resultlen;
- ret = iov_send_recv(afalg->opfd, &outv, 1,
- 0, iov_size(&outv, 1), false);
- if (ret < 0) {
- error_setg_errno(errp, errno, "Recv result from afalg-core failed");
} else {
+ /* No error, so return 0 */
ret = 0;
}
-out:
- if (!is_hmac) {
- qcrypto_afalg_comm_free(afalg);
+ return ret;
+}
+
+static
+int qcrypto_afalg_recv_from_kernel(QCryptoAFAlg *afalg,
+ QCryptoHashAlgorithm alg,
+ uint8_t **result,
+ size_t *result_len,
+ Error **errp)
+{
+ struct iovec outv;
+ int ret = 0;
+ const int expected_len = qcrypto_hash_digest_len(alg);
+
+ if (*result_len == 0) {
+ *result_len = expected_len;
+ *result = g_new0(uint8_t, *result_len);
+ } else if (*result_len != expected_len) {
+ error_setg(errp,
+ "Result buffer size %zu is not match hash %d",
+ *result_len, expected_len);
+ ret = -1;
+ }
+
+ if (ret == 0) {
+ /* hash && get result */
+ outv.iov_base = *result;
+ outv.iov_len = *result_len;
+ ret = iov_send_recv(afalg->opfd, &outv, 1,
+ 0, iov_size(&outv, 1), false);
+ if (ret < 0) {
+ error_setg_errno(errp, errno, "Recv result from afalg-core failed");
+ } else {
+ ret = 0;
+ }
}
+
return ret;
}
-static int
-qcrypto_afalg_hash_bytesv(QCryptoHashAlgorithm alg,
- const struct iovec *iov,
- size_t niov, uint8_t **result,
- size_t *resultlen,
- Error **errp)
+static
+int qcrypto_afalg_hash_update(QCryptoHash *hash,
+ const struct iovec *iov,
+ size_t niov,
+ Error **errp)
+{
+ return qcrypto_afalg_send_to_kernel((QCryptoAFAlg *) hash->opaque,
+ iov, niov, errp);
+}
+
+static
+int qcrypto_afalg_hash_finalize(QCryptoHash *hash,
+ uint8_t **result,
+ size_t *result_len,
+ Error **errp)
{
- return qcrypto_afalg_hash_hmac_bytesv(NULL, alg, iov, niov, result,
- resultlen, errp);
+ return qcrypto_afalg_recv_from_kernel((QCryptoAFAlg *) hash->opaque,
+ hash->alg, result, result_len, errp);
}
static int
@@ -190,9 +233,16 @@ qcrypto_afalg_hmac_bytesv(QCryptoHmac *hmac,
size_t *resultlen,
Error **errp)
{
- return qcrypto_afalg_hash_hmac_bytesv(hmac->opaque, hmac->alg,
- iov, niov, result, resultlen,
- errp);
+ int ret;
+
+ ret = qcrypto_afalg_send_to_kernel(hmac->opaque, iov, niov, errp);
+
+ if (ret == 0) {
+ ret = qcrypto_afalg_recv_from_kernel(hmac->opaque, hmac->alg, result,
+ resultlen, errp);
+ }
+
+ return ret;
}
static void qcrypto_afalg_hmac_ctx_free(QCryptoHmac *hmac)
@@ -204,7 +253,10 @@ static void qcrypto_afalg_hmac_ctx_free(QCryptoHmac *hmac)
}
QCryptoHashDriver qcrypto_hash_afalg_driver = {
- .hash_bytesv = qcrypto_afalg_hash_bytesv,
+ .hash_new = qcrypto_afalg_hash_new,
+ .hash_free = qcrypto_afalg_hash_free,
+ .hash_update = qcrypto_afalg_hash_update,
+ .hash_finalize = qcrypto_afalg_hash_finalize
};
QCryptoHmacDriver qcrypto_hmac_afalg_driver = {
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 11/12] tests/unit/test-crypto-hash: accumulative hashing
2024-08-05 15:50 [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations Alejandro Zeise
` (9 preceding siblings ...)
2024-08-05 15:50 ` [PATCH v3 10/12] crypto/hash-afalg: Update to new API Alejandro Zeise
@ 2024-08-05 15:50 ` Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 12/12] hw/misc/aspeed_hace: Fix SG Accumulative hashing Alejandro Zeise
2024-08-06 15:52 ` [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations Daniel P. Berrangé
12 siblings, 0 replies; 16+ messages in thread
From: Alejandro Zeise @ 2024-08-05 15:50 UTC (permalink / raw)
To: qemu-arm
Cc: alejandro.zeise, kris.conklin, jonathan.henze, evan.burgess, clg,
peter.maydell, berrange, qemu-devel
Added an accumulative hashing test. Checks for functionality of
the new hash create, update, finalize and free functions.
Signed-off-by: Alejandro Zeise <alejandro.zeise@seagate.com>
---
tests/unit/test-crypto-hash.c | 50 +++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/tests/unit/test-crypto-hash.c b/tests/unit/test-crypto-hash.c
index 1f4abb822b..8f66ad4115 100644
--- a/tests/unit/test-crypto-hash.c
+++ b/tests/unit/test-crypto-hash.c
@@ -1,6 +1,7 @@
/*
* QEMU Crypto hash algorithms
*
+ * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates
* Copyright (c) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -241,6 +242,54 @@ static void test_hash_base64(void)
}
}
+static void test_hash_accumulate(void)
+{
+ QCryptoHash *hash;
+ size_t i;
+
+ for (i = 0; i < G_N_ELEMENTS(expected_outputs) ; i++) {
+ struct iovec iov[3] = {
+ { .iov_base = (char *)INPUT_TEXT1, .iov_len = strlen(INPUT_TEXT1) },
+ { .iov_base = (char *)INPUT_TEXT2, .iov_len = strlen(INPUT_TEXT2) },
+ { .iov_base = (char *)INPUT_TEXT3, .iov_len = strlen(INPUT_TEXT3) },
+ };
+ uint8_t *result = NULL;
+ size_t resultlen = 0;
+ int ret;
+ size_t j;
+
+ if (!qcrypto_hash_supports(i)) {
+ continue;
+ }
+
+ hash = qcrypto_hash_new(i, &error_fatal);
+ g_assert(hash != NULL);
+
+ /* Add each iovec to the hash context separately */
+ for (j = 0; j < 3; j++) {
+ ret = qcrypto_hash_update(hash,
+ &iov[j], 1,
+ &error_fatal);
+
+ g_assert(ret == 0);
+ }
+
+ ret = qcrypto_hash_finalize_bytes(hash, &result, &resultlen,
+ &error_fatal);
+
+ g_assert(ret == 0);
+ g_assert(resultlen == expected_lens[i]);
+ for (j = 0; j < resultlen; j++) {
+ g_assert(expected_outputs[i][j * 2] == hex[(result[j] >> 4) & 0xf]);
+ g_assert(expected_outputs[i][j * 2 + 1] == hex[result[j] & 0xf]);
+ }
+ g_free(result);
+
+ ret = qcrypto_hash_free(hash);
+ g_assert(ret == 0);
+ }
+}
+
int main(int argc, char **argv)
{
int ret = qcrypto_init(&error_fatal);
@@ -252,5 +301,6 @@ int main(int argc, char **argv)
g_test_add_func("/crypto/hash/prealloc", test_hash_prealloc);
g_test_add_func("/crypto/hash/digest", test_hash_digest);
g_test_add_func("/crypto/hash/base64", test_hash_base64);
+ g_test_add_func("/crypto/hash/accumulate", test_hash_accumulate);
return g_test_run();
}
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 12/12] hw/misc/aspeed_hace: Fix SG Accumulative hashing
2024-08-05 15:50 [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations Alejandro Zeise
` (10 preceding siblings ...)
2024-08-05 15:50 ` [PATCH v3 11/12] tests/unit/test-crypto-hash: accumulative hashing Alejandro Zeise
@ 2024-08-05 15:50 ` Alejandro Zeise
2024-08-06 15:52 ` [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations Daniel P. Berrangé
12 siblings, 0 replies; 16+ messages in thread
From: Alejandro Zeise @ 2024-08-05 15:50 UTC (permalink / raw)
To: qemu-arm
Cc: alejandro.zeise, kris.conklin, jonathan.henze, evan.burgess, clg,
peter.maydell, berrange, qemu-devel
Make the Aspeed HACE module use the new qcrypto accumulative hashing functions
when in scatter-gather accumulative mode. A hash context will maintain a
"running-hash" as each scatter-gather chunk is received.
Previously each scatter-gather "chunk" was cached
so the hash could be computed once the final chunk was received.
However, the cache was a shallow copy, so once the guest overwrote the
memory provided to HACE the final hash would not be correct.
Possibly related to: https://gitlab.com/qemu-project/qemu/-/issues/1121
Buglink: https://github.com/openbmc/qemu/issues/36
Signed-off-by: Alejandro Zeise <alejandro.zeise@seagate.com>
---
hw/misc/aspeed_hace.c | 92 ++++++++++++++++++-----------------
include/hw/misc/aspeed_hace.h | 4 ++
2 files changed, 52 insertions(+), 44 deletions(-)
diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
index c06c04ddc6..5077204ee6 100644
--- a/hw/misc/aspeed_hace.c
+++ b/hw/misc/aspeed_hace.c
@@ -1,6 +1,7 @@
/*
* ASPEED Hash and Crypto Engine
*
+ * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates
* Copyright (C) 2021 IBM Corp.
*
* Joel Stanley <joel@jms.id.au>
@@ -151,50 +152,28 @@ static int reconstruct_iov(AspeedHACEState *s, struct iovec *iov, int id,
return iov_count;
}
-/**
- * Generate iov for accumulative mode.
- *
- * @param s aspeed hace state object
- * @param iov iov of the current request
- * @param id index of the current iov
- * @param req_len length of the current request
- *
- * @return count of iov
- */
-static int gen_acc_mode_iov(AspeedHACEState *s, struct iovec *iov, int id,
- hwaddr *req_len)
-{
- uint32_t pad_offset;
- uint32_t total_msg_len;
- s->total_req_len += *req_len;
-
- if (has_padding(s, &iov[id], *req_len, &total_msg_len, &pad_offset)) {
- if (s->iov_count) {
- return reconstruct_iov(s, iov, id, &pad_offset);
- }
-
- *req_len -= s->total_req_len - total_msg_len;
- s->total_req_len = 0;
- iov[id].iov_len = *req_len;
- } else {
- s->iov_cache[s->iov_count].iov_base = iov->iov_base;
- s->iov_cache[s->iov_count].iov_len = *req_len;
- ++s->iov_count;
- }
-
- return id + 1;
-}
-
static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
bool acc_mode)
{
struct iovec iov[ASPEED_HACE_MAX_SG];
+ uint32_t total_msg_len;
+ uint32_t pad_offset;
g_autofree uint8_t *digest_buf = NULL;
size_t digest_len = 0;
- int niov = 0;
+ bool sg_acc_mode_final_request = false;
int i;
void *haddr;
+ if (acc_mode && s->hash_ctx == NULL) {
+ s->hash_ctx = qcrypto_hash_new(algo, NULL);
+ if (s->hash_ctx == NULL) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: qcrypto failed to create hash context\n",
+ __func__);
+ return;
+ }
+ }
+
if (sg_mode) {
uint32_t len = 0;
@@ -226,8 +203,15 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
}
iov[i].iov_base = haddr;
if (acc_mode) {
- niov = gen_acc_mode_iov(s, iov, i, &plen);
-
+ s->total_req_len += plen;
+
+ if (has_padding(s, &iov[i], plen, &total_msg_len, &pad_offset)) {
+ /* Padding being present indicates the final request */
+ sg_acc_mode_final_request = true;
+ iov[i].iov_len = pad_offset;
+ } else {
+ iov[i].iov_len = plen;
+ }
} else {
iov[i].iov_len = plen;
}
@@ -252,20 +236,38 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
* required to check whether cache is empty. If no, we should
* combine cached iov and the current iov.
*/
- uint32_t total_msg_len;
- uint32_t pad_offset;
s->total_req_len += len;
if (has_padding(s, iov, len, &total_msg_len, &pad_offset)) {
- niov = reconstruct_iov(s, iov, 0, &pad_offset);
+ i = reconstruct_iov(s, iov, 0, &pad_offset);
}
}
}
- if (niov) {
- i = niov;
- }
+ if (acc_mode) {
+ if (qcrypto_hash_update(s->hash_ctx, iov, i, NULL) < 0) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: qcrypto hash update failed\n", __func__);
+ return;
+ }
+
+ if (sg_acc_mode_final_request) {
+ if (qcrypto_hash_finalize_bytes(s->hash_ctx, &digest_buf,
+ &digest_len, NULL)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: qcrypto failed to finalize hash\n", __func__);
+ }
- if (qcrypto_hash_bytesv(algo, iov, i, &digest_buf, &digest_len, NULL) < 0) {
+ if (qcrypto_hash_free(s->hash_ctx)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: qcrypto failed to free context\n", __func__);
+ }
+
+ s->hash_ctx = NULL;
+ s->iov_count = 0;
+ s->total_req_len = 0;
+ }
+ } else if (qcrypto_hash_bytesv(algo, iov, i, &digest_buf,
+ &digest_len, NULL) < 0) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto failed\n", __func__);
return;
}
@@ -397,6 +396,11 @@ static void aspeed_hace_reset(DeviceState *dev)
{
struct AspeedHACEState *s = ASPEED_HACE(dev);
+ if (s->hash_ctx != NULL) {
+ qcrypto_hash_free(s->hash_ctx);
+ s->hash_ctx = NULL;
+ }
+
memset(s->regs, 0, sizeof(s->regs));
s->iov_count = 0;
s->total_req_len = 0;
diff --git a/include/hw/misc/aspeed_hace.h b/include/hw/misc/aspeed_hace.h
index ecb1b67de8..4af9919195 100644
--- a/include/hw/misc/aspeed_hace.h
+++ b/include/hw/misc/aspeed_hace.h
@@ -1,6 +1,7 @@
/*
* ASPEED Hash and Crypto Engine
*
+ * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates
* Copyright (C) 2021 IBM Corp.
*
* SPDX-License-Identifier: GPL-2.0-or-later
@@ -10,6 +11,7 @@
#define ASPEED_HACE_H
#include "hw/sysbus.h"
+#include "crypto/hash.h"
#define TYPE_ASPEED_HACE "aspeed.hace"
#define TYPE_ASPEED_AST2400_HACE TYPE_ASPEED_HACE "-ast2400"
@@ -35,6 +37,8 @@ struct AspeedHACEState {
MemoryRegion *dram_mr;
AddressSpace dram_as;
+
+ QCryptoHash *hash_ctx;
};
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v3 01/12] crypto: accumulative hashing API
2024-08-05 15:50 ` [PATCH v3 01/12] crypto: accumulative hashing API Alejandro Zeise
@ 2024-08-06 15:45 ` Daniel P. Berrangé
0 siblings, 0 replies; 16+ messages in thread
From: Daniel P. Berrangé @ 2024-08-06 15:45 UTC (permalink / raw)
To: Alejandro Zeise
Cc: qemu-arm, kris.conklin, jonathan.henze, evan.burgess, clg,
peter.maydell, qemu-devel
On Mon, Aug 05, 2024 at 03:50:36PM +0000, Alejandro Zeise wrote:
> Changes the hash API to support accumulative hashing.
> Hash objects are created with "qcrypto_hash_new",
> updated with data with "qcrypto_hash_update", and
> the hash obtained with "qcrypto_hash_finalize".
>
> These changes bring the hashing API more in line with the
> hmac API.
>
> Signed-off-by: Alejandro Zeise <alejandro.zeise@seagate.com>
> ---
> crypto/hash.c | 136 +++++++++++++++++++++++++++++++-----------
> crypto/hashpriv.h | 19 ++++--
> include/crypto/hash.h | 106 ++++++++++++++++++++++++++++++++
> 3 files changed, 220 insertions(+), 41 deletions(-)
>
> diff --git a/crypto/hash.c b/crypto/hash.c
> index b0f8228bdc..5c60973bde 100644
> --- a/crypto/hash.c
> +++ b/crypto/hash.c
> @@ -1,6 +1,7 @@
> /*
> * QEMU Crypto hash algorithms
> *
> + * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates
> * Copyright (c) 2015 Red Hat, Inc.
> *
> * This library is free software; you can redistribute it and/or
> @@ -45,23 +46,20 @@ int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
> size_t *resultlen,
> Error **errp)
> {
> -#ifdef CONFIG_AF_ALG
> - int ret;
> - /*
> - * TODO:
> - * Maybe we should treat some afalg errors as fatal
> - */
> - ret = qcrypto_hash_afalg_driver.hash_bytesv(alg, iov, niov,
> - result, resultlen,
> - NULL);
> - if (ret == 0) {
> - return ret;
> + int fail;
> + QCryptoHash *ctx = qcrypto_hash_new(alg, errp);
> +
> + if (ctx) {
> + fail = qcrypto_hash_update(ctx, iov, niov, errp) ||
> + qcrypto_hash_finalize_bytes(ctx, result, resultlen, errp);
> +
> + /* Ensure context is always freed regardless of error */
> + fail = qcrypto_hash_free(ctx) || fail;
> + } else {
> + fail = -1;
> }
> -#endif
>
> - return qcrypto_hash_lib_driver.hash_bytesv(alg, iov, niov,
> - result, resultlen,
> - errp);
> + return fail;
> }
You can't do this conversion in this patch, because all the hash impls
are still using the old driver API, and haven't implemented the new
API yet.
QEMU requires "make check" succeed for *every* individual patch in
a series, so that 'git bisect' can be used in future.
> diff --git a/crypto/hashpriv.h b/crypto/hashpriv.h
> index cee26ccb47..8a7d80619e 100644
> --- a/crypto/hashpriv.h
> +++ b/crypto/hashpriv.h
> @@ -1,6 +1,7 @@
> /*
> * QEMU Crypto hash driver supports
> *
> + * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates
> * Copyright (c) 2017 HUAWEI TECHNOLOGIES CO., LTD.
> *
> * Authors:
> @@ -15,15 +16,21 @@
> #ifndef QCRYPTO_HASHPRIV_H
> #define QCRYPTO_HASHPRIV_H
>
> +#include "crypto/hash.h"
> +
> typedef struct QCryptoHashDriver QCryptoHashDriver;
>
> struct QCryptoHashDriver {
> - int (*hash_bytesv)(QCryptoHashAlgorithm alg,
> - const struct iovec *iov,
> - size_t niov,
> - uint8_t **result,
> - size_t *resultlen,
> - Error **errp);
Keep this present. It can only be removed at the very end of the
series once all the drivers are converted.
> + QCryptoHash *(*hash_new)(QCryptoHashAlgorithm alg, Error **errp);
> + int (*hash_update)(QCryptoHash *hash,
> + const struct iovec *iov,
> + size_t niov,
> + Error **errp);
> + int (*hash_finalize)(QCryptoHash *hash,
> + uint8_t **result,
> + size_t *resultlen,
> + Error **errp);
> + int (*hash_free)(QCryptoHash *hash);
I'd expect 'free' functions to always be 'void'
> diff --git a/include/crypto/hash.h b/include/crypto/hash.h
> index 54d87aa2a1..96d080eeb5 100644
> --- a/include/crypto/hash.h
> +++ b/include/crypto/hash.h
> @@ -1,6 +1,7 @@
> /*
> * QEMU Crypto hash algorithms
> *
> + * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates
> * Copyright (c) 2015 Red Hat, Inc.
> *
> * This library is free software; you can redistribute it and/or
> @@ -25,6 +26,13 @@
>
> /* See also "QCryptoHashAlgorithm" defined in qapi/crypto.json */
>
> +typedef struct QCryptoHash QCryptoHash;
> +struct QCryptoHash {
> + QCryptoHashAlgorithm alg;
> + void *opaque;
> + void *driver;
> +};
> +
> /**
> * qcrypto_hash_supports:
> * @alg: the hash algorithm
> @@ -120,6 +128,102 @@ int qcrypto_hash_digestv(QCryptoHashAlgorithm alg,
> char **digest,
> Error **errp);
>
> +/**
> + * qcrypto_hash_update:
> + * @hash: hash object from qcrypto_hash_new
> + * @iov: the array of memory regions to hash
> + * @niov: the length of @iov
> + * @errp: pointer to a NULL-initialized error object
> + *
> + * Updates the given hash object with all the memory regions
> + * present in @iov.
> + *
> + * Returns: 0 on success, -1 on error
> + */
> +int qcrypto_hash_update(QCryptoHash *hash,
> + const struct iovec *iov,
> + size_t niov,
> + Error **errp);
This should be renamed 'qcrypto_hash_updatev', and we should have a
separate non-iovec variant
int qcrypto_hash_update(QCryptoHash *hash,
const char *data,
size_t len,
Error **errp);
This can simply pack data+len into an iovec, and then call
qcrypto_hash_updatev.
> +
> +/**
> + * qcrypto_hash_finalize_digest:
> + * @hash: the hash object to finalize
> + * @digest: pointer to hold output hash
> + * @errp: pointer to a NULL-initialized error object
> + *
> + * Computes the hash from the given hash object. Hash object
> + * is expected to have its data updated from the qcrypto_hash_update function.
> + * The @digest pointer will be filled with the printable hex digest of the
> + * computed hash, which will be terminated by '\0'. The memory pointer
> + * in @digest must be released with a call to g_free() when
> + * no longer required.
> + *
> + * Returns: 0 on success, -1 on error
> + */
> +int qcrypto_hash_finalize_digest(QCryptoHash *hash,
> + char **digest,
> + Error **errp);
> +
> +/**
> + * qcrypto_hash_finalize_base64:
> + * @hash_ctx: hash object to finalize
s/hash_ctx/hash/
> + * @base64: pointer to store the hash result in
> + * @errp: pointer to a NULL-initialized error object
> + *
> + * Computes the hash from the given hash object. Hash object
> + * is expected to have it's data updated from the qcrypto_hash_update function.
> + * The @base64 pointer will be filled with the base64 encoding of the computed
> + * hash, which will be terminated by '\0'. The memory pointer in @base64
> + * must be released with a call to g_free() when no longer required.
> + *
> + * Returns: 0 on success, -1 on error
> + */
> +int qcrypto_hash_finalize_base64(QCryptoHash *hash,
> + char **base64,
> + Error **errp);
> +
> +/**
> + * qcrypto_hash_finalize_bytes:
> + * @hash_ctx: hash object to finalize
> + * @result: pointer to store the hash result in
> + * @result_len: Pointer to store the length of the result in
> + * @errp: pointer to a NULL-initialized error object
> + *
> + * Computes the hash from the given hash object. Hash object
> + * is expected to have it's data updated from the qcrypto_hash_update function.
> + * The memory pointer in @result must be released with a call to g_free()
> + * when no longer required.
> + *
> + * Returns: 0 on success, -1 on error
> + */
> +int qcrypto_hash_finalize_bytes(QCryptoHash *hash,
> + uint8_t **result,
> + size_t *result_len,
> + Error **errp);
> +
> +/**
> + * qcrypto_hash_new:
> + * @alg: the hash algorithm
> + * @errp: pointer to a NULL-initialized error object
> + *
> + * Creates a new hashing context for the chosen algorithm for
> + * usage with qcrypto_hash_update.
> + *
> + * Returns: New hash object with the given algorithm
.... ", or NULL on error"
> + */
> +QCryptoHash *qcrypto_hash_new(QCryptoHashAlgorithm alg,
> + Error **errp);
> +
> +/**
> + * qcrypto_hash_free:
> + * @hash: hash object to free
> + *
> + * Frees a hashing context for the chosen algorithm.
> + *
> + * Returns: 0 on success, -1 on error
> + */
> +int qcrypto_hash_free(QCryptoHash *hash);
Again I'd expect this to be 'void' and have a g_autoptr support
added using:
G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoHash, qcrypto_hash_free)
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations
2024-08-05 15:50 [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations Alejandro Zeise
` (11 preceding siblings ...)
2024-08-05 15:50 ` [PATCH v3 12/12] hw/misc/aspeed_hace: Fix SG Accumulative hashing Alejandro Zeise
@ 2024-08-06 15:52 ` Daniel P. Berrangé
2024-08-06 18:51 ` Alejandro Zeise
12 siblings, 1 reply; 16+ messages in thread
From: Daniel P. Berrangé @ 2024-08-06 15:52 UTC (permalink / raw)
To: Alejandro Zeise
Cc: qemu-arm, kris.conklin, jonathan.henze, evan.burgess, clg,
peter.maydell, qemu-devel
On Mon, Aug 05, 2024 at 03:50:35PM +0000, Alejandro Zeise wrote:
> The goal of this patch series is to fix accumulative hashing support in the
> Aspeed HACE module. The issue that stemmed this patch was a failure to boot an
> OpenBMC image using the "ast2600-evb" machine. The U-boot
> 2019.04 loader failed to verify image hashes.
>
> These incorrect image hashes given by the HACE to the U-boot guest are due to
> an oversight in the HACE module. Previously when operating in
> scatter-gather accumulative mode, the HACE would cache the address provided by
> the guest which contained the source data. However, there was no deep copy,
> so when HACE generated the digest upon the reception of the final accumulative chunk
> the digest was incorrect, as the addresses provided had their regions overwritten
> by that time.
>
> This fix consists of two main steps:
> * Add an accumulative hashing function to the qcrypto library
> * Modify the HACE module to use the accumulative hashing functions
>
> All the crypto library backends (nettle, gnutls, etc.) support accumulative hashing,
> so it was trivial to create wrappers for those functions.
>
> Changes in V3:
> * Reworked crypto hash API with comments from Daniel
> * Creation/Deletion of contexts, updating, and finalizing
> * Modified existing API functions to use the new 4 main core functions
> * Added test for accumulative hashing
> * Added afalg driver implementation
> * Fixed bug in HACE module where hash context fails to allocate,
> causing the HACE internal state to be incorrect and segfault.
>
> Changes in V2:
> * Fixed error checking bug in libgcrypt crypto backend of
> accumulate_bytesv
>
> Alejandro Zeise (12):
> crypto: accumulative hashing API
> crypto/hash-glib: Remove old hash API implementation
> crypto/hash-glib: Implement new hash API
> crypto/hash-gcrypt: Remove old hash API implementation
> crypto/hash-gcrypt: Implement new hash API
> crypto/hash-gnutls: Remove old hash API
> crypto/hash-gnutls: Implement new hash API
> crypto/hash-nettle: Remove old hash API
> crypto/hash-nettle: Implement new hash API
> crypto/hash-afalg: Update to new API
> tests/unit/test-crypto-hash: accumulative hashing
> hw/misc/aspeed_hace: Fix SG Accumulative hashing
To allow 'make check' to succeed at every individual patch, you'll need to
re-order these, and split a couple of patches, to be more or less like this:
crypto: accumulative hashing API (only define new driver APIs & new public APIs here)
crypto/hash-glib: Implement new hash API
crypto/hash-gcrypt: Implement new hash API
crypto/hash-gnutls: Implement new hash API
crypto/hash-nettle: Implement new hash API
crypto/hash-afalg: Update to new API (only add new APIs here )
< convert old public APIs to call the new driver APIs here>
tests/unit/test-crypto-hash: accumulative hashing
crypto/hash-glib: Remove old hash API implementation
crypto/hash-gcrypt: Remove old hash API implementation
crypto/hash-gnutls: Remove old hash API
crypto/hash-nettle: Remove old hash API
< remove old afalg support here >
< remove old driver APIs here >
hw/misc/aspeed_hace: Fix SG Accumulative hashing
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 16+ messages in thread
* RE: [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations
2024-08-06 15:52 ` [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations Daniel P. Berrangé
@ 2024-08-06 18:51 ` Alejandro Zeise
0 siblings, 0 replies; 16+ messages in thread
From: Alejandro Zeise @ 2024-08-06 18:51 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-arm@nongnu.org, Kris Conklin, Jonathan Henze, Evan Burgess,
clg@kaod.org, peter.maydell@linaro.org, qemu-devel@nongnu.org
> To allow 'make check' to succeed at every individual patch, you'll need to re-order these, and split a couple of patches, to be more or less like this:
>
> crypto: accumulative hashing API (only define new driver APIs & new public APIs here)
> crypto/hash-glib: Implement new hash API
> crypto/hash-gcrypt: Implement new hash API
> crypto/hash-gnutls: Implement new hash API
> crypto/hash-nettle: Implement new hash API
> crypto/hash-afalg: Update to new API (only add new APIs here )
> < convert old public APIs to call the new driver APIs here>
> tests/unit/test-crypto-hash: accumulative hashing
> crypto/hash-glib: Remove old hash API implementation
> crypto/hash-gcrypt: Remove old hash API implementation
> crypto/hash-gnutls: Remove old hash API
> crypto/hash-nettle: Remove old hash API
> < remove old afalg support here >
> < remove old driver APIs here >
> hw/misc/aspeed_hace: Fix SG Accumulative hashing
Apologies, I will reorder the patches so that 'make check' works independently and take your other comments into account.
Thank you for the feedback,
Alejandro
Seagate Internal
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2024-08-06 18:53 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-05 15:50 [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 01/12] crypto: accumulative hashing API Alejandro Zeise
2024-08-06 15:45 ` Daniel P. Berrangé
2024-08-05 15:50 ` [PATCH v3 02/12] crypto/hash-glib: Remove old hash API implementation Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 03/12] crypto/hash-glib: Implement new hash API Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 04/12] crypto/hash-gcrypt: Remove old hash API implementation Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 05/12] crypto/hash-gcrypt: Implement new hash API Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 06/12] crypto/hash-gnutls: Remove old " Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 07/12] crypto/hash-gnutls: Implement new " Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 08/12] crypto/hash-nettle: Remove old " Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 09/12] crypto/hash-nettle: Implement new " Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 10/12] crypto/hash-afalg: Update to new API Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 11/12] tests/unit/test-crypto-hash: accumulative hashing Alejandro Zeise
2024-08-05 15:50 ` [PATCH v3 12/12] hw/misc/aspeed_hace: Fix SG Accumulative hashing Alejandro Zeise
2024-08-06 15:52 ` [PATCH v3 00/12] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations Daniel P. Berrangé
2024-08-06 18:51 ` Alejandro Zeise
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).