1 /*
2  * Copyright (c) 2021 Google Inc. All rights reserved
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 #pragma once
25 
26 #include <lk/compiler.h>
27 #include <stdbool.h>
28 #include <stddef.h>
29 #include <stdint.h>
30 #include <uapi/trusty_uuid.h>
31 
32 __BEGIN_CDECLS
33 
34 /**
35  * enum app_manifest_config_key - Manifest configuration entry keys
36  * @APP_MANIFEST_CONFIG_KEY_MIN_STACK_SIZE: Key for "min_stack"
37  * @APP_MANIFEST_CONFIG_KEY_MIN_HEAP_SIZE: Key for "min_heap"
38  * @APP_MANIFEST_CONFIG_KEY_MAP_MEM: Key for memory maps
39  * @APP_MANIFEST_CONFIG_KEY_MGMT_FLAGS: Key for "mgmt_flags"
40  * @APP_MANIFEST_CONFIG_KEY_START_PORT: Key for "start_ports"
41  * @APP_MANIFEST_CONFIG_KEY_PINNED_CPU: Key for "pinned_cpu"
42  * @APP_MANIFEST_CONFIG_KEY_VERSION: Key for "version"
43  * @APP_MANIFEST_CONFIG_KEY_MIN_SHADOW_STACK_SIZE: Key for "min_shadow_stack"
44  * @APP_MANIFEST_CONFIG_KEY_APPLOADER: Key for "apploader_flags"
45  * @APP_MANIFEST_CONFIG_KEY_PRIORITY: Key for "priority" value
46  * @APP_MANIFEST_CONFIG_KEY_UUID: Pseudo-key for "uuid"
47  * @APP_MANIFEST_CONFIG_KEY_APP_NAME: Pseudo-key for name of application
48  * @APP_MANIFEST_CONFIG_KEY_MIN_VERSION: Key for "min_version"
49  */
50 enum app_manifest_config_key {
51     APP_MANIFEST_CONFIG_KEY_MIN_STACK_SIZE = 1,
52     APP_MANIFEST_CONFIG_KEY_MIN_HEAP_SIZE = 2,
53     APP_MANIFEST_CONFIG_KEY_MAP_MEM = 3,
54     APP_MANIFEST_CONFIG_KEY_MGMT_FLAGS = 4,
55     APP_MANIFEST_CONFIG_KEY_START_PORT = 5,
56     APP_MANIFEST_CONFIG_KEY_PINNED_CPU = 6,
57     APP_MANIFEST_CONFIG_KEY_VERSION = 7,
58     APP_MANIFEST_CONFIG_KEY_MIN_SHADOW_STACK_SIZE = 8,
59     APP_MANIFEST_CONFIG_KEY_APPLOADER_FLAGS = 9,
60     APP_MANIFEST_CONFIG_KEY_PRIORITY = 10,
61     APP_MANIFEST_CONFIG_KEY_MIN_VERSION = 11,
62 
63     /* Pseudo-keys for required entries */
64     APP_MANIFEST_CONFIG_KEY_UUID = 0xfffffffeU,
65     APP_MANIFEST_CONFIG_KEY_APP_NAME = 0xffffffffU,
66 };
67 
68 /**
69  * enum app_manifest_mgmt_flags - Masks for mgmt_flags configuration value
70  * @APP_MANIFEST_MGMT_FLAGS_NONE:
71  *      No flags
72  * @APP_MANIFEST_MGMT_FLAGS_RESTART_ON_EXIT:
73  *      Restart the application on exit
74  * @APP_MANIFEST_MGMT_FLAGS_DEFERRED_START:
75  *      Don't start the application at boot
76  * @APP_MANIFEST_MGMT_FLAGS_NON_CRITICAL_APP:
77  *      Exit application if application crashes or exit with a non-0 exit code
78  */
79 enum app_manifest_mgmt_flags {
80     APP_MANIFEST_MGMT_FLAGS_NONE = 0u,
81     APP_MANIFEST_MGMT_FLAGS_RESTART_ON_EXIT = (1u << 0),
82     APP_MANIFEST_MGMT_FLAGS_DEFERRED_START = (1u << 1),
83     APP_MANIFEST_MGMT_FLAGS_NON_CRITICAL_APP = (1u << 2),
84 };
85 
86 /**
87  * enum app_manifest_apploader_flags - Masks for apploader_flags configuration
88  *                                     value
89  * @APP_MANIFEST_APPLOADER_FLAGS_NONE:
90  *      No flags
91  * @APP_MANIFEST_APPLOADER_FLAGS_REQUIRES_ENCRYPTION:
92  *      Unless apploading is unlocked, require that the ELF image was encrypted
93  */
94 enum app_manifest_apploader_flags {
95     APP_MANIFEST_APPLOADER_FLAGS_NONE = 0u,
96     APP_MANIFEST_APPLOADER_FLAGS_REQUIRES_ENCRYPTION = (1u << 0),
97 };
98 
99 #define APP_MANIFEST_PINNED_CPU_NONE (-1)
100 
101 /**
102  * struct app_manifest_config_entry - Manifest configuration entry
103  * @key: Key for this entry, one of &enum app_manifest_config_key
104  * @value: The value for this key
105  * @value.uuid: Value of "uuid"
106  * @value.app_name: Name of application
107  * @value.min_stack_size: Value of "min_stack"
108  * @value.min_heap_size: Value of "min_heap"
109  * @value.mem_map: Values for "mem_map" key
110  * @value.mem_map.id: Value of "mem_map.id"
111  * @value.mem_map.arch_mmu_flags: Flags for memory mapping
112  * @value.mem_map.offset: Value of "mem_map.addr"
113  * @value.mem_map.size: Value of "mem_map.size"
114  * @value.mgmt_flags: Encoded value of "mgmt_flags", bitwise OR
115  *                    of values from &enum app_manifest_mgmt_flags
116  * @value.start_port: Values for "start_port" key
117  * @value.start_port.name_size: Size of @start_port.name
118  * @value.start_port.flags: Encoded value of "start_ports[...].flags"
119  * @value.start_port.name: Value of "start_ports[...].name"
120  * @value.pinned_cpu: Value of "pinned_cpu"
121  * @value.version: Value of "version"
122  * @value.min_version: Values ot "min_version"
123  * @value.apploader_flags: Flags for apploading
124  * @value.priority: Value of "priority"
125  */
126 struct app_manifest_config_entry {
127     enum app_manifest_config_key key;
128     union {
129         uuid_t uuid;
130         const char* app_name;
131         uint32_t min_stack_size;
132         uint32_t min_shadow_stack_size;
133         uint32_t min_heap_size;
134         struct {
135             uint32_t id;
136             uint32_t arch_mmu_flags;
137             uint64_t offset;
138             uint64_t size;
139         } mem_map;
140         uint32_t mgmt_flags;
141         struct {
142             uint32_t name_size;
143             uint32_t flags;
144             const char* name;
145         } start_port;
146         int pinned_cpu;
147         uint32_t version;
148         uint32_t min_version;
149         uint32_t apploader_flags;
150         uint32_t priority;
151     } value;
152 };
153 
154 /**
155  * struct app_manifest_iterator - Iterator over manifest contents
156  * @manifest_data: Pointer to start of manifest
157  * @manifest_size: Size of manifest in bytes
158  * @index: Index of the next entry in the manifest
159  * @app_name: Name of the application
160  * @error: Error code set by internal parsing functions
161  */
162 struct app_manifest_iterator {
163     const char* manifest_data;
164     size_t manifest_size;
165     size_t index;
166     const char* app_name;
167     int error;
168 };
169 
170 /**
171  * app_manifest_iterator_reset - Resets an iterator for a new iteration round
172  * @iterator: Pointer to output iterator to reset
173  * @manifest_data: Pointer to start of manifest
174  * @manifest_size: Size of manifest in bytes
175  *
176  * Return: %NO_ERROR if successful, an error value otherwise.
177  */
178 int app_manifest_iterator_reset(struct app_manifest_iterator* iterator,
179                                 const char* manifest_data,
180                                 size_t manifest_size);
181 
182 /**
183  * app_manifest_iterator_next - Advance the iterator to the next entry
184  *                              and read it into @entry
185  * @iterator: The iterator
186  * @entry: The next entry
187  * @out_error: If not %NULL, pointer to variable to store error code into
188  *
189  * Return: %true if the iterator was successfully advanced and an entry was
190  * read, %false otherwise. The function will set @out_error (if not %NULL) to
191  * %NO_ERROR in case the manifest ran out of entries, or to the actual error
192  * in case an error occurred, e.g., %ERR_NOT_VALID in case of invalid manifest.
193  */
194 bool app_manifest_iterator_next(struct app_manifest_iterator* iterator,
195                                 struct app_manifest_config_entry* entry,
196                                 int* out_error);
197 
198 __END_CDECLS
199