From 330ddb7adba33aec6ca1c5dcc85bd20a12913a3e Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Thu, 29 Sep 2022 08:15:44 +0000 Subject: [PATCH] libpv: add `copied` parameter to `pv_gbytes_memcpy` and adapt pvattest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's often useful to know how much data was actually copied, therefore let's introduce an nullable parameter `@copied` to `pv_gbytes_memcpy`. Signed-off-by: Marc Hartmayer Reviewed-by: Steffen Eiden Signed-off-by: Jan Höppner --- include/libpv/glib-helper.h | 7 +++++-- libpv/glib-helper.c | 4 +++- pvattest/src/arcb.c | 8 ++++---- pvattest/src/attestation.c | 2 +- pvattest/src/uvio.c | 10 +++++----- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/include/libpv/glib-helper.h b/include/libpv/glib-helper.h index 6dcd8532..5d3df50b 100644 --- a/include/libpv/glib-helper.h +++ b/include/libpv/glib-helper.h @@ -102,9 +102,12 @@ FILE *pv_file_open(const char *filename, const char *mode, GError **error); /** pv_gbytes_memcpy: * - * memcpy with size check. + * memcpy with size check. In case @dst_size is smaller than the size of @src + * the error value %NULL is returned and @copied and @dst are left unchanged. + * + * If @dst and @src data overlap, the behavior is undefined. */ -void *pv_gbytes_memcpy(void *dst, size_t dst_size, GBytes *src); +void *pv_gbytes_memcpy(void *dst, size_t dst_size, GBytes *src, size_t *copied); #define PV_GLIB_HELPER_ERROR g_quark_from_static_string("pv-glib-helper_error-quark") typedef enum { diff --git a/libpv/glib-helper.c b/libpv/glib-helper.c index fe89dd75..3e7bff76 100644 --- a/libpv/glib-helper.c +++ b/libpv/glib-helper.c @@ -168,12 +168,14 @@ GBytes *pv_file_get_content_as_secure_bytes(const char *filename) return pv_sec_gbytes_new_take(g_steal_pointer(&data), data_size); } -void *pv_gbytes_memcpy(void *dst, size_t dst_size, GBytes *src) +void *pv_gbytes_memcpy(void *dst, size_t dst_size, GBytes *src, size_t *copied) { size_t src_size; const void *src_data = g_bytes_get_data(src, &src_size); if (dst_size < src_size) return NULL; + if (copied) + *copied = src_size; return memcpy(dst, src_data, src_size); } diff --git a/pvattest/src/arcb.c b/pvattest/src/arcb.c index e2f96c75..71339429 100644 --- a/pvattest/src/arcb.c +++ b/pvattest/src/arcb.c @@ -171,9 +171,9 @@ int arcb_v1_add_key_slot(arcb_v1_t *arcb, EVP_PKEY *evp_host, GError **error) g_assert(g_bytes_get_size(phkh) == sizeof(key_slot->phkh)); key_slot = g_malloc0(sizeof(*key_slot)); - pv_gbytes_memcpy(key_slot->warpk, sizeof(key_slot->warpk), warpk); - pv_gbytes_memcpy(key_slot->kst, sizeof(key_slot->warpk), tag); - pv_gbytes_memcpy(key_slot->phkh, sizeof(key_slot->warpk), phkh); + pv_gbytes_memcpy(key_slot->warpk, sizeof(key_slot->warpk), warpk, NULL); + pv_gbytes_memcpy(key_slot->kst, sizeof(key_slot->warpk), tag, NULL); + pv_gbytes_memcpy(key_slot->phkh, sizeof(key_slot->warpk), phkh, NULL); arcb->host_key_slots = g_slist_prepend(arcb->host_key_slots, g_steal_pointer(&key_slot)); return 0; @@ -246,7 +246,7 @@ GBytes *arcb_v1_serialize(const arcb_v1_t *arcb, GError **error) /* copy plain data to contiguous memory */ hdr.arl = GUINT32_TO_BE((uint32_t)att_req_len); - pv_gbytes_memcpy(hdr.iv, ARCB_V1_IV_SIZE, arcb->iv); + pv_gbytes_memcpy(hdr.iv, ARCB_V1_IV_SIZE, arcb->iv, NULL); hdr.nks = (uint8_t)nks; hdr.sea = GUINT32_TO_BE((uint32_t)sea); ecdh_cpk = pv_evp_pkey_to_ecdh_pub_key(arcb->evp_cust_pub_key, error); diff --git a/pvattest/src/attestation.c b/pvattest/src/attestation.c index 741b74e9..1631109c 100644 --- a/pvattest/src/attestation.c +++ b/pvattest/src/attestation.c @@ -130,7 +130,7 @@ void att_add_uid(att_meas_ctx_t *meas_ctx, GBytes *config_uid) pv_wrapped_g_assert(config_uid); g_assert(g_bytes_get_size(config_uid) == ATT_CONFIG_UID_SIZE); - pv_gbytes_memcpy(meas_ctx->config_uid, ATT_CONFIG_UID_SIZE, config_uid); + pv_gbytes_memcpy(meas_ctx->config_uid, ATT_CONFIG_UID_SIZE, config_uid, NULL); } gboolean att_verify_measurement(const GBytes *calculated_measurement, diff --git a/pvattest/src/uvio.c b/pvattest/src/uvio.c index 1f784067..944040fd 100644 --- a/pvattest/src/uvio.c +++ b/pvattest/src/uvio.c @@ -48,17 +48,17 @@ uvio_attest_t *build_attestation_v1_ioctl(GBytes *serialized_arcb, GBytes *user_ g_steal_pointer(&serialized_arcb); if (user_data) { - size_t user_data_size = g_bytes_get_size(user_data); + size_t copied_data_size; - if (user_data_size > sizeof(uvio_attest->user_data)) { + if (pv_gbytes_memcpy(uvio_attest->user_data, sizeof(uvio_attest->user_data), + user_data, &copied_data_size) == NULL) { g_set_error(error, ATT_ERROR, ATT_ERR_INVALID_USER_DATA, _("User data %li bytes is larger than %li bytes"), - user_data_size, sizeof(uvio_attest->user_data)); + g_bytes_get_size(user_data), sizeof(uvio_attest->user_data)); return NULL; } - pv_gbytes_memcpy(uvio_attest->user_data, sizeof(uvio_attest->user_data), user_data); STATIC_ASSERT(sizeof(uvio_attest->user_data) <= UINT16_MAX); - uvio_attest->user_data_len = (uint16_t)user_data_size; + uvio_attest->user_data_len = (uint16_t)copied_data_size; } uvio_attest->meas_addr = PTR_TO_U64(g_malloc0(measurement_size));