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