1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3 * Copyright (c) 2015, Linaro Limited
4 */
5 #ifndef SIGNED_HDR_H
6 #define SIGNED_HDR_H
7
8 #include <inttypes.h>
9 #include <stdlib.h>
10 #include <tee_api_types.h>
11 #include <util.h>
12
13 enum shdr_img_type {
14 SHDR_TA = 0,
15 SHDR_BOOTSTRAP_TA = 1,
16 SHDR_ENCRYPTED_TA = 2,
17 };
18
19 #define SHDR_MAGIC 0x4f545348
20
21 /**
22 * struct shdr - signed header
23 * @magic: magic number must match SHDR_MAGIC
24 * @img_type: image type, values defined by enum shdr_img_type
25 * @img_size: image size in bytes
26 * @algo: algorithm, defined by public key algorithms TEE_ALG_*
27 * from TEE Internal API specification
28 * @hash_size: size of the signed hash
29 * @sig_size: size of the signature
30 * @hash: hash of an image
31 * @sig: signature of @hash
32 */
33 struct shdr {
34 uint32_t magic;
35 uint32_t img_type;
36 uint32_t img_size;
37 uint32_t algo;
38 uint16_t hash_size;
39 uint16_t sig_size;
40 /*
41 * Commented out element used to visualize the layout dynamic part
42 * of the struct.
43 *
44 * hash is accessed through the macro SHDR_GET_HASH and
45 * signature is accessed through the macro SHDR_GET_SIG
46 *
47 * uint8_t hash[hash_size];
48 * uint8_t sig[sig_size];
49 */
50 };
51
shdr_get_size(const struct shdr * shdr)52 static inline size_t shdr_get_size(const struct shdr *shdr)
53 {
54 size_t s = sizeof(*shdr);
55
56 if (ADD_OVERFLOW(s, shdr->hash_size, &s) ||
57 ADD_OVERFLOW(s, shdr->sig_size, &s))
58 return 0;
59
60 return s;
61 }
62
63 #define SHDR_GET_SIZE(x) shdr_get_size((x))
64 #define SHDR_GET_HASH(x) (uint8_t *)(((struct shdr *)(x)) + 1)
65 #define SHDR_GET_SIG(x) (SHDR_GET_HASH(x) + (x)->hash_size)
66
67 /**
68 * struct shdr_bootstrap_ta - bootstrap TA subheader
69 * @uuid: UUID of the TA
70 * @ta_version: Version of the TA
71 */
72 struct shdr_bootstrap_ta {
73 uint8_t uuid[sizeof(TEE_UUID)];
74 uint32_t ta_version;
75 };
76
77 /**
78 * struct shdr_encrypted_ta - encrypted TA header
79 * @enc_algo: authenticated encyption algorithm, defined by symmetric key
80 * algorithms TEE_ALG_* from TEE Internal API
81 * specification
82 * @flags: authenticated encyption flags
83 * @iv_size: size of the initialization vector
84 * @tag_size: size of the authentication tag
85 * @iv: initialization vector
86 * @tag: authentication tag
87 */
88 struct shdr_encrypted_ta {
89 uint32_t enc_algo;
90 uint32_t flags;
91 uint16_t iv_size;
92 uint16_t tag_size;
93 /*
94 * Commented out element used to visualize the layout dynamic part
95 * of the struct.
96 *
97 * iv is accessed through the macro SHDR_ENC_GET_IV and
98 * tag is accessed through the macro SHDR_ENC_GET_TAG
99 *
100 * uint8_t iv[iv_size];
101 * uint8_t tag[tag_size];
102 */
103 };
104
105 #define SHDR_ENC_KEY_TYPE_MASK 0x1
106
107 enum shdr_enc_key_type {
108 SHDR_ENC_KEY_DEV_SPECIFIC = 0,
109 SHDR_ENC_KEY_CLASS_WIDE = 1,
110 };
111
shdr_enc_get_size(const struct shdr_encrypted_ta * ehdr)112 static inline size_t shdr_enc_get_size(const struct shdr_encrypted_ta *ehdr)
113 {
114 size_t s = sizeof(*ehdr);
115
116 if (ADD_OVERFLOW(s, ehdr->iv_size, &s) ||
117 ADD_OVERFLOW(s, ehdr->tag_size, &s))
118 return 0;
119
120 return s;
121 }
122
123 #define SHDR_ENC_GET_SIZE(x) shdr_enc_get_size((x))
124 #define SHDR_ENC_GET_IV(x) ((uint8_t *) \
125 (((struct shdr_encrypted_ta *)(x)) + 1))
126 #define SHDR_ENC_GET_TAG(x) ({ typeof(x) _x = (x); \
127 (SHDR_ENC_GET_IV(_x) + _x->iv_size); })
128
129 /*
130 * Allocates a struct shdr large enough to hold the entire header,
131 * excluding a subheader like struct shdr_bootstrap_ta.
132 */
133 struct shdr *shdr_alloc_and_copy(const struct shdr *img, size_t img_size);
134
135 /* Frees a previously allocated struct shdr */
shdr_free(struct shdr * shdr)136 static inline void shdr_free(struct shdr *shdr)
137 {
138 free(shdr);
139 }
140
141 /*
142 * Verifies the signature in the @shdr.
143 *
144 * Note that the static part of struct shdr and payload still need to be
145 * checked against the hash contained in the header.
146 *
147 * Returns TEE_SUCCESS on success or TEE_ERROR_SECURITY on failure
148 */
149 TEE_Result shdr_verify_signature(const struct shdr *shdr);
150
151 #endif /*SIGNED_HDR_H*/
152