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