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