1 /*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4 */
5
6 #include <assert.h>
7 #include <debug.h>
8 #include <fpu_helpers.h>
9 #include <mbedtls/sha256.h>
10 #include <mbedtls/sha512.h>
11 #include <measurement.h>
12 #include <stdbool.h>
13
14 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
measurement_print(unsigned char * measurement,const enum hash_algo algorithm)15 static void measurement_print(unsigned char *measurement,
16 const enum hash_algo algorithm)
17 {
18 unsigned int size = 0U;
19 assert(measurement != NULL);
20
21 VERBOSE("Measurement ");
22
23 switch (algorithm) {
24 case HASH_ALGO_SHA256:
25 VERBOSE("(SHA256): 0x");
26 size = SHA256_SIZE;
27 break;
28 case HASH_ALGO_SHA512:
29 VERBOSE("(SHA512): 0x");
30 size = SHA512_SIZE;
31 break;
32 default:
33 /* Prevent static check and MISRA warnings */
34 assert(false);
35 }
36
37 for (unsigned int i = 0U; i < size; ++i) {
38 VERBOSE("%02x", *(measurement+i));
39 }
40 VERBOSE("\n");
41 }
42 #endif /* LOG_LEVEL */
43
do_hash(enum hash_algo hash_algo,void * data,size_t size,unsigned char * out)44 static void do_hash(enum hash_algo hash_algo,
45 void *data,
46 size_t size,
47 unsigned char *out)
48 {
49 __unused int ret;
50
51 assert(size <= GRANULE_SIZE);
52 assert((data != NULL) && (out != NULL));
53
54 fpu_save_my_state();
55
56 if (hash_algo == HASH_ALGO_SHA256) {
57 /* 0 to indicate SHA256 not SHA224 */
58 FPU_ALLOW(ret = mbedtls_sha256(data, size, out, 0));
59
60 assert(ret == 0);
61 } else if (hash_algo == HASH_ALGO_SHA512) {
62 /* 0 to indicate SHA512 not SHA384 */
63 FPU_ALLOW(ret = mbedtls_sha512(data, size, out, 0));
64
65 assert(ret == 0);
66 } else {
67 assert(false);
68 }
69
70 fpu_restore_my_state();
71
72 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
73 measurement_print(out, hash_algo);
74 #endif
75 }
76
measurement_hash_compute(enum hash_algo hash_algo,void * data,size_t size,unsigned char * out)77 void measurement_hash_compute(enum hash_algo hash_algo,
78 void *data,
79 size_t size,
80 unsigned char *out)
81 {
82 do_hash(hash_algo, data, size, out);
83 }
84
measurement_extend_sha256(void * current_measurement,size_t current_measurement_size,void * extend_measurement,size_t extend_measurement_size,unsigned char * out)85 static void measurement_extend_sha256(void *current_measurement,
86 size_t current_measurement_size,
87 void *extend_measurement,
88 size_t extend_measurement_size,
89 unsigned char *out)
90 {
91 mbedtls_sha256_context sha256_ctx;
92
93 __unused int ret = 0;
94
95 mbedtls_sha256_init(&sha256_ctx);
96 /* 0 to indicate SHA256 not SHA224 */
97 ret = mbedtls_sha256_starts(&sha256_ctx, 0);
98 assert(ret == 0);
99
100 /* Update the measurement */
101 ret = mbedtls_sha256_update(
102 &sha256_ctx,
103 (unsigned char *)current_measurement,
104 current_measurement_size);
105 assert(ret == 0);
106
107 ret = mbedtls_sha256_update(&sha256_ctx,
108 (unsigned char *)extend_measurement,
109 extend_measurement_size);
110 assert(ret == 0);
111
112 ret = mbedtls_sha256_finish(&sha256_ctx, out);
113 assert(ret == 0);
114 }
115
measurement_extend_sha512(void * current_measurement,size_t current_measurement_size,void * extend_measurement,size_t extend_measurement_size,unsigned char * out)116 static void measurement_extend_sha512(void *current_measurement,
117 size_t current_measurement_size,
118 void *extend_measurement,
119 size_t extend_measurement_size,
120 unsigned char *out)
121 {
122 mbedtls_sha512_context sha512_ctx;
123 __unused int ret = 0;
124
125 mbedtls_sha512_init(&sha512_ctx);
126 /* 0 to indicate SHA256 not SHA384 */
127 ret = mbedtls_sha512_starts(&sha512_ctx, 0);
128 assert(ret == 0);
129
130 /* Update the measurement */
131 ret = mbedtls_sha512_update(
132 &sha512_ctx,
133 (unsigned char *)current_measurement,
134 current_measurement_size);
135 assert(ret == 0);
136
137 ret = mbedtls_sha512_update(
138 &sha512_ctx,
139 (unsigned char *)extend_measurement_size,
140 extend_measurement_size);
141 assert(ret == 0);
142
143 ret = mbedtls_sha512_finish(&sha512_ctx, out);
144 assert(ret == 0);
145 }
146
measurement_extend(enum hash_algo hash_algo,void * current_measurement,void * extend_measurement,size_t extend_measurement_size,unsigned char * out)147 void measurement_extend(enum hash_algo hash_algo,
148 void *current_measurement,
149 void *extend_measurement,
150 size_t extend_measurement_size,
151 unsigned char *out)
152 {
153 size_t current_measurement_size = measurement_get_size(hash_algo);
154
155 /* We limit the maximum size of the payload to be of GRANULE_SIZE */
156 assert(current_measurement != NULL);
157 assert(extend_measurement_size <= GRANULE_SIZE);
158 assert(extend_measurement != NULL);
159 assert(out != NULL);
160
161 fpu_save_my_state();
162
163 switch (hash_algo) {
164 case HASH_ALGO_SHA256:
165 FPU_ALLOW(
166 measurement_extend_sha256(current_measurement,
167 current_measurement_size,
168 extend_measurement,
169 extend_measurement_size,
170 out));
171 break;
172 case HASH_ALGO_SHA512:
173 FPU_ALLOW(
174 measurement_extend_sha512(current_measurement,
175 current_measurement_size,
176 extend_measurement,
177 extend_measurement_size,
178 out));
179 break;
180 default:
181 assert(false);
182 }
183
184 fpu_restore_my_state();
185
186 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
187 measurement_print(out, hash_algo);
188 #endif
189 }
190