summaryrefslogtreecommitdiff
path: root/include/pinweaver.h
blob: 58210fa03745869687ac008434d7f2c5f23ad6fb (plain)
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
/* Copyright 2018 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef __CROS_EC_INCLUDE_PINWEAVER_H
#define __CROS_EC_INCLUDE_PINWEAVER_H

/* This is required before pinweaver_types.h to provide __packed and __aligned
 * while preserving the ability of pinweaver_types.h to be used in code outside
 * of src/platform/ec.
 */
#include <common.h>
#include <pinweaver_types.h>

#define PW_STORAGE_VERSION 0

#define BITS_PER_LEVEL_MIN 1
#define BITS_PER_LEVEL_MAX 5
#define HEIGHT_MIN 1
/* This will crash for logk == 0 so that condition must not be allowed when
 * using this.
 */
#define HEIGHT_MAX(logk) ((sizeof(struct label_t) * 8) / logk)

/* Persistent information used by this feature. */
struct merkle_tree_t {
	/* log2(Fan out). */
	struct bits_per_level_t bits_per_level;
	/* Height of the tree or param_l / bits_per_level. */
	struct height_t height;

	/* Root hash of the Merkle tree. */
	uint8_t root[PW_HASH_SIZE];

	/* Random bits used as part of the key derivation process. */
	uint8_t key_derivation_nonce[16];

	/* Key used to compute the HMACs of the metadata of the leaves. */
	uint8_t PW_ALIGN_TO_WRD hmac_key[32];

	/* Key used to encrypt and decrypt the metadata of the leaves. */
	uint8_t PW_ALIGN_TO_WRD wrap_key[32];
};

/* Do not remove fields within the same PW_LEAF_MAJOR_VERSION. */
/* Unencrypted part of the leaf data. */
struct PW_PACKED leaf_public_data_t {
	struct label_t label;
	struct delay_schedule_entry_t delay_schedule[PW_SCHED_COUNT];

	/* State used to rate limit. */
	struct pw_timestamp_t timestamp;
	struct attempt_count_t attempt_count;
};

/* Do not remove fields within the same PW_LEAF_MAJOR_VERSION. */
/* Encrypted part of the leaf data. */
struct PW_PACKED PW_ALIGN_TO_BLK leaf_sensitive_data_t {
	uint8_t low_entropy_secret[PW_SECRET_SIZE];
	uint8_t high_entropy_secret[PW_SECRET_SIZE];
	uint8_t reset_secret[PW_SECRET_SIZE];
};

/* Represents leaf data in a form that can be exported for storage. */
struct PW_PACKED wrapped_leaf_data_t {
	/* This is first so that head.leaf_version will be the first field
	 * in the struct to keep the meaning of the struct from becoming
	 * ambiguous across versions.
	 */
	struct leaf_header_t head;
	/* Covers .head, .pub, and .cipher_text. */
	uint8_t hmac[PW_HASH_SIZE];
	uint8_t iv[PW_WRAP_BLOCK_SIZE];
	struct leaf_public_data_t pub;
	uint8_t cipher_text[sizeof(struct leaf_sensitive_data_t)];
};

/* Represents encrypted leaf data after the lengths and version in the header
 * have been validated.
 */
struct imported_leaf_data_t {
	/* This is first so that head.leaf_version will be the first field
	 * in the struct to keep the meaning of the struct from becoming
	 * ambiguous across versions.
	 */
	const struct leaf_header_t *head;
	/* Covers .head, .pub, and .cipher_text. */
	const uint8_t *hmac;
	const uint8_t *iv;
	const struct leaf_public_data_t *pub;
	const uint8_t *cipher_text;
	const uint8_t (*hashes)[PW_HASH_SIZE];
};

/* The leaf data in a clear text working format. */
struct leaf_data_t {
	struct leaf_public_data_t pub;
	struct leaf_sensitive_data_t sec;
};

/* Handler for incoming messages after they have been reconstructed.
 *
 * merkle_tree->root needs to be updated with new_root outside of this function.
 */
int pw_handle_request(struct merkle_tree_t *merkle_tree,
		      const struct pw_request_t *request,
		      struct pw_response_t *response);

/******************************************************************************/
/* Struct helper functions.
 */

/* Sets up pointers to the relevant fields inside an wrapped leaf based on the
 * length fields in the header. These fields should be validated prior to
 * calling this function.
 */
void import_leaf(const struct unimported_leaf_data_t *unimported,
		 struct imported_leaf_data_t *imported);

/* Calculate how much is needed to add to the size of structs containing
 * an struct unimported_leaf_data_t because the variable length fields at the
 * end of the struct are not included by sizeof().
 */
#define PW_LEAF_PAYLOAD_SIZE (sizeof(struct wrapped_leaf_data_t) - \
		sizeof(struct unimported_leaf_data_t))


/******************************************************************************/
/* Utility functions exported for better test coverage.
 */

/* Computes the total number of the sibling hashes along a path. */
int get_path_auxiliary_hash_count(const struct merkle_tree_t *merkle_tree);

/* Computes the parent hash for an array of child hashes. */
void compute_hash(const uint8_t hashes[][PW_HASH_SIZE], uint16_t num_hashes,
		  struct index_t location,
		  const uint8_t child_hash[PW_HASH_SIZE],
		  uint8_t result[PW_HASH_SIZE]);

#endif  /* __CROS_EC_INCLUDE_PINWEAVER_H */