1
0
Fork 0

MLK-24497 crypto: caam - update tagged object functionality by adding red key length

Add red key length to tag object in order to have the plaintext
information available for both keys and blobs. This is used to
encrypt a red key into a black key and to decapsulate a
black key from a black blob.
While here, I've simplified the tagged object API by removing some
redundant functions.

Fixes: 04cab5a13d ("MLK-24420-1 crypto: caam - update tagged keys functionality and tk transformations for skcipher")
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-08-20 12:08:02 +03:00
parent 0b6f47cb8d
commit d3f5b6ad74
3 changed files with 49 additions and 98 deletions

View File

@ -747,9 +747,6 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
u32 *desc;
const bool is_rfc3686 = alg->caam.rfc3686;
print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
/*
* If the algorithm has support for tagged key,
* this is already set in tk_skcipher_setkey().
@ -761,6 +758,9 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
ctx->cdata.key_inline = true;
}
print_hex_dump_debug("key in @" __stringify(__LINE__) ": ",
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
/* skcipher_encrypt shared descriptor */
desc = ctx->sh_desc_enc;
cnstr_shdsc_skcipher_encap(desc, &ctx->cdata, ivsize, is_rfc3686,
@ -853,19 +853,28 @@ static int tk_skcipher_setkey(struct crypto_skcipher *skcipher,
struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
struct device *jrdev = ctx->jrdev;
struct header_conf *header;
struct tagged_object *tag_obj;
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) {
/* Check if one can retrieve the tag object header configuration */
if (keylen <= TAG_OVERHEAD_SIZE)
return -EINVAL;
/* Retrieve the tag object */
tag_obj = (struct tagged_object *)key;
/*
* Check tag object header configuration
* and retrieve the tag object header configuration
*/
if (is_valid_header_conf(&tag_obj->header)) {
header = &tag_obj->header;
} else {
dev_err(jrdev,
"unable to get tag object header configuration\n");
return ret;
return -EINVAL;
}
/* Check if the tag object header is a black key */
@ -878,21 +887,21 @@ static int tk_skcipher_setkey(struct crypto_skcipher *skcipher,
/* Retrieve the black key configuration */
get_key_conf(header,
&ctx->cdata.key_real_len,
&ctx->cdata.keylen,
&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);
/* Retrieve the address of the data of the tagged object */
ctx->cdata.key_virt = &tag_obj->object;
/* Validate key length for AES algorithms */
ret = aes_check_keylen(ctx->cdata.key_real_len);
if (ret) {
dev_err(jrdev,
"unable to get data from tagged object\n");
crypto_skcipher_set_flags(skcipher,
CRYPTO_TFM_RES_BAD_KEY_LEN);
return ret;
}
return skcipher_setkey(skcipher, key, keylen, 0);
return skcipher_setkey(skcipher, NULL, 0, 0);
}
#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API */

View File

@ -68,53 +68,25 @@ bool is_valid_header_conf(const struct header_conf *header)
{
return (header->_magic_number == TAG_OBJECT_MAGIC);
}
/**
* 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: '0' on success, error code otherwise
*/
int get_tag_object_header_conf(const void *buffer, size_t size,
struct header_conf **header)
{
bool valid;
/* Retrieve the tag object */
struct tagged_object *tag_obj = (struct tagged_object *)buffer;
/* Check if one can retrieve the tag object header configuration */
if (size < TAG_OVERHEAD_SIZE)
return -EINVAL;
/* Check tag object header configuration */
valid = is_valid_header_conf(&tag_obj->header);
/* Retrieve the tag object header configuration address */
*header = &tag_obj->header;
return valid ? 0 : -EINVAL;
}
EXPORT_SYMBOL(get_tag_object_header_conf);
EXPORT_SYMBOL(is_valid_header_conf);
/**
* 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
* @red_key_len: Red key length
* @obj_len: Black/Red key/blob 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 get_key_conf(const struct header_conf *header,
u32 *real_len, u32 *load_param)
u32 *red_key_len, u32 *obj_len, u32 *load_param)
{
*real_len = header->real_len;
*red_key_len = header->red_key_len;
*obj_len = header->obj_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;
@ -129,36 +101,6 @@ void get_key_conf(const struct header_conf *header,
}
EXPORT_SYMBOL(get_key_conf);
/**
* 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' on success, error code otherwise
*/
int get_tagged_data(const void *tagged_object, size_t tagged_object_size,
const void **data, u32 *data_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 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,
@ -166,15 +108,17 @@ EXPORT_SYMBOL(get_tagged_data);
* @header: The header configuration to initialize
* @version: The tag object version
* @type: The tag object type
* @len: The object (actual data) length
* @red_key_len: The red key length
* @obj_len: The object (actual data) length
*/
void init_tag_object_header(struct header_conf *header, u32 version,
u32 type, size_t len)
u32 type, size_t red_key_len, size_t obj_len)
{
header->_magic_number = TAG_OBJECT_MAGIC;
header->version = version;
header->type = type;
header->real_len = len;
header->red_key_len = red_key_len;
header->obj_len = obj_len;
}
EXPORT_SYMBOL(init_tag_object_header);

View File

@ -17,9 +17,9 @@
* 0x4f = 'O'
*/
#define TAG_OBJECT_MAGIC 0x5461674f
#define TAG_MIN_SIZE (2 * sizeof(struct header_conf))
#define TAG_OVERHEAD_SIZE sizeof(struct header_conf)
#define MIN_KEY_SIZE 16
#define TAG_MIN_SIZE (MIN_KEY_SIZE + TAG_OVERHEAD_SIZE)
/*
* Tag object type is a bitfield:
*
@ -64,13 +64,17 @@
* @_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
* @red_key_len : Length of the red key to be loaded by CAAM (for key
* generation or blob encapsulation)
* @obj_len : The total length of the (black/red) object (key/blob),
* after encryption/encapsulation
*/
struct header_conf {
u32 _magic_number;
u32 version;
u32 type;
u32 real_len;
u32 red_key_len;
u32 obj_len;
};
/**
@ -95,17 +99,11 @@ bool is_black_key(const struct header_conf * const header);
bool is_valid_header_conf(const struct header_conf *header);
int get_tag_object_header_conf(const void *buffer, size_t buffer_size,
struct header_conf **header);
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);
u32 *red_key_len, u32 *obj_len, u32 *load_param);
void init_tag_object_header(struct header_conf *header, u32 version,
u32 type, size_t len);
u32 type, size_t red_key_len, size_t obj_len);
int set_tag_object_header_conf(const struct header_conf *header,
void *buffer, size_t obj_size, u32 *to_size);