diff mbox series

[v2,19/58] qom: implement property helper for sha384

Message ID 20230818095041.1973309-20-xiaoyao.li@intel.com (mailing list archive)
State New, archived
Headers show
Series TDX QEMU support | expand

Commit Message

Xiaoyao Li Aug. 18, 2023, 9:50 a.m. UTC
From: Isaku Yamahata <isaku.yamahata@intel.com>

Implement property_add_sha384() which converts hex string <-> uint8_t[48]
It will be used for TDX which uses sha384 for measurement.

Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
 include/qom/object.h | 17 ++++++++++
 qom/object.c         | 76 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 93 insertions(+)

Comments

Daniel P. Berrangé Aug. 21, 2023, 9:25 a.m. UTC | #1
On Fri, Aug 18, 2023 at 05:50:02AM -0400, Xiaoyao Li wrote:
> From: Isaku Yamahata <isaku.yamahata@intel.com>
> 
> Implement property_add_sha384() which converts hex string <-> uint8_t[48]
> It will be used for TDX which uses sha384 for measurement.

I think it is likely a better idea to use base64 for the encoding
the binary hash - we use base64 for all the sev-guest properties
that were binary data.

At which points the property set/get logic is much simpler as it
is just needing a call to  g_base64_encode / g_base64_decode and
length validation for the decode case.

> 
> Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
> Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
> ---
>  include/qom/object.h | 17 ++++++++++
>  qom/object.c         | 76 ++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 93 insertions(+)
> 
> diff --git a/include/qom/object.h b/include/qom/object.h
> index ef7258a5e149..70399a5b1940 100644
> --- a/include/qom/object.h
> +++ b/include/qom/object.h
> @@ -1887,6 +1887,23 @@ ObjectProperty *object_property_add_alias(Object *obj, const char *name,
>  ObjectProperty *object_property_add_const_link(Object *obj, const char *name,
>                                                 Object *target);
>  
> +
> +/**
> + * object_property_add_sha384:
> + * @obj: the object to add a property to
> + * @name: the name of the property
> + * @v: pointer to value
> + * @flags: bitwise-or'd ObjectPropertyFlags
> + *
> + * Add an sha384 property in memory.  This function will add a
> + * property of type 'sha384'.
> + *
> + * Returns: The newly added property on success, or %NULL on failure.
> + */
> +ObjectProperty * object_property_add_sha384(Object *obj, const char *name,
> +                                            const uint8_t *v,
> +                                            ObjectPropertyFlags flags);
> +
>  /**
>   * object_property_set_description:
>   * @obj: the object owning the property
> diff --git a/qom/object.c b/qom/object.c
> index e25f1e96db1e..e71ce46ed576 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -15,6 +15,7 @@
>  #include "qapi/error.h"
>  #include "qom/object.h"
>  #include "qom/object_interfaces.h"
> +#include "qemu/ctype.h"
>  #include "qemu/cutils.h"
>  #include "qemu/memalign.h"
>  #include "qapi/visitor.h"
> @@ -2781,6 +2782,81 @@ object_property_add_alias(Object *obj, const char *name,
>      return op;
>  }
>  
> +#define SHA384_DIGEST_SIZE      48
> +static void property_get_sha384(Object *obj, Visitor *v, const char *name,
> +                                void *opaque, Error **errp)
> +{
> +    uint8_t *value = (uint8_t *)opaque;
> +    char str[SHA384_DIGEST_SIZE * 2 + 1];
> +    char *str_ = (char*)str;
> +    size_t i;
> +
> +    for (i = 0; i < SHA384_DIGEST_SIZE; i++) {
> +        char *buf;
> +        buf = &str[i * 2];
> +
> +        sprintf(buf, "%02hhx", value[i]);
> +    }
> +    str[SHA384_DIGEST_SIZE * 2] = '\0';
> +
> +    visit_type_str(v, name, &str_, errp);
> +}
> +
> +static void property_set_sha384(Object *obj, Visitor *v, const char *name,
> +                                    void *opaque, Error **errp)
> +{
> +    uint8_t *value = (uint8_t *)opaque;
> +    char* str;
> +    size_t len;
> +    size_t i;
> +
> +    if (!visit_type_str(v, name, &str, errp)) {
> +        goto err;
> +    }
> +
> +    len = strlen(str);
> +    if (len != SHA384_DIGEST_SIZE * 2) {
> +        error_setg(errp, "invalid length for sha348 hex string %s. "
> +                   "it must be 48 * 2 hex", name);
> +        goto err;
> +    }
> +
> +    for (i = 0; i < SHA384_DIGEST_SIZE; i++) {
> +        if (!qemu_isxdigit(str[i * 2]) || !qemu_isxdigit(str[i * 2 + 1])) {
> +            error_setg(errp, "invalid char for sha318 hex string %s at %c%c",
> +                       name, str[i * 2], str[i * 2 + 1]);
> +            goto err;
> +        }
> +
> +        if (sscanf(str + i * 2, "%02hhx", &value[i]) != 1) {
> +            error_setg(errp, "invalid format for sha318 hex string %s", name);
> +            goto err;
> +        }
> +    }
> +
> +err:
> +    g_free(str);
> +}
> +
> +ObjectProperty *
> +object_property_add_sha384(Object *obj, const char *name,
> +                           const uint8_t *v, ObjectPropertyFlags flags)
> +{
> +    ObjectPropertyAccessor *getter = NULL;
> +    ObjectPropertyAccessor *setter = NULL;
> +
> +    if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
> +        getter = property_get_sha384;
> +    }
> +
> +    if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
> +        setter = property_set_sha384;
> +    }
> +
> +    return object_property_add(obj, name, "sha384",
> +                               getter, setter, NULL, (void *)v);
> +}
> +
>  void object_property_set_description(Object *obj, const char *name,
>                                       const char *description)
>  {
> -- 
> 2.34.1
> 

With regards,
Daniel
Isaku Yamahata Aug. 21, 2023, 11:28 p.m. UTC | #2
On Mon, Aug 21, 2023 at 10:25:35AM +0100,
"Daniel P. Berrangé" <berrange@redhat.com> wrote:

> On Fri, Aug 18, 2023 at 05:50:02AM -0400, Xiaoyao Li wrote:
> > From: Isaku Yamahata <isaku.yamahata@intel.com>
> > 
> > Implement property_add_sha384() which converts hex string <-> uint8_t[48]
> > It will be used for TDX which uses sha384 for measurement.
> 
> I think it is likely a better idea to use base64 for the encoding
> the binary hash - we use base64 for all the sev-guest properties
> that were binary data.
> 
> At which points the property set/get logic is much simpler as it
> is just needing a call to  g_base64_encode / g_base64_decode and
> length validation for the decode case.

Hex string is poplar to show hash value, isn't it?  Anyway it's easy for human
operator, shell scripts, libvirt or whatever to convert those representations
with utility commands like base64 or xxd, or library call.  Either way would
work.
diff mbox series

Patch

diff --git a/include/qom/object.h b/include/qom/object.h
index ef7258a5e149..70399a5b1940 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1887,6 +1887,23 @@  ObjectProperty *object_property_add_alias(Object *obj, const char *name,
 ObjectProperty *object_property_add_const_link(Object *obj, const char *name,
                                                Object *target);
 
+
+/**
+ * object_property_add_sha384:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @v: pointer to value
+ * @flags: bitwise-or'd ObjectPropertyFlags
+ *
+ * Add an sha384 property in memory.  This function will add a
+ * property of type 'sha384'.
+ *
+ * Returns: The newly added property on success, or %NULL on failure.
+ */
+ObjectProperty * object_property_add_sha384(Object *obj, const char *name,
+                                            const uint8_t *v,
+                                            ObjectPropertyFlags flags);
+
 /**
  * object_property_set_description:
  * @obj: the object owning the property
diff --git a/qom/object.c b/qom/object.c
index e25f1e96db1e..e71ce46ed576 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -15,6 +15,7 @@ 
 #include "qapi/error.h"
 #include "qom/object.h"
 #include "qom/object_interfaces.h"
+#include "qemu/ctype.h"
 #include "qemu/cutils.h"
 #include "qemu/memalign.h"
 #include "qapi/visitor.h"
@@ -2781,6 +2782,81 @@  object_property_add_alias(Object *obj, const char *name,
     return op;
 }
 
+#define SHA384_DIGEST_SIZE      48
+static void property_get_sha384(Object *obj, Visitor *v, const char *name,
+                                void *opaque, Error **errp)
+{
+    uint8_t *value = (uint8_t *)opaque;
+    char str[SHA384_DIGEST_SIZE * 2 + 1];
+    char *str_ = (char*)str;
+    size_t i;
+
+    for (i = 0; i < SHA384_DIGEST_SIZE; i++) {
+        char *buf;
+        buf = &str[i * 2];
+
+        sprintf(buf, "%02hhx", value[i]);
+    }
+    str[SHA384_DIGEST_SIZE * 2] = '\0';
+
+    visit_type_str(v, name, &str_, errp);
+}
+
+static void property_set_sha384(Object *obj, Visitor *v, const char *name,
+                                    void *opaque, Error **errp)
+{
+    uint8_t *value = (uint8_t *)opaque;
+    char* str;
+    size_t len;
+    size_t i;
+
+    if (!visit_type_str(v, name, &str, errp)) {
+        goto err;
+    }
+
+    len = strlen(str);
+    if (len != SHA384_DIGEST_SIZE * 2) {
+        error_setg(errp, "invalid length for sha348 hex string %s. "
+                   "it must be 48 * 2 hex", name);
+        goto err;
+    }
+
+    for (i = 0; i < SHA384_DIGEST_SIZE; i++) {
+        if (!qemu_isxdigit(str[i * 2]) || !qemu_isxdigit(str[i * 2 + 1])) {
+            error_setg(errp, "invalid char for sha318 hex string %s at %c%c",
+                       name, str[i * 2], str[i * 2 + 1]);
+            goto err;
+        }
+
+        if (sscanf(str + i * 2, "%02hhx", &value[i]) != 1) {
+            error_setg(errp, "invalid format for sha318 hex string %s", name);
+            goto err;
+        }
+    }
+
+err:
+    g_free(str);
+}
+
+ObjectProperty *
+object_property_add_sha384(Object *obj, const char *name,
+                           const uint8_t *v, ObjectPropertyFlags flags)
+{
+    ObjectPropertyAccessor *getter = NULL;
+    ObjectPropertyAccessor *setter = NULL;
+
+    if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
+        getter = property_get_sha384;
+    }
+
+    if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
+        setter = property_set_sha384;
+    }
+
+    return object_property_add(obj, name, "sha384",
+                               getter, setter, NULL, (void *)v);
+}
+
 void object_property_set_description(Object *obj, const char *name,
                                      const char *description)
 {