linux-brain/drivers/crypto/caam/tag_object.c

165 lines
4.8 KiB
C

// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
* Copyright 2018-2020 NXP
*/
#include <linux/export.h>
#include <linux/string.h>
#include <linux/errno.h>
#include "tag_object.h"
#include "desc.h"
/**
* is_key_type - Check if the object is a key
*
* @type: The object type
*
* Return: True if the object is a key (of black or red color),
* false otherwise
*/
bool is_key_type(u32 type)
{
/* 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);
}
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
* @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 *red_key_len, u32 *obj_len, u32 *load_param)
{
*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;
/*
* 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(get_key_conf);
/**
* 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
* @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 red_key_len, size_t obj_len)
{
header->_magic_number = TAG_OBJECT_MAGIC;
header->version = version;
header->type = type;
header->red_key_len = red_key_len;
header->obj_len = obj_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);