qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Cédric Le Goater" <clg@kaod.org>
To: Alejandro Zeise <alejandro.zeise@seagate.com>, qemu-arm@nongnu.org
Cc: qemu-devel@nongnu.org, peter.maydell@linaro.org, berrange@redhat.com
Subject: Re: [PATCH v2 1/2] crypto: add support for accumulative hashing
Date: Tue, 30 Jul 2024 17:58:38 +0200	[thread overview]
Message-ID: <fdc53976-2000-46cd-a65a-c9976fc8c9d1@kaod.org> (raw)
In-Reply-To: <20240729190035.3419649-2-alejandro.zeise@seagate.com>

On 7/29/24 21:00, Alejandro Zeise wrote:
> This change adds an accumulative hashing function
> (qcrypto_hash_accumulate_bytesv) and implementation
> for each of the crypto library backends that QEMU supports.
> 
> The QCrypto API did not support hashing in an accumulative mode.
> As such, hardware hash modules (like the HACE from Aspeed's SoCs) are
> unable to perform such operations correctly when the guest requires it.
> 
> The creation and freeing of each library's context is abstracted by
> the qcrypto_hash_accumulate_new_ctx and qcrypto_hash_accumulate_free_ctx
> functions.
> 
> Changes in V2:
> * Fixed error checking bug in libgcrypt backend
> 
> Signed-off-by: Alejandro Zeise <alejandro.zeise@seagate.com>
> ---
>   crypto/hash-gcrypt.c  | 105 ++++++++++++++++++++++++++++++++++++++++++
>   crypto/hash-glib.c    |  89 +++++++++++++++++++++++++++++++++++
>   crypto/hash-gnutls.c  |  82 +++++++++++++++++++++++++++++++++
>   crypto/hash-nettle.c  |  93 +++++++++++++++++++++++++++++++++++++
>   crypto/hash.c         |  42 +++++++++++++++++
>   crypto/hashpriv.h     |  11 +++++
>   include/crypto/hash.h |  65 ++++++++++++++++++++++++++
>   7 files changed, 487 insertions(+)
> 
> diff --git a/crypto/hash-gcrypt.c b/crypto/hash-gcrypt.c
> index 829e48258d..6ef7e67711 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
> @@ -110,7 +111,111 @@ qcrypto_gcrypt_hash_bytesv(QCryptoHashAlgorithm alg,
>       return -1;
>   }
>   
> +static
> +int qcrypto_gcrypt_hash_accumulate_new_ctx(QCryptoHashAlgorithm alg,
> +                                           qcrypto_hash_accumulate_ctx_t **accumulate_ctx,
> +                                           Error **errp)
> +{
> +    int ret;
> +
> +    if (!qcrypto_hash_supports(alg)) {
> +        error_setg(errp,
> +                   "Unknown hash algorithm %d",
> +                   alg);
> +        return -1;
> +    }
> +
> +    ret = gcry_md_open((gcry_md_hd_t *) accumulate_ctx, qcrypto_hash_alg_map[alg], 0);
> +
> +    if (ret < 0) {
> +        error_setg(errp,
> +                   "Unable to initialize hash algorithm: %s",
> +                   gcry_strerror(ret));
> +        return -1;
> +    }
> +
> +    return 0;
> +}
> +
> +static
> +int qcrypto_gcrypt_hash_accumulate_free_ctx(qcrypto_hash_accumulate_ctx_t *hash_ctx,
> +                                            Error **errp)
> +{
> +    if (hash_ctx != NULL) {
> +        gcry_md_close((gcry_md_hd_t) hash_ctx);
> +    }
> +
> +    return 0;
> +}
> +
> +static
> +int qcrypto_gcrypt_hash_accumulate_bytesv(QCryptoHashAlgorithm alg,
> +                                          qcrypto_hash_accumulate_ctx_t *accumulate_ctx,
> +                                          const struct iovec *iov,
> +                                          size_t niov,
> +                                          uint8_t **result,
> +                                          size_t *resultlen,
> +                                          Error **errp)
> +{
> +    int i, ret;
> +    gcry_md_hd_t ctx_copy;
> +    unsigned char *digest;
> +
> +    if (!qcrypto_hash_supports(alg)) {
> +        error_setg(errp,
> +                   "Unknown hash algorithm %d",
> +                   alg);
> +        return -1;
> +    }
> +
> +    for (i = 0; i < niov; i++) {
> +        gcry_md_write((gcry_md_hd_t) accumulate_ctx, 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));
> +        return -1;
> +    }
> +
> +    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;
> +    }
> +
> +    /*
> +     * Make a copy so we don't distort the main context
> +     * by calculating the intermediate hash
> +     */
> +    ret = gcry_md_copy(&ctx_copy, (gcry_md_hd_t) accumulate_ctx);
> +    if (ret) {
> +        error_setg(errp, "Unable to make copy: %s", gcry_strerror(ret));
> +        return -1;
> +    }
> +
> +    digest = gcry_md_read(ctx_copy, 0);
> +    if (!digest) {
> +        error_setg(errp,
> +                   "No digest produced");
> +        return -1;
> +    }
> +    memcpy(*result, digest, *resultlen);
> +    gcry_md_close(ctx_copy);
> +
> +    return 0;
> +}
> +
>   
>   QCryptoHashDriver qcrypto_hash_lib_driver = {
>       .hash_bytesv = qcrypto_gcrypt_hash_bytesv,
> +    .hash_accumulate_bytesv = qcrypto_gcrypt_hash_accumulate_bytesv,
> +    .accumulate_new_ctx = qcrypto_gcrypt_hash_accumulate_new_ctx,
> +    .accumulate_free_ctx = qcrypto_gcrypt_hash_accumulate_free_ctx,
>   };
> diff --git a/crypto/hash-glib.c b/crypto/hash-glib.c
> index 82de9db705..c0d1d72c88 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
> @@ -95,6 +96,94 @@ qcrypto_glib_hash_bytesv(QCryptoHashAlgorithm alg,
>   }
>   
>   
> +static
> +int qcrypto_glib_hash_accumulate_new_ctx(QCryptoHashAlgorithm alg,
> +                                         qcrypto_hash_accumulate_ctx_t **accumulate_ctx,
> +                                         Error **errp)
> +{
> +    if (!qcrypto_hash_supports(alg)) {
> +        error_setg(errp,
> +                   "Unknown hash algorithm %d",
> +                   alg);
> +        return -1;
> +    }
> +
> +    *accumulate_ctx = g_checksum_new(qcrypto_hash_alg_map[alg]);
> +
> +    return 0;
> +}
> +
> +static
> +int qcrypto_glib_hash_accumulate_free_ctx(qcrypto_hash_accumulate_ctx_t *hash_ctx,
> +                                          Error **errp)
> +{
> +    if (hash_ctx != NULL) {
> +        g_checksum_free((GChecksum *) hash_ctx);
> +    }
> +
> +    return 0;
> +}
> +
> +
> +static
> +int qcrypto_glib_hash_accumulate_bytesv(QCryptoHashAlgorithm alg,
> +                                        qcrypto_hash_accumulate_ctx_t *accumulate_ctx,
> +                                        const struct iovec *iov,
> +                                        size_t niov,
> +                                        uint8_t **result,
> +                                        size_t *resultlen,
> +                                        Error **errp)
> +{
> +    int i, ret;
> +    GChecksum *ctx_copy;
> +
> +    if (!qcrypto_hash_supports(alg)) {
> +        error_setg(errp,
> +                   "Unknown hash algorithm %d",
> +                   alg);
> +        return -1;
> +    }
> +
> +    for (i = 0; i < niov; i++) {
> +        g_checksum_update((GChecksum *) accumulate_ctx, 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");
> +        return -1;
> +    }
> +    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;
> +    }
> +
> +    /*
> +    Make a copy so we don't distort the main context
> +    by calculating the intermediate hash.
> +    */
> +    ctx_copy = g_checksum_copy((GChecksum *) accumulate_ctx);
> +    if (ctx_copy == NULL) {
> +        error_setg(errp, "Unable to make copy: %s", __func__);
> +        return -1;
> +    }
> +
> +    g_checksum_get_digest((GChecksum *) ctx_copy, *result, resultlen);
> +    g_checksum_free(ctx_copy);
> +
> +    return 0;
> +}
> +
> +
>   QCryptoHashDriver qcrypto_hash_lib_driver = {
>       .hash_bytesv = qcrypto_glib_hash_bytesv,
> +    .hash_accumulate_bytesv = qcrypto_glib_hash_accumulate_bytesv,
> +    .accumulate_new_ctx = qcrypto_glib_hash_accumulate_new_ctx,
> +    .accumulate_free_ctx = qcrypto_glib_hash_accumulate_free_ctx,
>   };
> diff --git a/crypto/hash-gnutls.c b/crypto/hash-gnutls.c
> index 17911ac5d1..9464893213 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
> @@ -99,6 +100,87 @@ qcrypto_gnutls_hash_bytesv(QCryptoHashAlgorithm alg,
>   }
>   
>   
> +static
> +int qcrypto_gnutls_hash_accumulate_new_ctx(QCryptoHashAlgorithm alg,
> +                                           qcrypto_hash_accumulate_ctx_t **hash_ctx,
> +                                           Error **errp)
> +{
> +    int ret;
> +
> +    if (!qcrypto_hash_supports(alg)) {
> +        error_setg(errp,
> +                   "Unknown hash algorithm %d",
> +                   alg);
> +        return -1;
> +    }
> +
> +    ret = gnutls_hash_init((gnutls_hash_hd_t *) hash_ctx, qcrypto_hash_alg_map[alg]);
> +    if (ret < 0) {
> +        error_setg(errp,
> +                   "Unable to initialize hash algorithm: %s",
> +                   gnutls_strerror(ret));
> +        return -1;
> +    }
> +
> +    return 0;
> +}
> +
> +static
> +int qcrypto_gnutls_hash_accumulate_free_ctx(qcrypto_hash_accumulate_ctx_t *hash_ctx,
> +                                            Error **errp)
> +{
> +    if (hash_ctx != NULL) {
> +        gnutls_hash_deinit((gnutls_hash_hd_t) hash_ctx, NULL);
> +    }
> +
> +    return 0;
> +}
> +
> +static
> +int qcrypto_gnutls_hash_accumulate_bytesv(QCryptoHashAlgorithm alg,
> +                                          qcrypto_hash_accumulate_ctx_t *hash_ctx,
> +                                          const struct iovec *iov,
> +                                          size_t niov,
> +                                          uint8_t **result,
> +                                          size_t *resultlen,
> +                                          Error **errp)
> +{
> +    int i, ret;
> +
> +    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;
> +    }
> +
> +    for (i = 0; i < niov; i++) {
> +        gnutls_hash((gnutls_hash_hd_t) hash_ctx,
> +                    iov[i].iov_base, iov[i].iov_len);
> +    }
> +
> +    /* Make a copy so we don't distort the main context */
> +    gnutls_hash_hd_t copy = gnutls_hash_copy((gnutls_hash_hd_t) hash_ctx);
> +    gnutls_hash_deinit(copy, *result);
> +
> +    return 0;
> +}
> +
> +
>   QCryptoHashDriver qcrypto_hash_lib_driver = {
>       .hash_bytesv = qcrypto_gnutls_hash_bytesv,
> +    .hash_accumulate_bytesv = qcrypto_gnutls_hash_accumulate_bytesv,
> +    .accumulate_new_ctx = qcrypto_gnutls_hash_accumulate_new_ctx,
> +    .accumulate_free_ctx = qcrypto_gnutls_hash_accumulate_free_ctx,
>   };
> diff --git a/crypto/hash-nettle.c b/crypto/hash-nettle.c
> index 1ca1a41062..e21d0c6cf9 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
> @@ -155,7 +156,99 @@ qcrypto_nettle_hash_bytesv(QCryptoHashAlgorithm alg,
>       return 0;
>   }
>   
> +static
> +int qcrypto_nettle_hash_accumulate_new_ctx(QCryptoHashAlgorithm alg,
> +                                           qcrypto_hash_accumulate_ctx_t **hash_ctx,
> +                                           Error **errp)
> +{
> +    if (!qcrypto_hash_supports(alg)) {
> +        error_setg(errp,
> +                   "Unknown hash algorithm %d",
> +                   alg);
> +        return -1;
> +    }
> +
> +    *((union qcrypto_hash_ctx **) hash_ctx) = g_malloc(sizeof(union qcrypto_hash_ctx));
> +
> +    qcrypto_hash_alg_map[alg].init(*((union qcrypto_hash_ctx **) accumulate_ctx));
> +
> +    return 0;
> +}
> +
> +static
> +int qcrypto_nettle_hash_accumulate_free_ctx(qcrypto_hash_accumulate_ctx_t *hash_ctx,
> +                                            Error **errp)
> +{
> +    g_free((union qcrypto_hash_ctx *) hash_ctx);
> +    return 0;
> +}
> +
> +static
> +int qcrypto_nettle_hash_accumulate_bytesv(QCryptoHashAlgorithm alg,
> +                                          qcrypto_hash_accumulate_ctx_t *hash_ctx,
> +                                          const struct iovec *iov,
> +                                          size_t niov,
> +                                          uint8_t **result,
> +                                          size_t *resultlen,
> +                                          Error **errp)
> +{
> +    union qcrypto_hash_ctx *ctx_copy;
> +    int i;
> +
> +    if (!qcrypto_hash_supports(alg)) {
> +        error_setg(errp,
> +                   "Unknown hash algorithm %d",
> +                   alg);
> +        return -1;
> +    }
> +
> +    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((union qcrypto_hash_ctx *) hash_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;
> +    }
> +
> +    /*
> +    Make a copy so we don't distort the main context
> +    by calculating the intermediate hash
> +    */
> +    ctx_copy = g_new(union qcrypto_hash_ctx, 1);
> +    memcpy(ctx_copy, (union qcrypto_hash_ctx *) hash_ctx,
> +           sizeof(union qcrypto_hash_ctx));
> +
> +    qcrypto_hash_alg_map[alg].result(ctx_copy,
> +                                     *resultlen, *result);
> +
> +    g_free(ctx_copy);
> +
> +    return 0;
> +}
> +
>   
>   QCryptoHashDriver qcrypto_hash_lib_driver = {
>       .hash_bytesv = qcrypto_nettle_hash_bytesv,
> +    .hash_accumulate_bytesv = qcrypto_nettle_hash_accumulate_bytesv,
> +    .accumulate_new_ctx = qcrypto_nettle_hash_accumulate_new_ctx,
> +    .accumulate_free_ctx = qcrypto_nettle_hash_accumulate_free_ctx,
>   };
> diff --git a/crypto/hash.c b/crypto/hash.c
> index b0f8228bdc..0d45ce1e1b 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
> @@ -77,6 +78,47 @@ int qcrypto_hash_bytes(QCryptoHashAlgorithm alg,
>       return qcrypto_hash_bytesv(alg, &iov, 1, result, resultlen, errp);
>   }
>   
> +int qcrypto_hash_accumulate_bytesv(QCryptoHashAlgorithm alg,
> +                                   qcrypto_hash_accumulate_ctx_t *accumulate_ctx,
> +                                   const struct iovec *iov,
> +                                   size_t niov,
> +                                   uint8_t **result,
> +                                   size_t *resultlen,
> +                                   Error **errp)
> +{
> +#ifdef CONFIG_AF_ALG
> +    qemu_log_mask(LOG_UNIMP, "%s: AF_ALG support unimplemented.\n", __func__);
> +    return 1;
> +#else
> +    return qcrypto_hash_lib_driver.hash_accumulate_bytesv(alg, accumulate_ctx,
> +                                                          iov, niov, result,
> +                                                          resultlen, NULL);
> +#endif /* CONFIG_AF_ALG */
> +}
> +
> +int qcrypto_hash_accumulate_new_ctx(QCryptoHashAlgorithm alg,
> +                                    qcrypto_hash_accumulate_ctx_t **accumulate_ctx,
> +                                    Error **errp)
> +{
> +#ifdef CONFIG_AF_ALG
> +    qemu_log_mask(LOG_UNIMP, "%s: AF_ALG support unimplemented.\n", __func__);
> +    return 1;
> +#else
> +    return qcrypto_hash_lib_driver.accumulate_new_ctx(alg, accumulate_ctx, errp);
> +#endif /* CONFIG_AF_ALG */
> +}
> +
> +int qcrypto_hash_accumulate_free_ctx(qcrypto_hash_accumulate_ctx_t *accumulate_ctx,
> +                                     Error **errp)
> +{
> +#ifdef CONFIG_AF_ALG
> +    qemu_log_mask(LOG_UNIMP, "%s: AF_ALG support unimplemented.\n", __func__);
> +    return 1;
> +#else
> +    return qcrypto_hash_lib_driver.accumulate_free_ctx(accumulate_ctx, errp);
> +#endif /* CONFIG_AF_ALG */
> +}
> +
>   static const char hex[] = "0123456789abcdef";
>   
>   int qcrypto_hash_digestv(QCryptoHashAlgorithm alg,
> diff --git a/crypto/hashpriv.h b/crypto/hashpriv.h
> index cee26ccb47..49b3927208 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:
> @@ -24,6 +25,16 @@ struct QCryptoHashDriver {
>                          uint8_t **result,
>                          size_t *resultlen,
>                          Error **errp);
> +    int (*hash_accumulate_bytesv)(QCryptoHashAlgorithm alg,
> +                                  void *hash_ctx,
> +                                  const struct iovec *iov,
> +                                  size_t niov,
> +                                  uint8_t **result,
> +                                  size_t *resultlen,
> +                                  Error **errp);
> +    int (*accumulate_new_ctx)(QCryptoHashAlgorithm alg, void **hash_ctx,
> +                              Error **errp);
> +    int (*accumulate_free_ctx)(void *hash_ctx, Error **errp);
>   };
>   
>   extern QCryptoHashDriver qcrypto_hash_lib_driver;
> diff --git a/include/crypto/hash.h b/include/crypto/hash.h
> index 54d87aa2a1..fb8ae2d099 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,8 @@
>   
>   /* See also "QCryptoHashAlgorithm" defined in qapi/crypto.json */
>   
> +typedef void qcrypto_hash_accumulate_ctx_t;


QCryptoHmac defines a similar API. I would do the same for the hash
accumulative mode. See hmac files.

Thanks,

C.

  

  
> +
>   /**
>    * qcrypto_hash_supports:
>    * @alg: the hash algorithm
> @@ -120,6 +123,68 @@ int qcrypto_hash_digestv(QCryptoHashAlgorithm alg,
>                            char **digest,
>                            Error **errp);
>   
> +/**
> + * qcrypto_hash_accumulate_bytesv:
> + * @alg: the hash algorithm
> + * @accumulate_ctx: pointer to the algorithm's context for further hash operations
> + * @iov: the array of memory regions to hash
> + * @niov: the length of @iov
> + * @result: pointer to hold output hash
> + * @resultlen: pointer to hold length of @result
> + * @errp: pointer to a NULL-initialized error object
> + *
> + * Computes the hash across all the memory regions
> + * present in @iov using the existing hash context
> + * given in @accumulate_ctx. The @result pointer will be
> + * filled with raw bytes representing the computed
> + * hash, which will have length @resultlen. 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_accumulate_bytesv(QCryptoHashAlgorithm alg,
> +                                   qcrypto_hash_accumulate_ctx_t *accumulate_ctx,
> +                                   const struct iovec *iov,
> +                                   size_t niov,
> +                                   uint8_t **result,
> +                                   size_t *resultlen,
> +                                   Error **errp);
> +
> +/**
> + * qcrypto_hash_accumulate_new_ctx:
> + * @alg: the hash algorithm
> + * @accumulate_ctx: pointer to the pointer holding the algorithm's
> + *                  context for further hash operations. The pointer will
> + *                  be modified to point to the memory this function
> + *                  allocates to hold the context.
> + * @errp: pointer to a NULL-initialized error object
> + *
> + * Creates a new hashing context for the chosen algorithm for
> + * usage with qcrypto_hash_accumulate_bytesv().
> + * This is useful for when one has multiple inputs to compute a hash, but
> + * not all are available at a single point in time, making qcrypto_hash_bytesv()
> + * inadequate. The @accumulate_ctx pointer must be released with a call to
> + * qcrypto_hash_accumulate_free_ctx() once all hash operations are complete.
> + *
> + * Returns: 0 on success, -1 on error
> + */
> +int qcrypto_hash_accumulate_new_ctx(QCryptoHashAlgorithm alg,
> +                                    qcrypto_hash_accumulate_ctx_t **accumulate_ctx,
> +                                    Error **errp);
> +
> +/**
> + * qcrypto_hash_accumulate_free_ctx:
> + * @accumulate_ctx: pointer to the algorithm's context for further hash operations
> + * @errp: pointer to a NULL-initialized error object
> + *
> + * frees a hashing context for the chosen algorithm.
> + *
> + * Returns: 0 on success, -1 on error
> + */
> +int qcrypto_hash_accumulate_free_ctx(qcrypto_hash_accumulate_ctx_t *accumulate_ctx,
> +                                     Error **errp);
> +
>   /**
>    * qcrypto_hash_digest:
>    * @alg: the hash algorithm



  reply	other threads:[~2024-07-30 15:59 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-29 19:00 [PATCH v2 0/2] hw/misc/aspeed_hace: Fix SG Accumulative Hash Calculations Alejandro Zeise
2024-07-29 19:00 ` [PATCH v2 1/2] crypto: add support for accumulative hashing Alejandro Zeise
2024-07-30 15:58   ` Cédric Le Goater [this message]
2024-07-30 16:34     ` Daniel P. Berrangé
2024-07-30 16:26   ` Daniel P. Berrangé
2024-07-29 19:00 ` [PATCH v2 2/2] hw/misc/aspeed_hace: Fix SG Accumulative hashing Alejandro Zeise
2024-07-30  7:03   ` Philippe Mathieu-Daudé
2024-07-30 10:54   ` Cédric Le Goater
2024-07-30 16:01     ` Alejandro Zeise

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fdc53976-2000-46cd-a65a-c9976fc8c9d1@kaod.org \
    --to=clg@kaod.org \
    --cc=alejandro.zeise@seagate.com \
    --cc=berrange@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).