MLK-19801: Add tag functionality
authorFranck LENORMAND <franck.lenormand@nxp.com>
Fri, 5 Oct 2018 14:08:25 +0000 (16:08 +0200)
committerLeonard Crestez <leonard.crestez@nxp.com>
Wed, 17 Apr 2019 23:51:34 +0000 (02:51 +0300)
Add functions to tag an object with metadata(configuration).

It is possible to:
 - create metadata:
- init_tag_object_header
- init_blackey_conf
- set_tag_object_conf
 - retrieve metadata:
- get_tag_object_conf
- get_blackey_conf

The API expects an object to be a space a memory
with an address and a size.

The implementation of the tag is currently exposed
but users shouldn't access it directly, they should
use the functions provided.

Signed-off-by: Franck LENORMAND <franck.lenormand@nxp.com>
(cherry picked from commit ebbb132da8e7f9de7f3d375eff8d87f684feb1eb)
Signed-off-by: Vipul Kumar <vipul_kumar@mentor.com>
drivers/crypto/caam/Kconfig
drivers/crypto/caam/Makefile
drivers/crypto/caam/tag_object.c [new file with mode: 0644]
drivers/crypto/caam/tag_object.h [new file with mode: 0644]

index dac40e9..855abf2 100644 (file)
@@ -143,6 +143,16 @@ config CRYPTO_DEV_FSL_CAAM_RNG_API
          To compile this as a module, choose M here: the module
          will be called caamrng.
 
+config CRYPTO_DEV_FSL_CAAM_TK_API
+       bool "Register tagged key cryptography implementations with Crypto API"
+       depends on CRYPTO_DEV_FSL_CAAM_CRYPTO_API
+       help
+         Selecting this will register algorithms supporting tagged
+         key.
+
+         Tagged key are keys that contains metadata indicating what
+         they are and how to handle them.
+
 config CRYPTO_DEV_FSL_CAAM_RNG_TEST
        bool "Test caam rng"
        depends on CRYPTO_DEV_FSL_CAAM_RNG_API
index 96d5e9d..229e7d9 100644 (file)
@@ -25,3 +25,5 @@ ifneq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI),)
        ccflags-y += -DCONFIG_CAAM_QI
        caam-objs += qi.o
 endif
+
+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) += tag_object.o
diff --git a/drivers/crypto/caam/tag_object.c b/drivers/crypto/caam/tag_object.c
new file mode 100644 (file)
index 0000000..f4218a4
--- /dev/null
@@ -0,0 +1,260 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Copyright 2018 NXP
+ */
+
+#include <linux/export.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+
+#include "tag_object.h"
+#include "desc.h"
+
+/*
+ * Magic number to clearly identify the structure is for us
+ * 0x54 = 'T'
+ * 0x61 = 'a'
+ * 0x67 = 'g'
+ * 0x4f = 'O'
+ */
+#define TAG_OBJECT_MAGIC 0x5461674f
+
+/**
+ * struct tagged_object - Structure representing a tagged object
+ * @tag : The configuration of the data
+ * @object : The object
+ */
+struct tagged_object {
+       struct tag_object_conf tag;
+       char object;
+};
+
+/**
+ * is_bk_type() - Determines if black key type.
+ * @type: The type
+ *
+ * Return: True if black key type, False otherwise.
+ */
+static bool is_bk_type(enum tag_type type)
+{
+       return (type == TAG_TYPE_BLACK_KEY_ECB) ||
+               (type == TAG_TYPE_BLACK_KEY_ECB_TRUSTED) ||
+               (type == TAG_TYPE_BLACK_KEY_CCM) ||
+               (type == TAG_TYPE_BLACK_KEY_CCM_TRUSTED);
+}
+
+/**
+ * is_bk_conf() - Determines if black key conf.
+ * @tag_obj_conf : The tag object conf
+ *
+ * Return: True if black key conf, False otherwise.
+ */
+bool is_bk_conf(const struct tag_object_conf *tag_obj_conf)
+{
+       return is_bk_type(tag_obj_conf->header.type);
+}
+EXPORT_SYMBOL(is_bk_conf);
+
+/**
+ * get_bk_conf() - Gets the block conf.
+ * @tag_obj_conf : The tag object conf
+ *
+ * Return: The block conf.
+ */
+const struct blackey_conf *get_bk_conf(const struct tag_object_conf *tag_obj_conf)
+{
+       return &tag_obj_conf->conf.bk_conf;
+}
+
+/**
+ * get_tag_object_overhead() - Gets the tag object overhead.
+ *
+ * Return: The tag object overhead.
+ */
+size_t get_tag_object_overhead(void)
+{
+       return TAG_OVERHEAD;
+}
+EXPORT_SYMBOL(get_tag_object_overhead);
+
+/**
+ * is_valid_type() - Determines if valid type.
+ * @type : The type
+ *
+ * Return: True if valid type, False otherwise.
+ */
+bool is_valid_type(enum tag_type type)
+{
+       return (type > TAG_TYPE_NOT_SUPPORTED) && (type < NB_TAG_TYPE);
+}
+EXPORT_SYMBOL(is_valid_type);
+
+/**
+ * is_valid_header() - Determines if valid header.
+ * @header : The header
+ *
+ * Return: True if valid tag object conf, False otherwise.
+ */
+static bool is_valid_header(const struct conf_header *header)
+{
+       bool valid = header->_magic_number == TAG_OBJECT_MAGIC;
+
+       valid = valid && is_valid_type(header->type);
+
+       return valid;
+}
+
+/**
+ * is_valid_tag_object_conf() - Determines if valid tag object conf.
+ * @tag_obj_conf : The tag object conf
+ *
+ * Return: True if valid header, False otherwise.
+ */
+bool is_valid_tag_object_conf(const struct tag_object_conf *tag_obj_conf)
+{
+       bool valid = true;
+
+       valid = is_valid_header(&tag_obj_conf->header);
+
+       return valid;
+}
+EXPORT_SYMBOL(is_valid_tag_object_conf);
+
+/**
+ * get_tag_object_conf() - Gets a pointer on the tag object conf.
+ * @tag_obj_conf : The tag object conf
+ * @buffer : The buffer
+ * @size : The size
+ *
+ * Return: 0 if success, else error code
+ */
+int get_tag_object_conf(void *buffer, size_t size,
+                       struct tag_object_conf **tag_obj_conf)
+{
+       bool is_valid;
+       struct tagged_object *tago = (struct tagged_object *)buffer;
+       size_t conf_size = get_tag_object_overhead();
+
+       /* Check we can retrieve the conf */
+       if (size < conf_size)
+               return -EINVAL;
+
+       is_valid = is_valid_tag_object_conf(&tago->tag);
+
+       *tag_obj_conf = &tago->tag;
+
+       return (is_valid) ? 0 : -EINVAL;
+}
+EXPORT_SYMBOL(get_tag_object_conf);
+
+/**
+ * init_tag_object_header() - Initialize the tag object header
+ * @conf_header : The configuration header
+ * @type : The type
+ *
+ * It initialize the header structure
+ */
+void init_tag_object_header(struct conf_header *conf_header,
+                           enum tag_type type)
+{
+       conf_header->_magic_number = TAG_OBJECT_MAGIC;
+       conf_header->type = type;
+}
+EXPORT_SYMBOL(init_tag_object_header);
+
+/**
+ * set_tag_object_conf() - Sets the tag object conf.
+ * @tag_obj_conf : The tag object conf
+ * @buffer : The buffer
+ * @obj_size : The object size
+ * @to_size : The tagged object size
+ *
+ * Return: 0 if success, else error code
+ */
+int set_tag_object_conf(const struct tag_object_conf *tag_obj_conf,
+                       void *buffer, size_t obj_size, u32 *to_size)
+{
+       struct tagged_object *tago = buffer;
+       size_t conf_size = get_tag_object_overhead();
+       size_t req_size = obj_size + conf_size;
+
+       /* Check we can set the conf */
+       if (*to_size < req_size) {
+               *to_size = req_size;
+               return -EINVAL;
+       }
+
+       /* Move the object */
+       memmove(&tago->object, buffer, obj_size);
+
+       /* Copy the tag */
+       memcpy(&tago->tag, tag_obj_conf, conf_size);
+
+       *to_size = req_size;
+
+       return 0;
+}
+EXPORT_SYMBOL(set_tag_object_conf);
+
+/**
+ * init_blackey_conf() - Initialize the black key configuration
+ * @blackey_conf : The blackey conf
+ * @len : The length
+ * @ccm : The ccm
+ * @tk : The trusted key
+ *
+ * It initialize the black key configuration structure
+ */
+void init_blackey_conf(struct blackey_conf *blackey_conf,
+                      size_t len, bool ccm, bool tk)
+{
+       blackey_conf->real_len = len;
+       blackey_conf->load = KEY_ENC
+                               | ((ccm) ? KEY_EKT : 0)
+                               | ((tk) ? KEY_TK : 0);
+}
+EXPORT_SYMBOL(init_blackey_conf);
+
+/**
+ * get_blackey_conf() - Get the black key configuration
+ * @blackey_conf : The blackey conf
+ * @real_len : The real length
+ * @load_param : The load parameter
+ *
+ * It retrieve the black key configuration
+ */
+void get_blackey_conf(const struct blackey_conf *blackey_conf,
+                     u32 *real_len, u32 *load_param)
+{
+       *real_len = blackey_conf->real_len;
+       *load_param = blackey_conf->load;
+}
+EXPORT_SYMBOL(get_blackey_conf);
+
+/**
+ * get_tagged_data() - Get a pointer on the data and the size
+ * @tagged_object : Pointer on the tagged object
+ * @tagged_object_size : tagged object size in bytes
+ * @data : Pointer on the data
+ * @data_size : data size in bytes
+ *
+ * Return: 0 if success, else error code
+ */
+int get_tagged_data(void *tagged_object, size_t tagged_object_size,
+                   void **data, u32 *data_size)
+{
+       struct tagged_object *tago =
+               (struct tagged_object *)tagged_object;
+       size_t conf_size = get_tag_object_overhead();
+
+       /* Check we can retrieve the object */
+       if (tagged_object_size < conf_size)
+               return -EINVAL;
+
+       /* Retrieve the object */
+       *data = &tago->object;
+       *data_size = tagged_object_size - conf_size;
+
+       return 0;
+}
+EXPORT_SYMBOL(get_tagged_data);
diff --git a/drivers/crypto/caam/tag_object.h b/drivers/crypto/caam/tag_object.h
new file mode 100644 (file)
index 0000000..2ecc1be
--- /dev/null
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/*
+ * Copyright 2018 NXP
+ */
+
+#ifndef _TAG_OBJECT_H_
+#define _TAG_OBJECT_H_
+
+#include <linux/types.h>
+
+#define TAG_MIN_SIZE (2 * sizeof(struct conf_header))
+#define TAG_OVERHEAD sizeof(struct tag_object_conf)
+
+/**
+ * enum tag_type - Type of data represented by the tag
+ */
+enum tag_type {
+       /** @TAG_TYPE_NOT_SUPPORTED: The type is not supported */
+       TAG_TYPE_NOT_SUPPORTED = 0,
+
+       /* Type that passes is_tag_type_valid() */
+       /** @TAG_TYPE_BLACK_KEY_ECB: Black key encrypted with ECB */
+       TAG_TYPE_BLACK_KEY_ECB,
+       /**
+        * @TAG_TYPE_BLACK_KEY_ECB_TRUSTED: ECB Black key created by trusted
+        * descriptor
+        */
+       TAG_TYPE_BLACK_KEY_ECB_TRUSTED,
+       /** @TAG_TYPE_BLACK_KEY_CCM: Black key encrypted with CCM */
+       TAG_TYPE_BLACK_KEY_CCM,
+       /**
+        * @TAG_TYPE_BLACK_KEY_CCM_TRUSTED: CCM Black key created by trusted
+        * descriptor
+        */
+       TAG_TYPE_BLACK_KEY_CCM_TRUSTED,
+
+       /** @NB_TAG_TYPE: Number of type of tag */
+       NB_TAG_TYPE,
+};
+
+/**
+ * struct conf_header - Common struture holding the type of data and the magic
+ * number
+ * @_magic_number : A magic number to identify the structure
+ * @type : The type of data contained
+ */
+struct conf_header {
+       u32 _magic_number;
+       u32 type;
+};
+
+/**
+ * struct blackey_conf - Configuration for a black key
+ * @load : Load parameter for CAAM
+ * @real_len : Length of the key before encryption
+ */
+struct blackey_conf {
+       u32 load;
+       u32 real_len;
+};
+
+/**
+ * struct tag_object_conf - Common structure which is the tag applied to data
+ * @header : Part of the data initialized with common function
+ * :c:func:`init_tag_object_header`
+ * @conf : Configuration data about the object tagged, initialized with
+ * specific function
+ */
+struct tag_object_conf {
+       struct conf_header header;
+       union {
+               struct blackey_conf bk_conf;
+       } conf;
+};
+
+bool is_bk_conf(const struct tag_object_conf *tag_obj_conf);
+
+bool is_valid_tag_object_conf(const struct tag_object_conf *tag_obj_conf);
+
+void init_tag_object_header(struct conf_header *conf_header,
+                           enum tag_type type);
+
+int get_tag_object_conf(void *buffer, size_t buffer_size,
+                       struct tag_object_conf **tag_obj_conf);
+
+int set_tag_object_conf(const struct tag_object_conf *tag_obj_conf,
+                       void *buffer, size_t obj_size, u32 *to_size);
+
+size_t get_tag_object_overhead(void);
+
+void get_blackey_conf(const struct blackey_conf *blackey_conf,
+                     u32 *real_len, u32 *load_param);
+
+void init_blackey_conf(struct blackey_conf *blackey_conf,
+                      size_t len, bool ccm, bool tk);
+
+int get_tagged_data(void *buffer, size_t buffer_size,
+                   void **data, u32 *data_size);
+
+#endif /* _TAG_OBJECT_H_ */