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