Branch data Line data Source code
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)
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)
78 : 342 : psa_status_t mbedtls_psa_hash_abort(
79 : : mbedtls_psa_hash_operation_t *operation )
80 : : {
81 [ - + - - ]: 342 : 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 : 0 : case PSA_ALG_SHA_224:
105 : 0 : mbedtls_sha256_free( &operation->ctx.sha256 );
106 : 0 : break;
107 : : #endif
108 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
109 : 342 : case PSA_ALG_SHA_256:
110 : 342 : mbedtls_sha256_free( &operation->ctx.sha256 );
111 : 342 : 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 : 342 : operation->alg = 0;
127 : 342 : return( PSA_SUCCESS );
128 : : }
129 : :
130 : 342 : psa_status_t mbedtls_psa_hash_setup(
131 : : mbedtls_psa_hash_operation_t *operation,
132 : : psa_algorithm_t alg )
133 : : {
134 : 342 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
135 : :
136 : : /* A context must be freshly initialized before it can be set up. */
137 [ + - ]: 342 : if( operation->alg != 0 )
138 : : {
139 : : return( PSA_ERROR_BAD_STATE );
140 : : }
141 : :
142 [ - + - ]: 342 : 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 : 0 : case PSA_ALG_SHA_224:
164 : 0 : mbedtls_sha256_init( &operation->ctx.sha256 );
165 : 0 : ret = mbedtls_sha256_starts( &operation->ctx.sha256, 1 );
166 : 0 : break;
167 : : #endif
168 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
169 : 342 : case PSA_ALG_SHA_256:
170 : 342 : mbedtls_sha256_init( &operation->ctx.sha256 );
171 : 342 : ret = mbedtls_sha256_starts( &operation->ctx.sha256, 0 );
172 : 342 : 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 : 0 : default:
187 : 0 : return( PSA_ALG_IS_HASH( alg ) ?
188 [ # # ]: 0 : PSA_ERROR_NOT_SUPPORTED :
189 : : PSA_ERROR_INVALID_ARGUMENT );
190 : : }
191 [ + - ]: 342 : if( ret == 0 )
192 : 342 : operation->alg = alg;
193 : : else
194 : 0 : mbedtls_psa_hash_abort( operation );
195 : 342 : return( mbedtls_to_psa_error( ret ) );
196 : : }
197 : :
198 : 0 : 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 [ # # # # ]: 0 : 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 : 0 : case PSA_ALG_SHA_224:
226 : 0 : mbedtls_sha256_clone( &target_operation->ctx.sha256,
227 : : &source_operation->ctx.sha256 );
228 : 0 : break;
229 : : #endif
230 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
231 : 0 : case PSA_ALG_SHA_256:
232 : 0 : mbedtls_sha256_clone( &target_operation->ctx.sha256,
233 : : &source_operation->ctx.sha256 );
234 : 0 : 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 : 0 : default:
249 : 0 : (void) source_operation;
250 : 0 : (void) target_operation;
251 : 0 : return( PSA_ERROR_NOT_SUPPORTED );
252 : : }
253 : :
254 : 0 : target_operation->alg = source_operation->alg;
255 : 0 : return( PSA_SUCCESS );
256 : : }
257 : :
258 : 650 : 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 : 650 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
264 : :
265 [ - + - ]: 650 : 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 : 0 : case PSA_ALG_SHA_224:
287 : 0 : ret = mbedtls_sha256_update( &operation->ctx.sha256,
288 : : input, input_length );
289 : 0 : break;
290 : : #endif
291 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
292 : 650 : case PSA_ALG_SHA_256:
293 : 650 : ret = mbedtls_sha256_update( &operation->ctx.sha256,
294 : : input, input_length );
295 : 650 : 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 : 650 : return( mbedtls_to_psa_error( ret ) );
316 : : }
317 : :
318 : 342 : 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 : 342 : psa_status_t status;
325 : 342 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
326 [ + - ]: 342 : 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 : 342 : *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 [ + - ]: 342 : if( hash_size != 0 )
335 : 342 : memset( hash, '!', hash_size );
336 : :
337 [ - + ]: 342 : if( hash_size < actual_hash_length )
338 : : {
339 : 0 : status = PSA_ERROR_BUFFER_TOO_SMALL;
340 : 0 : goto exit;
341 : : }
342 : :
343 [ - + - ]: 342 : 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 : 0 : case PSA_ALG_SHA_224:
362 : 0 : ret = mbedtls_sha256_finish( &operation->ctx.sha256, hash );
363 : 0 : break;
364 : : #endif
365 : : #if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
366 : 342 : case PSA_ALG_SHA_256:
367 : 342 : ret = mbedtls_sha256_finish( &operation->ctx.sha256, hash );
368 : 342 : 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 : 342 : status = mbedtls_to_psa_error( ret );
385 : :
386 : 342 : exit:
387 [ + - ]: 342 : if( status == PSA_SUCCESS )
388 : 342 : *hash_length = actual_hash_length;
389 : : return( status );
390 : : }
391 : :
392 : 34 : 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 : 34 : mbedtls_psa_hash_operation_t operation = MBEDTLS_PSA_HASH_OPERATION_INIT;
401 : 34 : psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
402 : 34 : psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
403 : :
404 : 34 : *hash_length = hash_size;
405 : 34 : status = mbedtls_psa_hash_setup( &operation, alg );
406 [ - + ]: 34 : if( status != PSA_SUCCESS )
407 : 0 : goto exit;
408 : 34 : status = mbedtls_psa_hash_update( &operation, input, input_length );
409 [ - + ]: 34 : if( status != PSA_SUCCESS )
410 : 0 : goto exit;
411 : 34 : status = mbedtls_psa_hash_finish( &operation, hash, hash_size, hash_length );
412 [ + - ]: 34 : if( status != PSA_SUCCESS )
413 : 0 : goto exit;
414 : :
415 : 34 : exit:
416 : 34 : abort_status = mbedtls_psa_hash_abort( &operation );
417 [ - + ]: 34 : if( status == PSA_SUCCESS )
418 : : return( abort_status );
419 : : else
420 : 0 : return( status );
421 : :
422 : : }
423 : : #endif /* MBEDTLS_PSA_BUILTIN_HASH */
424 : :
425 : : #endif /* MBEDTLS_PSA_CRYPTO_C */
|