1 /*
2 * PSA hashing layer on top of Mbed TLS software crypto
3 */
4 /*
5 * Copyright The Mbed TLS Contributors
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 * not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21 #include "common.h"
22
23 #if defined(MBEDTLS_PSA_CRYPTO_C)
24
25 #include <psa/crypto.h>
26 #include "psa_crypto_core.h"
27 #include "psa_crypto_hash.h"
28
29 #include <mbedtls/error.h>
30 #include <string.h>
31
32 #if defined(MBEDTLS_PSA_BUILTIN_HASH)
mbedtls_psa_hash_abort(mbedtls_psa_hash_operation_t * operation)33 psa_status_t mbedtls_psa_hash_abort(
34 mbedtls_psa_hash_operation_t *operation)
35 {
36 switch (operation->alg) {
37 case 0:
38 /* The object has (apparently) been initialized but it is not
39 * in use. It's ok to call abort on such an object, and there's
40 * nothing to do. */
41 break;
42 #if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
43 case PSA_ALG_MD5:
44 mbedtls_md5_free(&operation->ctx.md5);
45 break;
46 #endif
47 #if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
48 case PSA_ALG_RIPEMD160:
49 mbedtls_ripemd160_free(&operation->ctx.ripemd160);
50 break;
51 #endif
52 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
53 case PSA_ALG_SHA_1:
54 mbedtls_sha1_free(&operation->ctx.sha1);
55 break;
56 #endif
57 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
58 case PSA_ALG_SHA_224:
59 mbedtls_sha256_free(&operation->ctx.sha256);
60 break;
61 #endif
62 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
63 case PSA_ALG_SHA_256:
64 mbedtls_sha256_free(&operation->ctx.sha256);
65 break;
66 #endif
67 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
68 case PSA_ALG_SHA_384:
69 mbedtls_sha512_free(&operation->ctx.sha512);
70 break;
71 #endif
72 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
73 case PSA_ALG_SHA_512:
74 mbedtls_sha512_free(&operation->ctx.sha512);
75 break;
76 #endif
77 default:
78 return PSA_ERROR_BAD_STATE;
79 }
80 operation->alg = 0;
81 return PSA_SUCCESS;
82 }
83
mbedtls_psa_hash_setup(mbedtls_psa_hash_operation_t * operation,psa_algorithm_t alg)84 psa_status_t mbedtls_psa_hash_setup(
85 mbedtls_psa_hash_operation_t *operation,
86 psa_algorithm_t alg)
87 {
88 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
89
90 /* A context must be freshly initialized before it can be set up. */
91 if (operation->alg != 0) {
92 return PSA_ERROR_BAD_STATE;
93 }
94
95 switch (alg) {
96 #if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
97 case PSA_ALG_MD5:
98 mbedtls_md5_init(&operation->ctx.md5);
99 ret = mbedtls_md5_starts(&operation->ctx.md5);
100 break;
101 #endif
102 #if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
103 case PSA_ALG_RIPEMD160:
104 mbedtls_ripemd160_init(&operation->ctx.ripemd160);
105 ret = mbedtls_ripemd160_starts(&operation->ctx.ripemd160);
106 break;
107 #endif
108 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
109 case PSA_ALG_SHA_1:
110 mbedtls_sha1_init(&operation->ctx.sha1);
111 ret = mbedtls_sha1_starts(&operation->ctx.sha1);
112 break;
113 #endif
114 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
115 case PSA_ALG_SHA_224:
116 mbedtls_sha256_init(&operation->ctx.sha256);
117 ret = mbedtls_sha256_starts(&operation->ctx.sha256, 1);
118 break;
119 #endif
120 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
121 case PSA_ALG_SHA_256:
122 mbedtls_sha256_init(&operation->ctx.sha256);
123 ret = mbedtls_sha256_starts(&operation->ctx.sha256, 0);
124 break;
125 #endif
126 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
127 case PSA_ALG_SHA_384:
128 mbedtls_sha512_init(&operation->ctx.sha512);
129 ret = mbedtls_sha512_starts(&operation->ctx.sha512, 1);
130 break;
131 #endif
132 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
133 case PSA_ALG_SHA_512:
134 mbedtls_sha512_init(&operation->ctx.sha512);
135 ret = mbedtls_sha512_starts(&operation->ctx.sha512, 0);
136 break;
137 #endif
138 default:
139 return PSA_ALG_IS_HASH(alg) ?
140 PSA_ERROR_NOT_SUPPORTED :
141 PSA_ERROR_INVALID_ARGUMENT;
142 }
143 if (ret == 0) {
144 operation->alg = alg;
145 } else {
146 mbedtls_psa_hash_abort(operation);
147 }
148 return mbedtls_to_psa_error(ret);
149 }
150
mbedtls_psa_hash_clone(const mbedtls_psa_hash_operation_t * source_operation,mbedtls_psa_hash_operation_t * target_operation)151 psa_status_t mbedtls_psa_hash_clone(
152 const mbedtls_psa_hash_operation_t *source_operation,
153 mbedtls_psa_hash_operation_t *target_operation)
154 {
155 switch (source_operation->alg) {
156 case 0:
157 return PSA_ERROR_BAD_STATE;
158 #if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
159 case PSA_ALG_MD5:
160 mbedtls_md5_clone(&target_operation->ctx.md5,
161 &source_operation->ctx.md5);
162 break;
163 #endif
164 #if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
165 case PSA_ALG_RIPEMD160:
166 mbedtls_ripemd160_clone(&target_operation->ctx.ripemd160,
167 &source_operation->ctx.ripemd160);
168 break;
169 #endif
170 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
171 case PSA_ALG_SHA_1:
172 mbedtls_sha1_clone(&target_operation->ctx.sha1,
173 &source_operation->ctx.sha1);
174 break;
175 #endif
176 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
177 case PSA_ALG_SHA_224:
178 mbedtls_sha256_clone(&target_operation->ctx.sha256,
179 &source_operation->ctx.sha256);
180 break;
181 #endif
182 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
183 case PSA_ALG_SHA_256:
184 mbedtls_sha256_clone(&target_operation->ctx.sha256,
185 &source_operation->ctx.sha256);
186 break;
187 #endif
188 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
189 case PSA_ALG_SHA_384:
190 mbedtls_sha512_clone(&target_operation->ctx.sha512,
191 &source_operation->ctx.sha512);
192 break;
193 #endif
194 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
195 case PSA_ALG_SHA_512:
196 mbedtls_sha512_clone(&target_operation->ctx.sha512,
197 &source_operation->ctx.sha512);
198 break;
199 #endif
200 default:
201 (void) source_operation;
202 (void) target_operation;
203 return PSA_ERROR_NOT_SUPPORTED;
204 }
205
206 target_operation->alg = source_operation->alg;
207 return PSA_SUCCESS;
208 }
209
mbedtls_psa_hash_update(mbedtls_psa_hash_operation_t * operation,const uint8_t * input,size_t input_length)210 psa_status_t mbedtls_psa_hash_update(
211 mbedtls_psa_hash_operation_t *operation,
212 const uint8_t *input,
213 size_t input_length)
214 {
215 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
216
217 switch (operation->alg) {
218 #if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
219 case PSA_ALG_MD5:
220 ret = mbedtls_md5_update(&operation->ctx.md5,
221 input, input_length);
222 break;
223 #endif
224 #if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
225 case PSA_ALG_RIPEMD160:
226 ret = mbedtls_ripemd160_update(&operation->ctx.ripemd160,
227 input, input_length);
228 break;
229 #endif
230 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
231 case PSA_ALG_SHA_1:
232 ret = mbedtls_sha1_update(&operation->ctx.sha1,
233 input, input_length);
234 break;
235 #endif
236 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
237 case PSA_ALG_SHA_224:
238 ret = mbedtls_sha256_update(&operation->ctx.sha256,
239 input, input_length);
240 break;
241 #endif
242 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
243 case PSA_ALG_SHA_256:
244 ret = mbedtls_sha256_update(&operation->ctx.sha256,
245 input, input_length);
246 break;
247 #endif
248 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
249 case PSA_ALG_SHA_384:
250 ret = mbedtls_sha512_update(&operation->ctx.sha512,
251 input, input_length);
252 break;
253 #endif
254 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
255 case PSA_ALG_SHA_512:
256 ret = mbedtls_sha512_update(&operation->ctx.sha512,
257 input, input_length);
258 break;
259 #endif
260 default:
261 (void) input;
262 (void) input_length;
263 return PSA_ERROR_BAD_STATE;
264 }
265
266 return mbedtls_to_psa_error(ret);
267 }
268
mbedtls_psa_hash_finish(mbedtls_psa_hash_operation_t * operation,uint8_t * hash,size_t hash_size,size_t * hash_length)269 psa_status_t mbedtls_psa_hash_finish(
270 mbedtls_psa_hash_operation_t *operation,
271 uint8_t *hash,
272 size_t hash_size,
273 size_t *hash_length)
274 {
275 psa_status_t status;
276 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
277 size_t actual_hash_length = PSA_HASH_LENGTH(operation->alg);
278
279 /* Fill the output buffer with something that isn't a valid hash
280 * (barring an attack on the hash and deliberately-crafted input),
281 * in case the caller doesn't check the return status properly. */
282 *hash_length = hash_size;
283 /* If hash_size is 0 then hash may be NULL and then the
284 * call to memset would have undefined behavior. */
285 if (hash_size != 0) {
286 memset(hash, '!', hash_size);
287 }
288
289 if (hash_size < actual_hash_length) {
290 status = PSA_ERROR_BUFFER_TOO_SMALL;
291 goto exit;
292 }
293
294 switch (operation->alg) {
295 #if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
296 case PSA_ALG_MD5:
297 ret = mbedtls_md5_finish(&operation->ctx.md5, hash);
298 break;
299 #endif
300 #if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
301 case PSA_ALG_RIPEMD160:
302 ret = mbedtls_ripemd160_finish(&operation->ctx.ripemd160, hash);
303 break;
304 #endif
305 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
306 case PSA_ALG_SHA_1:
307 ret = mbedtls_sha1_finish(&operation->ctx.sha1, hash);
308 break;
309 #endif
310 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
311 case PSA_ALG_SHA_224:
312 ret = mbedtls_sha256_finish(&operation->ctx.sha256, hash);
313 break;
314 #endif
315 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
316 case PSA_ALG_SHA_256:
317 ret = mbedtls_sha256_finish(&operation->ctx.sha256, hash);
318 break;
319 #endif
320 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
321 case PSA_ALG_SHA_384:
322 ret = mbedtls_sha512_finish(&operation->ctx.sha512, hash);
323 break;
324 #endif
325 #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
326 case PSA_ALG_SHA_512:
327 ret = mbedtls_sha512_finish(&operation->ctx.sha512, hash);
328 break;
329 #endif
330 default:
331 (void) hash;
332 return PSA_ERROR_BAD_STATE;
333 }
334 status = mbedtls_to_psa_error(ret);
335
336 exit:
337 if (status == PSA_SUCCESS) {
338 *hash_length = actual_hash_length;
339 }
340 return status;
341 }
342
mbedtls_psa_hash_compute(psa_algorithm_t alg,const uint8_t * input,size_t input_length,uint8_t * hash,size_t hash_size,size_t * hash_length)343 psa_status_t mbedtls_psa_hash_compute(
344 psa_algorithm_t alg,
345 const uint8_t *input,
346 size_t input_length,
347 uint8_t *hash,
348 size_t hash_size,
349 size_t *hash_length)
350 {
351 mbedtls_psa_hash_operation_t operation = MBEDTLS_PSA_HASH_OPERATION_INIT;
352 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
353 psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
354
355 *hash_length = hash_size;
356 status = mbedtls_psa_hash_setup(&operation, alg);
357 if (status != PSA_SUCCESS) {
358 goto exit;
359 }
360 status = mbedtls_psa_hash_update(&operation, input, input_length);
361 if (status != PSA_SUCCESS) {
362 goto exit;
363 }
364 status = mbedtls_psa_hash_finish(&operation, hash, hash_size, hash_length);
365 if (status != PSA_SUCCESS) {
366 goto exit;
367 }
368
369 exit:
370 abort_status = mbedtls_psa_hash_abort(&operation);
371 if (status == PSA_SUCCESS) {
372 return abort_status;
373 } else {
374 return status;
375 }
376
377 }
378 #endif /* MBEDTLS_PSA_BUILTIN_HASH */
379
380 #endif /* MBEDTLS_PSA_CRYPTO_C */
381