1 /*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4 */
5
6 #ifndef MEASUREMENT_H
7 #define MEASUREMENT_H
8
9 #include <assert.h>
10 #include <stdbool.h>
11 #include <stddef.h>
12 #include <utils_def.h>
13
14 /* Supported algorithms */
15 enum hash_algo {
16 HASH_ALGO_SHA256 = 0,
17 HASH_ALGO_SHA512 = 1,
18 };
19
20 /*
21 * RmiDataMeasureContent enumeration representing
22 * whether to measure DATA Granule contents.
23 */
24 enum rmi_data_measure_content {
25 /* Do not measure DATA Granule contents */
26 RMI_NO_MEASURE_CONTENT = 0U,
27
28 /* Measure DATA Granule contents */
29 RMI_MEASURE_CONTENT = 1U
30 };
31
32 /*
33 * Types of measurement headers as specified in RMM Spec. section C1.1.2
34 */
35 #define MEASUREMENT_REALM_HEADER (1U)
36 #define MEASUREMENT_DATA_HEADER (2U)
37 #define MEASUREMENT_REC_HEADER (3U)
38
39 /* Measurement slot reserved for RIM */
40 #define RIM_MEASUREMENT_SLOT (0U)
41
42 /* Maximum number of measurements */
43 #define MEASUREMENT_SLOT_NR (5U)
44
45 /* Size in bytes of the SHA256 measurement */
46 #define SHA256_SIZE (32U)
47
48 /* Size in bytes of the SHA512 measurement */
49 #define SHA512_SIZE (64U)
50
51 #define MEASURE_DESC_TYPE_DATA 0x0
52 #define MEASURE_DESC_TYPE_REC 0x1
53 #define MEASURE_DESC_TYPE_RIPAS 0x2
54
55 /*
56 * Size in bytes of the largest measurement type that can be supported.
57 * This macro needs to be updated accordingly if new algorithms are supported.
58 */
59 #define MAX_MEASUREMENT_SIZE SHA512_SIZE
60
61 /* RmmMeasurementDescriptorData type as per RMM spec */
62 struct measurement_desc_data {
63 /* Measurement descriptor type, value 0x0 */
64 SET_MEMBER(unsigned char desc_type, 0x0, 0x8);
65 /* Length of this data structure in bytes */
66 SET_MEMBER(unsigned long len, 0x8, 0x10);
67 /* Current RIM value */
68 SET_MEMBER(unsigned char rim[MAX_MEASUREMENT_SIZE], 0x10, 0x50);
69 /* IPA at which the DATA Granule is mapped in the Realm */
70 SET_MEMBER(unsigned long ipa, 0x50, 0x58);
71 /* Flags provided by Host */
72 SET_MEMBER(unsigned long flags, 0x58, 0x60);
73 /*
74 * Hash of contents of DATA Granule, or zero if flags indicate DATA
75 * Granule contents are unmeasured
76 */
77 SET_MEMBER(unsigned char content[MAX_MEASUREMENT_SIZE], 0x60, 0x100);
78 };
79 COMPILER_ASSERT(sizeof(struct measurement_desc_data) == 0x100);
80
81 COMPILER_ASSERT(offsetof(struct measurement_desc_data, desc_type) == 0x0);
82 COMPILER_ASSERT(offsetof(struct measurement_desc_data, len) == 0x8);
83 COMPILER_ASSERT(offsetof(struct measurement_desc_data, rim) == 0x10);
84 COMPILER_ASSERT(offsetof(struct measurement_desc_data, ipa) == 0x50);
85 COMPILER_ASSERT(offsetof(struct measurement_desc_data, flags) == 0x58);
86 COMPILER_ASSERT(offsetof(struct measurement_desc_data, content) == 0x60);
87
88 /* RmmMeasurementDescriptorRec type as per RMM spec */
89 struct measurement_desc_rec {
90 /* Measurement descriptor type, value 0x1 */
91 SET_MEMBER(unsigned char desc_type, 0x0, 0x8);
92 /* Length of this data structure in bytes */
93 SET_MEMBER(unsigned long len, 0x8, 0x10);
94 /* Current RIM value */
95 SET_MEMBER(unsigned char rim[MAX_MEASUREMENT_SIZE], 0x10, 0x50);
96 /* Hash of 4KB page which contains REC parameters data structure */
97 SET_MEMBER(unsigned char content[MAX_MEASUREMENT_SIZE], 0x50, 0x100);
98 };
99 COMPILER_ASSERT(sizeof(struct measurement_desc_rec) == 0x100);
100
101 COMPILER_ASSERT(offsetof(struct measurement_desc_rec, desc_type) == 0x0);
102 COMPILER_ASSERT(offsetof(struct measurement_desc_rec, len) == 0x8);
103 COMPILER_ASSERT(offsetof(struct measurement_desc_rec, rim) == 0x10);
104 COMPILER_ASSERT(offsetof(struct measurement_desc_rec, content) == 0x50);
105
106 /* RmmMeasurementDescriptorRipas type as per RMM spec */
107 struct measurement_desc_ripas {
108 /* Measurement descriptor type, value 0x2 */
109 SET_MEMBER(unsigned char desc_type, 0x0, 0x8);
110 /* Length of this data structure in bytes */
111 SET_MEMBER(unsigned long len, 0x8, 0x10);
112 /* Current RIM value */
113 SET_MEMBER(unsigned char rim[MAX_MEASUREMENT_SIZE], 0x10, 0x50);
114 /* IPA at which the RIPAS change occurred */
115 SET_MEMBER(unsigned long ipa, 0x50, 0x58);
116 /* RTT level at which the RIPAS change occurred */
117 SET_MEMBER(unsigned char level, 0x58, 0x100);
118 };
119 COMPILER_ASSERT(sizeof(struct measurement_desc_ripas) == 0x100);
120
121 COMPILER_ASSERT(offsetof(struct measurement_desc_ripas, desc_type) == 0x0);
122 COMPILER_ASSERT(offsetof(struct measurement_desc_ripas, len) == 0x8);
123 COMPILER_ASSERT(offsetof(struct measurement_desc_ripas, rim) == 0x10);
124 COMPILER_ASSERT(offsetof(struct measurement_desc_ripas, ipa) == 0x50);
125 COMPILER_ASSERT(offsetof(struct measurement_desc_ripas, level) == 0x58);
126
127 /*
128 * Calculate the hash of data with algorithm hash_algo to the buffer `out`.
129 */
130 void measurement_hash_compute(enum hash_algo hash_algo,
131 void *data,
132 size_t size, unsigned char *out);
133
134 /* Extend a measurement with algorithm hash_algo. */
135 void measurement_extend(enum hash_algo hash_algo,
136 void *current_measurement,
137 void *extend_measurement,
138 size_t extend_measurement_size,
139 unsigned char *out);
140
141 /*
142 * Return the hash size in bytes for the selected measurement algorithm.
143 *
144 * Arguments:
145 * - algorithm: Algorithm to check.
146 */
measurement_get_size(const enum hash_algo algorithm)147 static inline size_t measurement_get_size(
148 const enum hash_algo algorithm)
149 {
150 size_t ret = 0;
151
152 switch (algorithm) {
153 case HASH_ALGO_SHA256:
154 ret = (size_t)SHA256_SIZE;
155 break;
156 case HASH_ALGO_SHA512:
157 ret = (size_t)SHA512_SIZE;
158 break;
159 default:
160 assert(false);
161 }
162
163 return ret;
164 }
165
166 #endif /* MEASUREMENT_H */
167