xref: /optee_os/core/include/signed_hdr.h (revision 40bb4a98fa790da8c9b306effa538b6d7ec4d414)
11bb92983SJerome Forissier /* SPDX-License-Identifier: BSD-2-Clause */
2bc420748SJens Wiklander /*
3bc420748SJens Wiklander  * Copyright (c) 2015, Linaro Limited
4bc420748SJens Wiklander  */
5bc420748SJens Wiklander #ifndef SIGNED_HDR_H
6bc420748SJens Wiklander #define SIGNED_HDR_H
7bc420748SJens Wiklander 
892ea2867SJens Wiklander #include <inttypes.h>
9064663e8SJens Wiklander #include <stdlib.h>
10*40bb4a98SJens Wiklander #include <tee_api_types.h>
11*40bb4a98SJens Wiklander #include <util.h>
12bc420748SJens Wiklander 
13bc420748SJens Wiklander enum shdr_img_type {
14bc420748SJens Wiklander 	SHDR_TA = 0,
1582b5346dSJens Wiklander 	SHDR_BOOTSTRAP_TA = 1,
16e1afc439SSumit Garg 	SHDR_ENCRYPTED_TA = 2,
17bc420748SJens Wiklander };
18bc420748SJens Wiklander 
19bc420748SJens Wiklander #define SHDR_MAGIC	0x4f545348
20bc420748SJens Wiklander 
21bc420748SJens Wiklander /**
22bc420748SJens Wiklander  * struct shdr - signed header
23bc420748SJens Wiklander  * @magic:	magic number must match SHDR_MAGIC
24bc420748SJens Wiklander  * @img_type:	image type, values defined by enum shdr_img_type
25bc420748SJens Wiklander  * @img_size:	image size in bytes
26bc420748SJens Wiklander  * @algo:	algorithm, defined by public key algorithms TEE_ALG_*
27bc420748SJens Wiklander  *		from TEE Internal API specification
28bc420748SJens Wiklander  * @hash_size:	size of the signed hash
29bc420748SJens Wiklander  * @sig_size:	size of the signature
30bc420748SJens Wiklander  * @hash:	hash of an image
31bc420748SJens Wiklander  * @sig:	signature of @hash
32bc420748SJens Wiklander  */
33bc420748SJens Wiklander struct shdr {
34bc420748SJens Wiklander 	uint32_t magic;
35bc420748SJens Wiklander 	uint32_t img_type;
36bc420748SJens Wiklander 	uint32_t img_size;
37bc420748SJens Wiklander 	uint32_t algo;
38bc420748SJens Wiklander 	uint16_t hash_size;
39bc420748SJens Wiklander 	uint16_t sig_size;
40bc420748SJens Wiklander 	/*
41bc420748SJens Wiklander 	 * Commented out element used to visualize the layout dynamic part
42bc420748SJens Wiklander 	 * of the struct.
43bc420748SJens Wiklander 	 *
44bc420748SJens Wiklander 	 * hash is accessed through the macro SHDR_GET_HASH and
45bc420748SJens Wiklander 	 * signature is accessed through the macro SHDR_GET_SIG
46bc420748SJens Wiklander 	 *
47bc420748SJens Wiklander 	 * uint8_t hash[hash_size];
48bc420748SJens Wiklander 	 * uint8_t sig[sig_size];
49bc420748SJens Wiklander 	 */
50bc420748SJens Wiklander };
51bc420748SJens Wiklander 
52*40bb4a98SJens Wiklander static inline size_t shdr_get_size(const struct shdr *shdr)
53*40bb4a98SJens Wiklander {
54*40bb4a98SJens Wiklander 	size_t s = sizeof(*shdr);
55*40bb4a98SJens Wiklander 
56*40bb4a98SJens Wiklander 	if (ADD_OVERFLOW(s, shdr->hash_size, &s) ||
57*40bb4a98SJens Wiklander 	    ADD_OVERFLOW(s, shdr->sig_size, &s))
58*40bb4a98SJens Wiklander 		return 0;
59*40bb4a98SJens Wiklander 
60*40bb4a98SJens Wiklander 	return s;
61*40bb4a98SJens Wiklander }
62*40bb4a98SJens Wiklander 
63*40bb4a98SJens Wiklander #define SHDR_GET_SIZE(x)	shdr_get_size((x))
64bc420748SJens Wiklander #define SHDR_GET_HASH(x)	(uint8_t *)(((struct shdr *)(x)) + 1)
65bc420748SJens Wiklander #define SHDR_GET_SIG(x)		(SHDR_GET_HASH(x) + (x)->hash_size)
66bc420748SJens Wiklander 
67b19db423SJens Wiklander /**
68b19db423SJens Wiklander  * struct shdr_bootstrap_ta - bootstrap TA subheader
69b19db423SJens Wiklander  * @uuid:	UUID of the TA
70b19db423SJens Wiklander  * @ta_version:	Version of the TA
71b19db423SJens Wiklander  */
7282b5346dSJens Wiklander struct shdr_bootstrap_ta {
7382b5346dSJens Wiklander 	uint8_t uuid[sizeof(TEE_UUID)];
74a8f769f3SEtienne Carriere 	uint32_t ta_version;
7582b5346dSJens Wiklander };
7682b5346dSJens Wiklander 
77e1afc439SSumit Garg /**
78e1afc439SSumit Garg  * struct shdr_encrypted_ta - encrypted TA header
79e1afc439SSumit Garg  * @enc_algo:	authenticated encyption algorithm, defined by symmetric key
80e1afc439SSumit Garg  *		algorithms TEE_ALG_* from TEE Internal API
81e1afc439SSumit Garg  *		specification
82e1afc439SSumit Garg  * @flags:	authenticated encyption flags
83e1afc439SSumit Garg  * @iv_size:	size of the initialization vector
84e1afc439SSumit Garg  * @tag_size:	size of the authentication tag
85e1afc439SSumit Garg  * @iv:		initialization vector
86e1afc439SSumit Garg  * @tag:	authentication tag
87e1afc439SSumit Garg  */
88e1afc439SSumit Garg struct shdr_encrypted_ta {
89e1afc439SSumit Garg 	uint32_t enc_algo;
90e1afc439SSumit Garg 	uint32_t flags;
91e1afc439SSumit Garg 	uint16_t iv_size;
92e1afc439SSumit Garg 	uint16_t tag_size;
93e1afc439SSumit Garg 	/*
94e1afc439SSumit Garg 	 * Commented out element used to visualize the layout dynamic part
95e1afc439SSumit Garg 	 * of the struct.
96e1afc439SSumit Garg 	 *
97e1afc439SSumit Garg 	 * iv is accessed through the macro SHDR_ENC_GET_IV and
98e1afc439SSumit Garg 	 * tag is accessed through the macro SHDR_ENC_GET_TAG
99e1afc439SSumit Garg 	 *
100e1afc439SSumit Garg 	 * uint8_t iv[iv_size];
101e1afc439SSumit Garg 	 * uint8_t tag[tag_size];
102e1afc439SSumit Garg 	 */
103e1afc439SSumit Garg };
104e1afc439SSumit Garg 
105e1afc439SSumit Garg #define SHDR_ENC_KEY_TYPE_MASK	0x1
106e1afc439SSumit Garg 
107e1afc439SSumit Garg enum shdr_enc_key_type {
108e1afc439SSumit Garg 	SHDR_ENC_KEY_DEV_SPECIFIC = 0,
109e1afc439SSumit Garg 	SHDR_ENC_KEY_CLASS_WIDE = 1,
110e1afc439SSumit Garg };
111e1afc439SSumit Garg 
112e1afc439SSumit Garg #define SHDR_ENC_GET_SIZE(x)	({ typeof(x) _x = (x); \
113e1afc439SSumit Garg 				   (sizeof(struct shdr_encrypted_ta) + \
114e1afc439SSumit Garg 				   _x->iv_size + _x->tag_size); })
115e1afc439SSumit Garg #define SHDR_ENC_GET_IV(x)	((uint8_t *) \
116e1afc439SSumit Garg 				 (((struct shdr_encrypted_ta *)(x)) + 1))
117e1afc439SSumit Garg #define SHDR_ENC_GET_TAG(x)	({ typeof(x) _x = (x); \
118e1afc439SSumit Garg 				   (SHDR_ENC_GET_IV(_x) + _x->iv_size); })
119e1afc439SSumit Garg 
120064663e8SJens Wiklander /*
121064663e8SJens Wiklander  * Allocates a struct shdr large enough to hold the entire header,
122064663e8SJens Wiklander  * excluding a subheader like struct shdr_bootstrap_ta.
123064663e8SJens Wiklander  */
124064663e8SJens Wiklander struct shdr *shdr_alloc_and_copy(const struct shdr *img, size_t img_size);
125bc420748SJens Wiklander 
126064663e8SJens Wiklander /* Frees a previously allocated struct shdr */
127064663e8SJens Wiklander static inline void shdr_free(struct shdr *shdr)
128064663e8SJens Wiklander {
129064663e8SJens Wiklander 	free(shdr);
130064663e8SJens Wiklander }
131064663e8SJens Wiklander 
132064663e8SJens Wiklander /*
133064663e8SJens Wiklander  * Verifies the signature in the @shdr.
134064663e8SJens Wiklander  *
135064663e8SJens Wiklander  * Note that the static part of struct shdr and payload still need to be
136064663e8SJens Wiklander  * checked against the hash contained in the header.
137064663e8SJens Wiklander  *
138064663e8SJens Wiklander  * Returns TEE_SUCCESS on success or TEE_ERROR_SECURITY on failure
139064663e8SJens Wiklander  */
140064663e8SJens Wiklander TEE_Result shdr_verify_signature(const struct shdr *shdr);
141064663e8SJens Wiklander 
142064663e8SJens Wiklander #endif /*SIGNED_HDR_H*/
143