Add packed-c protocol support for crypto service
To provide a lightweight parameter encoding that is aligned to
conventions used by SCMI, the packed-c parameter serialization has
been added to the crypto service. This builds on generic
components that allow other packed-c service access protocols
to be added easily. Service level tests have been extended to
use both protobuf and packed-c clients.
Signed-off-by: julhal01 <julian.hall@arm.com>
Change-Id: I9279b0814bcc9cf6c4aa4e30629e2f46f2df4c23
diff --git a/components/common/tlv/tlv.h b/components/common/tlv/tlv.h
new file mode 100644
index 0000000..64233a3
--- /dev/null
+++ b/components/common/tlv/tlv.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TLV_H
+#define TLV_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * TLV provides a general purpose serialization for variable length
+ * objects, identified by a tag. A serialized TLV record has the following
+ * structure:
+ * | Tag | Length | Value |
+ * | (16-bits) | (16-bits) | (Length bytes) |
+ *
+ * No assumptions are made about the alignment of the start of a serialized record.
+ * Tag and Length fields are encoded in Big Endian byte order.
+ */
+#define TLV_TAG_WIDTH (2)
+#define TLV_LENGTH_WIDTH (2)
+#define TLV_HDR_LEN (TLV_TAG_WIDTH + TLV_LENGTH_WIDTH)
+#define TLV_TAG_OFFSET (0)
+#define TLV_LENGTH_OFFSET TLV_TAG_WIDTH
+#define TLV_VALUE_OFFSET TLV_HDR_LEN
+
+/*
+ * TLV record structure provides access to a serialized record.
+ */
+struct tlv_record
+{
+ uint16_t tag;
+ uint16_t length;
+ const uint8_t *value;
+};
+
+/*
+ * Iterator state for interating over serialized tlv records when encoding.
+ */
+struct tlv_iterator
+{
+ uint8_t *pos;
+ uint8_t *limit;
+ uint16_t prev_tag;
+};
+
+/*
+ * Iterator state for interating over serialized tlv records when decoding.
+ */
+struct tlv_const_iterator
+{
+ const uint8_t *pos;
+ const uint8_t *limit;
+};
+
+/*
+ * Return the space required in bytes for a serialized record with the
+ * specified value length.
+ */
+size_t tlv_required_space(size_t length);
+
+/*
+ * Initializes a TLV iterator to the start of a buffer. Used when writing
+ * records to a buffer when encoding.
+ */
+void tlv_iterator_begin(struct tlv_iterator *iter, uint8_t *buf, size_t bufsize);
+
+/*
+ * Initializes a TLV const iterator to the start of a buffer. Used when reading
+ * records from a buffer when decoding.
+ */
+void tlv_const_iterator_begin(struct tlv_const_iterator *iter, const uint8_t *buf, size_t bufsize);
+
+/*
+ * Encode a serialized record and advance the iterator, ready to encode the next
+ * record. Returns true if successful, false if insufficient room.
+ */
+bool tlv_encode(struct tlv_iterator *iter, const struct tlv_record *input);
+
+/*
+ * Decode a serialized record and advance the iterator, ready to decode the next
+ * record (if there is one). Returns true if successful, false there is no serialized record
+ * or an incomplete one.
+ */
+bool tlv_decode(struct tlv_const_iterator *iter, struct tlv_record *output);
+
+/*
+ * Advances the iterator until a record with the specified tag is found. If
+ * it's found, it's decoded and the iterator is advanced to the next position.
+ * This can be used when decoding an expected set of records, encoded in ascending
+ * tag order. Any unrecognised records are skipped over. This is the typical
+ * decoding pattern.
+ */
+bool tlv_find_decode(struct tlv_const_iterator *iter, uint16_t tag, struct tlv_record *output);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TLV_H */