diff --git a/drivers/crypto/caam/Kconfig b/drivers/crypto/caam/Kconfig index f38af9c3ddb8..3931165bb9f7 100644 --- a/drivers/crypto/caam/Kconfig +++ b/drivers/crypto/caam/Kconfig @@ -158,12 +158,11 @@ config CRYPTO_DEV_FSL_CAAM_RNG_API config CRYPTO_DEV_FSL_CAAM_TK_API bool "Register tagged key cryptography implementations with Crypto API" - depends on CRYPTO_DEV_FSL_CAAM_CRYPTO_API + select CRYPTO_DEV_FSL_CAAM_CRYPTO_API help - Selecting this will register algorithms supporting tagged - key. + Selecting this will register algorithms supporting tagged key. - Tagged key are keys that contains metadata indicating what + Tagged keys are keys that contain metadata indicating what they are and how to handle them. config CRYPTO_DEV_FSL_CAAM_RNG_TEST diff --git a/drivers/crypto/caam/Makefile b/drivers/crypto/caam/Makefile index 60891ecee898..79da340a069c 100644 --- a/drivers/crypto/caam/Makefile +++ b/drivers/crypto/caam/Makefile @@ -16,8 +16,8 @@ obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC) += caamhash_desc.o obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_JR_UIO) += fsl_jr_uio.o caam-y := ctrl.o -caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) += tag_object.o caam_jr-y := jr.o key_gen.o +caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) += tag_object.o caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += caamalg_qi.o caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o @@ -26,7 +26,6 @@ caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API) += caampkc.o pkc_desc.o caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM) += sm_store.o obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST) += sm_test.o obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO) += secvio.o -#caam-jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) += tag_object.o caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += qi.o ifneq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI),) diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index 1128f88aca6b..ce2ebbc80695 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -3,7 +3,7 @@ * caam - Freescale FSL CAAM support for crypto API * * Copyright 2008-2011 Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP + * Copyright 2016-2020 NXP * * Based on talitos crypto API driver. * @@ -750,47 +750,16 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, print_hex_dump_debug("key in @"__stringify(__LINE__)": ", DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); - ctx->cdata.keylen = keylen; - ctx->cdata.key_virt = key; - ctx->cdata.key_inline = true; - -#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API /* - * Check if the key is not in plaintext format + * If the algorithm has support for tagged key, + * this is already set in tk_skcipher_setkey(). + * Otherwise, set here the algorithm details. */ - if (alg->caam.support_tagged_key) { - struct tag_object_conf *tagged_key_conf; - int ret; - - /* Get the configuration */ - ret = get_tag_object_conf(ctx->cdata.key_virt, - ctx->cdata.keylen, &tagged_key_conf); - if (ret) { - dev_err(jrdev, - "caam algorithms can't process tagged key\n"); - return ret; - } - - /* Only support black key */ - if (!is_bk_conf(tagged_key_conf)) { - dev_err(jrdev, - "The tagged key provided is not a black key\n"); - return -EINVAL; - } - - get_blackey_conf(&tagged_key_conf->conf.bk_conf, - &ctx->cdata.key_real_len, - &ctx->cdata.key_cmd_opt); - - ret = get_tagged_data(ctx->cdata.key_virt, ctx->cdata.keylen, - &ctx->cdata.key_virt, &ctx->cdata.keylen); - if (ret) { - dev_err(jrdev, - "caam algorithms wrong data from tagged key\n"); - return ret; - } + if (!alg->caam.support_tagged_key) { + ctx->cdata.keylen = keylen; + ctx->cdata.key_virt = key; + ctx->cdata.key_inline = true; } -#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API */ /* skcipher_encrypt shared descriptor */ desc = ctx->sh_desc_enc; @@ -879,8 +848,50 @@ static int arc4_skcipher_setkey(struct crypto_skcipher *skcipher, #ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API static int tk_skcipher_setkey(struct crypto_skcipher *skcipher, - const u8 *key, unsigned int keylen) + const u8 *key, unsigned int keylen) { + struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher); + struct device *jrdev = ctx->jrdev; + struct header_conf *header; + int ret; + + ctx->cdata.keylen = keylen; + ctx->cdata.key_virt = key; + ctx->cdata.key_inline = true; + + /* Retrieve the address of the tag object configuration */ + ret = get_tag_object_header_conf(ctx->cdata.key_virt, + ctx->cdata.keylen, &header); + if (ret) { + dev_err(jrdev, + "unable to get tag object header configuration\n"); + return ret; + } + + /* Check if the tag object header is a black key */ + if (!is_black_key(header)) { + dev_err(jrdev, + "tagged key provided is not a black key\n"); + return -EINVAL; + } + + /* Retrieve the black key configuration */ + get_key_conf(header, + &ctx->cdata.key_real_len, + &ctx->cdata.key_cmd_opt); + + /* + * Retrieve the address of the data + * and size of the tagged object + */ + ret = get_tagged_data(ctx->cdata.key_virt, ctx->cdata.keylen, + &ctx->cdata.key_virt, &ctx->cdata.keylen); + if (ret) { + dev_err(jrdev, + "unable to get data from tagged object\n"); + return ret; + } + return skcipher_setkey(skcipher, key, keylen, 0); } #endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API */ @@ -3538,8 +3549,7 @@ static void caam_skcipher_alg_init(struct caam_skcipher_alg *t_alg) struct skcipher_alg *alg = &t_alg->skcipher; alg->base.cra_module = THIS_MODULE; - alg->base.cra_priority = - t_alg->caam.support_tagged_key ? 1 : CAAM_CRA_PRIORITY; + alg->base.cra_priority = CAAM_CRA_PRIORITY; alg->base.cra_ctxsize = sizeof(struct caam_ctx); alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY; diff --git a/drivers/crypto/caam/caamalg_desc.c b/drivers/crypto/caam/caamalg_desc.c index 00a726d38b99..f1947c98d964 100644 --- a/drivers/crypto/caam/caamalg_desc.c +++ b/drivers/crypto/caam/caamalg_desc.c @@ -1805,6 +1805,10 @@ void cnstr_shdsc_skcipher_encap(u32 * const desc, struct alginfo *cdata, /* Load class1 key only */ if (IS_ENABLED(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) && cdata->key_cmd_opt) + /* + * Black keys can be loaded using only a KEY command + * with ENC=1 and the proper setting of the EKT bit. + */ append_key_as_imm(desc, cdata->key_virt, cdata->keylen, cdata->key_real_len, CLASS_1 | KEY_DEST_CLASS_REG | cdata->key_cmd_opt); @@ -1886,6 +1890,10 @@ void cnstr_shdsc_skcipher_decap(u32 * const desc, struct alginfo *cdata, /* Load class1 key only */ if (IS_ENABLED(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) && cdata->key_cmd_opt) + /* + * Black keys can be loaded using only a KEY command + * with ENC=1 and the proper setting of the EKT bit. + */ append_key_as_imm(desc, cdata->key_virt, cdata->keylen, cdata->key_real_len, CLASS_1 | KEY_DEST_CLASS_REG | cdata->key_cmd_opt); diff --git a/drivers/crypto/caam/desc.h b/drivers/crypto/caam/desc.h index 30724be7a6a0..73c709316425 100644 --- a/drivers/crypto/caam/desc.h +++ b/drivers/crypto/caam/desc.h @@ -153,7 +153,7 @@ * with the TDKEK if TK is set */ #define KEY_ENC 0x00400000 - +#define KEY_ENC_OFFSET 22 /* * No Write Back - Do not allow key to be FIFO STOREd */ @@ -163,11 +163,13 @@ * Enhanced Encryption of Key */ #define KEY_EKT 0x00100000 +#define KEY_EKT_OFFSET 20 /* * Encrypted with Trusted Key */ #define KEY_TK 0x00008000 +#define KEY_TK_OFFSET 15 /* * KDEST - Key Destination: 0 - class key register, diff --git a/drivers/crypto/caam/tag_object.c b/drivers/crypto/caam/tag_object.c index d046b65cc746..25d32b9651f2 100644 --- a/drivers/crypto/caam/tag_object.c +++ b/drivers/crypto/caam/tag_object.c @@ -1,6 +1,6 @@ -// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* - * Copyright 2018-2019 NXP + * Copyright 2018-2020 NXP */ #include @@ -10,251 +10,211 @@ #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 + * is_key_type - Check if the object is a key * - * Return: True if black key type, False otherwise. + * @type: The object type + * + * Return: True if the object is a key (of black or red color), + * false otherwise */ -static bool is_bk_type(enum tag_type type) +bool is_key_type(u32 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); + /* Check type bitfield from object type */ + return ((type >> TAG_OBJ_TYPE_OFFSET) & TAG_OBJ_TYPE_MASK) == 0; +} +EXPORT_SYMBOL(is_key_type); + +/** + * is_trusted_type - Check if the object is a trusted key + * Trusted Descriptor Key Encryption Key (TDKEK) + * + * @type: The object type + * + * Return: True if the object is a trusted key, + * false otherwise + */ +bool is_trusted_type(u32 type) +{ + /* Check type bitfield from object type */ + return ((type >> TAG_OBJ_TK_OFFSET) & TAG_OBJ_TK_MASK) == 1; +} +EXPORT_SYMBOL(is_trusted_type); + +/** + * is_black_key - Check if the tag object header is a black key + * @header: The tag object header configuration + * + * Return: True if is a black key, false otherwise + */ +bool is_black_key(const struct header_conf *header) +{ + u32 type = header->type; + /* Check type and color bitfields from tag object type */ + return (type & (BIT(TAG_OBJ_COLOR_OFFSET) | + BIT(TAG_OBJ_TYPE_OFFSET))) == BIT(TAG_OBJ_COLOR_OFFSET); +} +EXPORT_SYMBOL(is_black_key); + +/** + * is_valid_header_conf - Check if the header configuration is valid + * @header: The header configuration + * + * Return: True if the header of the tag object configuration, + * has the TAG_OBJECT_MAGIC number and a valid type, + * false otherwise + */ +bool is_valid_header_conf(const struct header_conf *header) +{ + return (header->_magic_number == TAG_OBJECT_MAGIC); } /** - * is_bk_conf() - Determines if black key conf. - * @tag_obj_conf : The tag object conf + * get_tag_object_header_conf - Retrieve the address of tag object + * header configuration + * @buffer: Buffer containing the tag object + * @size: The size of buffer + * @header: Returned tag object header configuration * - * Return: True if black key conf, False otherwise. + * Return: '0' on success, error code otherwise */ -bool is_bk_conf(const struct tag_object_conf *tag_obj_conf) +int get_tag_object_header_conf(const void *buffer, size_t size, + struct header_conf **header) { - return is_bk_type(tag_obj_conf->header.type); -} -EXPORT_SYMBOL(is_bk_conf); + bool valid; -/** - * 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; -} + /* Retrieve the tag object */ + struct tagged_object *tag_obj = (struct tagged_object *)buffer; -/** - * 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(const 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) + /* Check if one can retrieve the tag object header configuration */ + if (size < TAG_OVERHEAD_SIZE) return -EINVAL; - is_valid = is_valid_tag_object_conf(&tago->tag); + /* Check tag object header configuration */ + valid = is_valid_header_conf(&tag_obj->header); - *tag_obj_conf = &tago->tag; + /* Retrieve the tag object header configuration address */ + *header = &tag_obj->header; - return (is_valid) ? 0 : -EINVAL; + return valid ? 0 : -EINVAL; } -EXPORT_SYMBOL(get_tag_object_conf); +EXPORT_SYMBOL(get_tag_object_header_conf); /** - * init_tag_object_header() - Initialize the tag object header - * @conf_header : The configuration header - * @type : The type - * - * It initialize the header structure + * get_key_conf - Retrieve the key configuration, + * meaning the length of the black key and + * the KEY command parameters needed for CAAM + * @header: The tag object header configuration + * @real_len: Key length + * @load_param: Load parameters for KEY command: + * - indicator for encrypted keys: plaintext or black + * - indicator for encryption mode: AES-ECB or AES-CCM + * - indicator for encryption keys: JDKEK or TDKEK */ -void init_tag_object_header(struct conf_header *conf_header, - enum tag_type type) +void get_key_conf(const struct header_conf *header, + u32 *real_len, u32 *load_param) { - conf_header->_magic_number = TAG_OBJECT_MAGIC; - conf_header->type = type; + *real_len = header->real_len; + /* Based on the color of the key, set key encryption bit (ENC) */ + *load_param = ((header->type >> TAG_OBJ_COLOR_OFFSET) & + TAG_OBJ_COLOR_MASK) << KEY_ENC_OFFSET; + /* + * For red keys, the TK and EKT bits are ignored. + * So we set them anyway, to be valid when the key is black. + */ + *load_param |= ((header->type >> TAG_OBJ_TK_OFFSET) & + TAG_OBJ_TK_MASK) << KEY_TK_OFFSET; + *load_param |= ((header->type >> TAG_OBJ_EKT_OFFSET) & + TAG_OBJ_EKT_MASK) << KEY_EKT_OFFSET; } -EXPORT_SYMBOL(init_tag_object_header); +EXPORT_SYMBOL(get_key_conf); /** - * 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 + * get_tagged_data - Retrieve the address of the data and size + * of the tagged object + * @tagged_object: Pointer to tag object + * @tagged_object_size: The tagged object size + * @data: Returned the address of the data from + * the tagged object + * @data_size: Returned the size of the data from the + * tagged object * - * 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 + * Return: '0' on success, error code otherwise */ int get_tagged_data(const void *tagged_object, size_t tagged_object_size, const 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) + /* Retrieve the tag object */ + struct tagged_object *tag_obj = (struct tagged_object *)tagged_object; + /* Check if one can retrieve the data from the tagged object */ + if (tagged_object_size < TAG_OVERHEAD_SIZE) return -EINVAL; - /* Retrieve the object */ - *data = &tago->object; - *data_size = tagged_object_size - conf_size; + /* Retrieve the address of the data/object from the tagged object */ + *data = &tag_obj->object; + /* Retrieve the size of the data from the tagged object */ + *data_size = tagged_object_size - TAG_OVERHEAD_SIZE; return 0; } EXPORT_SYMBOL(get_tagged_data); + +/** + * init_tag_object_header - Initialize the tag object header by setting up + * the TAG_OBJECT_MAGIC number, tag object version, + * a valid type and the object's length + * @header: The header configuration to initialize + * @version: The tag object version + * @type: The tag object type + * @len: The object (actual data) length + */ +void init_tag_object_header(struct header_conf *header, u32 version, + u32 type, size_t len) +{ + header->_magic_number = TAG_OBJECT_MAGIC; + header->version = version; + header->type = type; + header->real_len = len; +} +EXPORT_SYMBOL(init_tag_object_header); + +/** + * set_tag_object_header_conf - Set tag object header configuration + * @header: The tag object header configuration to set + * @buffer: The buffer needed to be tagged + * @buf_size: The buffer size + * @tag_obj_size: The tagged object size + * + * Return: '0' on success, error code otherwise + */ +int set_tag_object_header_conf(const struct header_conf *header, + void *buffer, size_t buf_size, u32 *tag_obj_size) +{ + /* Retrieve the tag object */ + struct tagged_object *tag_obj = (struct tagged_object *)buffer; + /* + * Requested size for the tagged object is the buffer size + * and the header configuration size (TAG_OVERHEAD_SIZE) + */ + size_t req_size = buf_size + TAG_OVERHEAD_SIZE; + + /* + * Check if the configuration can be set, + * based on the size of the tagged object + */ + if (*tag_obj_size < req_size) + return -EINVAL; + + /* + * Buffers might overlap, use memmove to + * copy the buffer into the tagged object + */ + memmove(&tag_obj->object, buffer, buf_size); + /* Copy the tag object header configuration into the tagged object */ + memcpy(&tag_obj->header, header, TAG_OVERHEAD_SIZE); + /* Set tagged object size */ + *tag_obj_size = req_size; + + return 0; +} +EXPORT_SYMBOL(set_tag_object_header_conf); diff --git a/drivers/crypto/caam/tag_object.h b/drivers/crypto/caam/tag_object.h index 4ad41d68e29b..fea460d151ef 100644 --- a/drivers/crypto/caam/tag_object.h +++ b/drivers/crypto/caam/tag_object.h @@ -1,100 +1,113 @@ -/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ /* - * Copyright 2018-2019 NXP + * Copyright 2018-2020 NXP */ #ifndef _TAG_OBJECT_H_ #define _TAG_OBJECT_H_ #include - -#define TAG_MIN_SIZE (2 * sizeof(struct conf_header)) -#define TAG_OVERHEAD sizeof(struct tag_object_conf) +#include /** - * enum tag_type - Type of data represented by the tag + * Magic number to identify the tag object structure + * 0x54 = 'T' + * 0x61 = 'a' + * 0x67 = 'g' + * 0x4f = 'O' */ -enum tag_type { - /** @TAG_TYPE_NOT_SUPPORTED: The type is not supported */ - TAG_TYPE_NOT_SUPPORTED = 0, +#define TAG_OBJECT_MAGIC 0x5461674f +#define TAG_MIN_SIZE (2 * sizeof(struct header_conf)) +#define TAG_OVERHEAD_SIZE sizeof(struct header_conf) - /* 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, -}; +/* + * Tag object type is a bitfield: + * + * EKT: Encrypted Key Type (AES-ECB or AES-CCM) + * TK: Trusted Key (use Job Descriptor Key Encryption Key (JDKEK) + * or Trusted Descriptor Key Encryption Key (TDKEK) to + * decrypt the key to be loaded into a Key Register). + * + *| Denomination | Security state | Memory | EKT | TK | Type | Color | + *| ------------ | -------------- | ------- | --- | ----- | ---- | ----- | + *| bit(s) | 5-6 | 4 | 3 | 2 | 1 | 0 | + *| option 0 | non-secure | general | ECB | JDKEK | key | red | + *| option 1 | secure | secure | CCM | TDKEK | blob | black | + *| option 2 | trusted | | | | | | + * + * CAAM supports two different Black Key encapsulation schemes, + * one intended for quick decryption (uses AES-ECB encryption), + * and another intended for high assurance (uses AES-CCM encryption). + * + * CAAM implements both Trusted and normal (non-Trusted) Black Keys, + * which are encrypted with different key-encryption keys. + * Both Trusted and normal Descriptors are allowed to encrypt or decrypt + * normal Black Keys, but only Trusted Descriptors are allowed to + * encrypt or decrypt Trusted Black Keys. + */ +#define TAG_OBJ_COLOR_OFFSET 0 +#define TAG_OBJ_COLOR_MASK 0x1 +#define TAG_OBJ_TYPE_OFFSET 1 +#define TAG_OBJ_TYPE_MASK 0x1 +#define TAG_OBJ_TK_OFFSET 2 +#define TAG_OBJ_TK_MASK 0x1 +#define TAG_OBJ_EKT_OFFSET 3 +#define TAG_OBJ_EKT_MASK 0x1 +#define TAG_OBJ_MEM_OFFSET 4 +#define TAG_OBJ_MEM_MASK 0x1 +#define TAG_OBJ_SEC_STATE_OFFSET 5 /** - * 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 header_conf - Header configuration structure, which represents + * the metadata (or simply a header) applied to the + * actual data (e.g. black key) + * @_magic_number : A magic number to identify the structure + * @version : The version of the data contained (e.g. tag object) + * @type : The type of data contained (e.g. black key, blob, etc.) + * @real_len : Length of the object to be loaded by CAAM */ -struct conf_header { +struct header_conf { u32 _magic_number; + u32 version; 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 tagged_object - Tag object structure, which represents the metadata + * (or simply a header) and the actual data + * (e.g. black key) obtained from hardware + * @tag : The configuration of the data (e.g. header) + * @object : The actual data (e.g. black key) */ -struct tag_object_conf { - struct conf_header header; - union { - struct blackey_conf bk_conf; - } conf; +struct tagged_object { + struct header_conf header; + char object; }; -bool is_bk_conf(const struct tag_object_conf *tag_obj_conf); +bool is_key_type(u32 type); -bool is_valid_tag_object_conf(const struct tag_object_conf *tag_obj_conf); +bool is_trusted_type(u32 type); -void init_tag_object_header(struct conf_header *conf_header, - enum tag_type type); +bool is_black_key(const struct header_conf * const header); -int get_tag_object_conf(const void *buffer, size_t buffer_size, - struct tag_object_conf **tag_obj_conf); +bool is_black_key(const struct header_conf * const header); -int set_tag_object_conf(const struct tag_object_conf *tag_obj_conf, - void *buffer, size_t obj_size, u32 *to_size); +bool is_valid_header_conf(const struct header_conf *header); -size_t get_tag_object_overhead(void); +int get_tag_object_header_conf(const void *buffer, size_t buffer_size, + struct header_conf **header); -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); +void get_key_conf(const struct header_conf *header, + u32 *real_len, u32 *load_param); int get_tagged_data(const void *buffer, size_t buffer_size, const void **data, u32 *data_size); +void init_tag_object_header(struct header_conf *header, u32 version, + u32 type, size_t len); + +int set_tag_object_header_conf(const struct header_conf *header, + void *buffer, size_t obj_size, u32 *to_size); + #endif /* _TAG_OBJECT_H_ */