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