Software APIs
datatypes.h
1// Copyright lowRISC contributors (OpenTitan project).
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4
5#ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_OWNERSHIP_DATATYPES_H_
6#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_OWNERSHIP_DATATYPES_H_
7
8#include <stdint.h>
9
12#include "sw/device/silicon_creator/lib/sigverify/ecdsa_p256_key.h"
13#include "sw/device/silicon_creator/lib/sigverify/rsa_key.h"
14#include "sw/device/silicon_creator/lib/sigverify/spx_key.h"
15
16#ifdef __cplusplus
17extern "C" {
18#endif // __cplusplus
19
20typedef struct hybrid_key {
21 ecdsa_p256_public_key_t ecdsa;
22 sigverify_spx_key_t spx;
23} hybrid_key_t;
24
25/**
26 * An owner_key can be either a ECDSA P256 or SPX+ key. The type of the key
27 * material will be determined by a separate field on the owner block
28 */
29typedef union owner_key {
30 /** ECDSA P256 public key */
31 ecdsa_p256_public_key_t ecdsa;
32 /** SPHINCS+ public key */
33 sigverify_spx_key_t spx;
34 /** Hybrid ECDSA & SPHINCS+ public key */
35 hybrid_key_t hybrid;
36 /** Enough space to hold an ECDSA key and a SPX+ key for hybrid schemes */
37 uint32_t raw[16 + 8];
38} owner_key_t;
39
40/**
41 * An owner_signature is an ECDSA P256 signature.
42 */
43typedef union owner_signature {
44 /** ECDSA P256 signature key */
45 ecdsa_p256_signature_t ecdsa;
46 uint32_t raw[16];
47} owner_signature_t;
48
49typedef enum ownership_state {
50 /* Locked Owner: `OWND`. */
51 kOwnershipStateLockedOwner = 0x444e574f,
52 /* Locked Update: `USLF`. */
53 kOwnershipStateUnlockedSelf = 0x464c5355,
54 /* Unlocked Any: `UANY`. */
55 kOwnershipStateUnlockedAny = 0x594e4155,
56 /* Unlocked Endorsed: `UEND`. */
57 kOwnershipStateUnlockedEndorsed = 0x444e4555,
58 /* Locked None: any bit pattern not listed above. */
59 kOwnershipStateRecovery = 0,
60} ownership_state_t;
61
62typedef enum ownership_key_alg {
63 /** Key algorithm RSA: `RSA3` */
64 kOwnershipKeyAlgRsa = 0x33415352,
65 /** Key algorithm ECDSA P-256: `P256` */
66 kOwnershipKeyAlgEcdsaP256 = 0x36353250,
67 /** Key algorithm SPX+ Pure: `S+Pu` */
68 kOwnershipKeyAlgSpxPure = 0x75502b53,
69 /** Key algorithm SPX+ Prehashed SHA256: `S+S2` */
70 kOwnershipKeyAlgSpxPrehash = 0x32532b53,
71 /** Key algorithm Hybrid P256 & SPX+ Pure: `H+Pu` */
72 kOwnershipKeyAlgHybridSpxPure = 0x75502b48,
73 /** Key algorithm Hybrid P256 & SPX+ Prehashed SHA256: `H+S2` */
74 kOwnershipKeyAlgHybridSpxPrehash = 0x32532b48,
75
76 // Tentative identifiers for SPHINCS+ q20 variants (not yet supported):
77 // Key algorithm SPX+ Pure: `SqPu`
78 kOwnershipKeyAlgSq20Pure = 0x75507153,
79 // Key algorithm SPX+ Prehashed SHA256: `SqS2`
80 kOwnershipKeyAlgSq20Prehash = 0x32537153,
81 // Key algorithm Hybrid P256 & SPX+ Pure: `HqPu`
82 kOwnershipKeyAlgHybridSq20Pure = 0x75507148,
83 // Key algorithm Hybrid P256 & SPX+ Prehashed SHA256: `HqS2`
84 kOwnershipKeyAlgHybridSq20Prehash = 0x32537148,
85
86 /** Key algorithm category mask */
87 kOwnershipKeyAlgCategoryMask = 0xFF,
88 /** Key algorithm category for Sphincs+: `S...` */
89 kOwnershipKeyAlgCategorySpx = 0x53,
90 /** Key algorithm category for Hybrid: `H...` */
91 kOwnershipKeyAlgCategoryHybrid = 0x48,
92} ownership_key_alg_t;
93
94typedef enum ownership_update_mode {
95 /** Update mode open: `OPEN` (unlock key has full power) */
96 kOwnershipUpdateModeOpen = 0x4e45504f,
97 /** Update mode self: `SELF` (unlock key only unlocks to UnlockedSelf) */
98 kOwnershipUpdateModeSelf = 0x464c4553,
99 /**
100 * Update mode NewVersion: `NEWV`
101 * (unlock key can't unlock; accept new owner configs from self-same owner
102 * if the config_version is newer)
103 */
104 kOwnershipUpdateModeNewVersion = 0x5657454e,
105 /**
106 * Update mode SelfVersion: `SELV`
107 * (unlock key only unlocks to UnlockedSelf; accept new owner configs from
108 * self-same owner if the config_version is newer)
109 */
110 kOwnershipUpdateModeSelfVersion = 0x564c4553,
111} ownership_update_mode_t;
112
113typedef enum lock_constraint {
114 /** No locking constraint: `~~~~`. */
115 kLockConstraintNone = 0x7e7e7e7e,
116} lock_constraint_t;
117
118typedef enum tlv_tag {
119 /** Owner struct: `OWNR`. */
120 kTlvTagOwner = 0x524e574f,
121 /** Application Key: `APPK`. */
122 kTlvTagApplicationKey = 0x4b505041,
123 /** Flash Configuration: `FLSH`. */
124 kTlvTagFlashConfig = 0x48534c46,
125 /** Flash INFO configuration: `INFO`. */
126 kTlvTagInfoConfig = 0x4f464e49,
127 /** Rescue Configuration: `RESQ`. */
128 kTlvTagRescueConfig = 0x51534552,
129 /** Not Present: `ZZZZ`. */
130 kTlvTagNotPresent = 0x5a5a5a5a,
131} tlv_tag_t;
132
133typedef struct struct_version {
134 uint8_t major;
135 uint8_t minor;
136} struct_version_t;
137
138typedef struct tlv_header {
139 uint32_t tag;
140 uint16_t length;
141 struct_version_t version;
142} tlv_header_t;
143
144typedef enum owner_sram_exec_mode {
145 /** SRAM Exec disabled and locked: `LNEX`. */
146 kOwnerSramExecModeDisabledLocked = 0x58454e4c,
147 /** SRAM Exec disabled: `NOEX`. */
148 kOwnerSramExecModeDisabled = 0x58454f4e,
149 /** SRAM Exec enabled: `EXEC` */
150 kOwnerSramExecModeEnabled = 0x43455845,
151} owner_sram_exec_mode_t;
152
153/**
154 * The owner configuration block describes an owner identity and configuration.
155 */
156typedef struct owner_block {
157 /**
158 * Header identifying this struct.
159 * tag: `OWNR`.
160 * length: 2048.
161 * version: 0
162 */
163 tlv_header_t header;
164 /** Configuraion version (monotonically increasing per owner) */
166 /** SRAM execution configuration (DisabledLocked, Disabled, Enabled). */
168 /** Ownership key algorithm (currently, only ECDSA is supported). */
170 /** Ownership update mode (one of OPEN, SELF, NEWV) */
171 uint32_t update_mode;
172 /** Set the minimum security version to this value (UINT32_MAX: no change) */
174 /** The device ID locking constraint */
176 /** The device ID to which this config applies */
177 uint32_t device_id[8];
178 /** Reserved space for future use. */
179 uint32_t reserved[16];
180 /** Owner public key. */
181 owner_key_t owner_key;
182 /** Owner's Activate public key. */
183 owner_key_t activate_key;
184 /** Owner's Unlock public key. */
185 owner_key_t unlock_key;
186 /** Data region to hold the other configuration structs. */
187 uint8_t data[1536];
188 /** Signature over the owner block with the Owner private key. */
189 owner_signature_t signature;
190 /** A sealing value to seal the owner block to a specific chip. */
191 uint32_t seal[8];
192} owner_block_t;
193
194OT_ASSERT_MEMBER_OFFSET(owner_block_t, header, 0);
195OT_ASSERT_MEMBER_OFFSET(owner_block_t, config_version, 8);
196OT_ASSERT_MEMBER_OFFSET(owner_block_t, sram_exec_mode, 12);
197OT_ASSERT_MEMBER_OFFSET(owner_block_t, ownership_key_alg, 16);
198OT_ASSERT_MEMBER_OFFSET(owner_block_t, update_mode, 20);
199OT_ASSERT_MEMBER_OFFSET(owner_block_t, min_security_version_bl0, 24);
200OT_ASSERT_MEMBER_OFFSET(owner_block_t, lock_constraint, 28);
201OT_ASSERT_MEMBER_OFFSET(owner_block_t, device_id, 32);
202OT_ASSERT_MEMBER_OFFSET(owner_block_t, reserved, 64);
203OT_ASSERT_MEMBER_OFFSET(owner_block_t, owner_key, 128);
204OT_ASSERT_MEMBER_OFFSET(owner_block_t, activate_key, 224);
205OT_ASSERT_MEMBER_OFFSET(owner_block_t, unlock_key, 320);
206OT_ASSERT_MEMBER_OFFSET(owner_block_t, data, 416);
207OT_ASSERT_MEMBER_OFFSET(owner_block_t, signature, 1952);
208OT_ASSERT_MEMBER_OFFSET(owner_block_t, seal, 2016);
209OT_ASSERT_SIZE(owner_block_t, 2048);
210
211/**
212 * The owner application domain designates an application key
213 * as one of Test, Dev or Prod.
214 */
215typedef enum owner_app_domain {
216 /** Test domain: `test` */
217 kOwnerAppDomainTest = 0x74736574,
218 /** Dev domain: `dev_` */
219 kOwnerAppDomainDev = 0x5f766564,
220 /** Prod domain: `prod` */
221 kOwnerAppDomainProd = 0x646f7270,
222} owner_app_domain_t;
223/**
224 * The owner application key encodes keys for verifying the owner's application
225 * firmware.
226 */
227typedef struct owner_application_key {
228 /**
229 * Header identifying this struct.
230 * tag: `APPK`.
231 * length: 48 + sizeof(key).
232 */
233 tlv_header_t header;
234 /** Key algorithm. One of ECDSA, SPX+ or SPXq20. */
235 uint32_t key_alg;
236 union {
237 struct {
238 /** Key domain. Recognized values: PROD, DEV, TEST */
239 uint32_t key_domain;
240 /** Key diversifier.
241 *
242 * This value is concatenated to key_domain to create an 8 word
243 * diversification constant to be programmed into the keymgr.
244 */
245 uint32_t key_diversifier[7];
246 };
247 uint32_t raw_diversifier[8];
248 };
249 /** Usage constraint must match manifest header's constraint */
251 /** Key material. Varies by algorithm type. */
252 union {
253 uint32_t id;
254 sigverify_rsa_key_t rsa;
255 sigverify_spx_key_t spx;
256 ecdsa_p256_public_key_t ecdsa;
257 hybrid_key_t hybrid;
259} owner_application_key_t;
260
261OT_ASSERT_MEMBER_OFFSET(owner_application_key_t, header, 0);
262OT_ASSERT_MEMBER_OFFSET(owner_application_key_t, key_alg, 8);
263OT_ASSERT_MEMBER_OFFSET(owner_application_key_t, key_domain, 12);
264OT_ASSERT_MEMBER_OFFSET(owner_application_key_t, key_diversifier, 16);
265OT_ASSERT_MEMBER_OFFSET(owner_application_key_t, usage_constraint, 44);
266OT_ASSERT_MEMBER_OFFSET(owner_application_key_t, data, 48);
267OT_ASSERT_SIZE(owner_application_key_t, 464);
268
269enum {
270 kTlvLenApplicationKeyRsa =
271 offsetof(owner_application_key_t, data) + sizeof(sigverify_rsa_key_t),
272 kTlvLenApplicationKeySpx =
273 offsetof(owner_application_key_t, data) + sizeof(sigverify_spx_key_t),
274 kTlvLenApplicationKeyEcdsa =
275 offsetof(owner_application_key_t, data) + sizeof(ecdsa_p256_public_key_t),
276 kTlvLenApplicationKeyHybrid =
277 offsetof(owner_application_key_t, data) + sizeof(hybrid_key_t),
278};
279
280// clang-format off
281/**
282 * Bitfields for the `access` word of flash region configs.
283 */
284#define FLASH_CONFIG_READ ((bitfield_field32_t) { .mask = 0xF, .index = 0 })
285#define FLASH_CONFIG_PROGRAM ((bitfield_field32_t) { .mask = 0xF, .index = 4 })
286#define FLASH_CONFIG_ERASE ((bitfield_field32_t) { .mask = 0xF, .index = 8 })
287#define FLASH_CONFIG_PROTECT_WHEN_PRIMARY ((bitfield_field32_t) { .mask = 0xF, .index = 24 })
288#define FLASH_CONFIG_LOCK ((bitfield_field32_t) { .mask = 0xF, .index = 28 })
289
290/**
291 * Bitfields for the `properties` word of flash region configs.
292 */
293#define FLASH_CONFIG_SCRAMBLE ((bitfield_field32_t) { .mask = 0xF, .index = 0 })
294#define FLASH_CONFIG_ECC ((bitfield_field32_t) { .mask = 0xF, .index = 4 })
295#define FLASH_CONFIG_HIGH_ENDURANCE ((bitfield_field32_t) { .mask = 0xF, .index = 8 })
296// clang-format on
297
298/**
299 * The owner flash region describes a region of flash and its configuration
300 * properties (ie: ECC, Scrambling, High Endurance, etc).
301 */
302typedef struct owner_flash_region {
303 /** The start of the region, in flash pages. */
304 uint16_t start;
305 /** The size of the region, in flash pages. */
306 uint16_t size;
307 /** The access properties of the flash region. */
308 uint32_t access;
309 /** The flash properties of the flash region. */
310 uint32_t properties;
311} owner_flash_region_t;
312OT_ASSERT_SIZE(owner_flash_region_t, 12);
313
314/**
315 * The owner flash config is a collection of owner region configuration items.
316 */
317typedef struct owner_flash_config {
318 /**
319 * Header identifiying this struct.
320 * tag: `FLSH`.
321 * length: 8 + 12 * length(config).
322 */
323 tlv_header_t header;
324 /**
325 * A list of flash region configurations.
326 * In each `config` item, the `access` and `properties` fields are xor-ed
327 * with the region index in each nibble (ie: index 1 == 0x11111111).
328 */
329 owner_flash_region_t config[];
330} owner_flash_config_t;
331OT_ASSERT_MEMBER_OFFSET(owner_flash_config_t, header, 0);
332OT_ASSERT_MEMBER_OFFSET(owner_flash_config_t, config, 8);
333OT_ASSERT_SIZE(owner_flash_config_t, 8);
334
335/**
336 * The owner info page describes an INFO page in flash and its configuration
337 * properties (ie: ECC, Scrambling, High Endurance, etc).
338 */
339typedef struct owner_info_page {
340 /** The bank where the info page is located. */
341 uint8_t bank;
342 /** The info page number. */
343 uint8_t page;
344 uint16_t _pad;
345 /** The access properties of the flash region. */
346 uint32_t access;
347 /** The flash properties of the flash region. */
348 uint32_t properties;
349} owner_info_page_t;
350OT_ASSERT_SIZE(owner_info_page_t, 12);
351
353 /**
354 * Header identifiying this struct.
355 * tag: `INFO`.
356 * length: 8 + 12 * length(config).
357 */
358 tlv_header_t header;
359 /**
360 * A list of flash info page configurations.
361 * In each `config` item, the `access` and `properties` fields are xor-ed
362 * with the region index in each nibble (ie: index 1 == 0x11111111).
363 */
364 owner_info_page_t config[];
365} owner_flash_info_config_t;
366OT_ASSERT_MEMBER_OFFSET(owner_flash_info_config_t, header, 0);
367OT_ASSERT_MEMBER_OFFSET(owner_flash_info_config_t, config, 8);
368OT_ASSERT_SIZE(owner_flash_info_config_t, 8);
369
370/**
371 * The owner rescue configuration describes how the rescue protocol should
372 * behave when invoked in the ROM_EXT.
373 */
374typedef struct owner_rescue_config {
375 /**
376 * Header identifiying this struct.
377 * tag: `RESQ`.
378 * length: 16 + sizeof(command_allow).
379 */
380 tlv_header_t header;
381 /** The rescue type. Currently, only `XMDM` is supported. */
382 uint32_t rescue_type;
383 /** The start offset of the rescue region in flash (in pages). */
384 uint16_t start;
385 /** The size of the rescue region in flash (in pages). */
386 uint16_t size;
387 /** An allowlist of rescue and boot_svc commands that may be invoked by the
388 * rescue protocol. The commands are identified by their 4-byte tags (tag
389 * identifiers between rescue commands and boot_svc commands are unique).
390 */
391 uint32_t command_allow[];
392} owner_rescue_config_t;
393OT_ASSERT_MEMBER_OFFSET(owner_rescue_config_t, header, 0);
394OT_ASSERT_MEMBER_OFFSET(owner_rescue_config_t, rescue_type, 8);
395OT_ASSERT_MEMBER_OFFSET(owner_rescue_config_t, start, 12);
396OT_ASSERT_MEMBER_OFFSET(owner_rescue_config_t, size, 14);
397OT_ASSERT_MEMBER_OFFSET(owner_rescue_config_t, command_allow, 16);
398OT_ASSERT_SIZE(owner_rescue_config_t, 16);
399
400#ifdef __cplusplus
401} // extern "C"
402#endif // __cplusplus
403#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_OWNERSHIP_DATATYPES_H_