blob: 21571da7b068bcbeffe46d5a997c32577a6931ad [file] [log] [blame]
Andrey Pronin9b10e512021-04-13 11:18:53 -07001/* Copyright 2018 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6#ifndef __CROS_EC_INCLUDE_PINWEAVER_H
7#define __CROS_EC_INCLUDE_PINWEAVER_H
8
9/* This is required before pinweaver_types.h to provide __packed and __aligned
10 * while preserving the ability of pinweaver_types.h to be used in code outside
11 * of src/platform/ec.
12 */
13#include <common.h>
14#include <pinweaver_types.h>
15
16#ifdef __cplusplus
17extern "C" {
18#endif
19
20#define PW_STORAGE_VERSION 0
21
22#define BITS_PER_LEVEL_MIN 1
23#define BITS_PER_LEVEL_MAX 5
24#define HEIGHT_MIN 1
25/* This will crash for logk == 0 so that condition must not be allowed when
26 * using this.
27 */
28#define HEIGHT_MAX(logk) ((sizeof(struct label_t) * 8) / logk)
29
30#define PW_LOG_ENTRY_COUNT 2
31
32/* Persistent information used by this feature. */
33struct merkle_tree_t {
34 /* log2(Fan out). */
35 struct bits_per_level_t bits_per_level;
36 /* Height of the tree or param_l / bits_per_level. */
37 struct height_t height;
38
39 /* Root hash of the Merkle tree. */
40 uint8_t root[PW_HASH_SIZE];
41
42 /* Random bits used as part of the key derivation process. */
43 uint8_t key_derivation_nonce[16];
44
45 /* Key used to compute the HMACs of the metadata of the leaves. */
46 uint8_t PW_ALIGN_TO_WRD hmac_key[32];
47
48 /* Key used to encrypt and decrypt the metadata of the leaves. */
49 uint8_t PW_ALIGN_TO_WRD wrap_key[32];
50};
51
52/* Long term flash storage for tree metadata. */
53struct PW_PACKED pw_long_term_storage_t {
54 uint16_t storage_version;
55
56 /* log2(Fan out). */
57 struct bits_per_level_t bits_per_level;
58 /* Height of the tree or param_l / bits_per_level. */
59 struct height_t height;
60
61 /* Random bits used as part of the key derivation process. */
62 uint8_t key_derivation_nonce[16];
63};
64
65struct PW_PACKED pw_log_storage_t {
66 uint16_t storage_version;
67 uint32_t restart_count;
68 struct pw_get_log_entry_t entries[PW_LOG_ENTRY_COUNT];
69};
70
71/* Do not remove fields within the same PW_LEAF_MAJOR_VERSION. */
72/* Encrypted part of the leaf data.
73 */
74struct PW_PACKED PW_ALIGN_TO_BLK leaf_sensitive_data_t {
75 uint8_t low_entropy_secret[PW_SECRET_SIZE];
76 uint8_t high_entropy_secret[PW_SECRET_SIZE];
77 uint8_t reset_secret[PW_SECRET_SIZE];
78};
79
80/* Represents leaf data in a form that can be exported for storage. */
81struct PW_PACKED wrapped_leaf_data_t {
82 /* This is first so that head.leaf_version will be the first field
83 * in the struct to keep the meaning of the struct from becoming
84 * ambiguous across versions.
85 */
86 struct leaf_header_t head;
87 /* Covers .head, .pub, and .cipher_text. */
88 uint8_t hmac[PW_HASH_SIZE];
89 uint8_t iv[PW_WRAP_BLOCK_SIZE];
90 struct leaf_public_data_t pub;
91 uint8_t cipher_text[sizeof(struct leaf_sensitive_data_t)];
92};
93
94/* Represents encrypted leaf data after the lengths and version in the header
95 * have been validated.
96 */
97struct imported_leaf_data_t {
98 /* This is first so that head.leaf_version will be the first field
99 * in the struct to keep the meaning of the struct from becoming
100 * ambiguous across versions.
101 */
102 const struct leaf_header_t *head;
103 /* Covers .head, .pub, and .cipher_text. */
104 const uint8_t *hmac;
105 const uint8_t *iv;
106 const struct leaf_public_data_t *pub;
107 const uint8_t *cipher_text;
108 const uint8_t (*hashes)[PW_HASH_SIZE];
109};
110
111/* The leaf data in a clear text working format. */
112struct leaf_data_t {
113 struct leaf_public_data_t pub;
114 struct leaf_sensitive_data_t sec;
115};
116
117/* Key names for nvmem_vars */
118#define PW_TREE_VAR "pwT0"
119#define PW_LOG_VAR0 "pwL0"
120/* The maximum key-value pair space allowed for the values of PinWeaver until
121 * the Cr50 NVRAM implementation is updated to use a separate object per
122 * key value pair.
123 */
124#define PW_MAX_VAR_USAGE 192
125
126/* Initializes the PinWeaver feature.
127 *
128 * This needs to be called prior to handling any messages.
129 */
130void pinweaver_init(void);
131
132/* Handler for incoming messages after they have been reconstructed.
133 *
134 * merkle_tree->root needs to be updated with new_root outside of this function.
135 */
136int pw_handle_request(struct merkle_tree_t *merkle_tree,
137 struct pw_request_t *request,
138 struct pw_response_t *response);
139
140/******************************************************************************/
141/* Struct helper functions.
142 */
143
144/* Sets up pointers to the relevant fields inside an wrapped leaf based on the
145 * length fields in the header. These fields should be validated prior to
146 * calling this function.
147 */
148void import_leaf(const struct unimported_leaf_data_t *unimported,
149 struct imported_leaf_data_t *imported);
150
151/* Calculate how much is needed to add to the size of structs containing
152 * an struct unimported_leaf_data_t because the variable length fields at the
153 * end of the struct are not included by sizeof().
154 */
155#define PW_LEAF_PAYLOAD_SIZE (sizeof(struct wrapped_leaf_data_t) - \
156 sizeof(struct unimported_leaf_data_t))
157
158
159/******************************************************************************/
160/* Utility functions exported for better test coverage.
161 */
162
163/* Computes the total number of the sibling hashes along a path. */
164int get_path_auxiliary_hash_count(const struct merkle_tree_t *merkle_tree);
165
166/* Computes the parent hash for an array of child hashes. */
167void compute_hash(const uint8_t hashes[][PW_HASH_SIZE], uint16_t num_hashes,
168 struct index_t location,
169 const uint8_t child_hash[PW_HASH_SIZE],
170 uint8_t result[PW_HASH_SIZE]);
171
172/* This should only be used in tests. */
173void force_restart_count(uint32_t mock_value);
174
175/* NV RAM log functions exported for use in test code. */
176int store_log_data(const struct pw_log_storage_t *log);
177int store_merkle_tree(const struct merkle_tree_t *merkle_tree);
178int log_insert_leaf(struct label_t label, const uint8_t root[PW_HASH_SIZE],
179 const uint8_t hmac[PW_HASH_SIZE]);
180int log_remove_leaf(struct label_t label, const uint8_t root[PW_HASH_SIZE]);
181int log_auth(struct label_t label, const uint8_t root[PW_HASH_SIZE], int code,
182 struct pw_timestamp_t timestamp);
183
184#ifdef __cplusplus
185}
186#endif
187
188#endif /* __CROS_EC_INCLUDE_PINWEAVER_H */