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