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