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