1
0
Fork 0

MLK-24420-1 crypto: caam - update tagged keys functionality and tk transformations for skcipher

Tagged keys are keys that contain metadata indicating what
they are and how to handle them using the new added tag_object API.
A tag object represents the metadata (or simply a header/configuration)
and the actual data (e.g. black key) obtained from hardware.
The support, for tagged keys, to skcipher algorithms, is done by
adding new transformations, with tk prefix to distinguish
between plaintext and tagged keys.
The tk_ transformations can be used directly by their name:
struct sockaddr_alg sa = {
.salg_family = AF_ALG,
.salg_type = "skcipher", /* this selects the symmetric cipher */
.salg_name = "tk(cbc(aes))" /* this is the cipher name */
};
or for dm-crypt, e.g. using dmsetup:
dmsetup -v create encrypted --table "0 $(blockdev --getsz /dev/mmcblk2p10)
crypt capi:tk(cbc(aes))-plain :32:logon:seckey 0 /dev/mmcblk2p10 0 1
sector_size:512".
tk_ transformations will know how to handle tagged keys, by loading the
proper settings for KEY command.

The API expects that the object (the actual data) from a tag object
to be a buffer (defined by address and size).

Signed-off-by: Iuliana Prodan <iuliana.prodan@nxp.com>
Reviewed-by: Horia Geantă <horia.geanta@nxp.com>
5.4-rM2-2.2.x-imx-squashed
Iuliana Prodan 2020-07-30 12:26:31 +03:00
parent 31b92c7ddf
commit 04cab5a13d
7 changed files with 321 additions and 330 deletions

View File

@ -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

View File

@ -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),)

View File

@ -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;

View File

@ -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);

View File

@ -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,

View File

@ -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 <linux/export.h>
@ -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);

View File

@ -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 <linux/types.h>
#define TAG_MIN_SIZE (2 * sizeof(struct conf_header))
#define TAG_OVERHEAD sizeof(struct tag_object_conf)
#include <linux/bitops.h>
/**
* 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_ */