blob: f4218a4341bc83f5c273fc89cd51ebe20217f4a0 [file] [log] [blame]
// 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);