1 /* 2 * PSA cipher driver entry points 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_cipher.h" 14 #include "psa_crypto_core.h" 15 #include "psa_crypto_random_impl.h" 16 17 #include "mbedtls/cipher.h" 18 #include "mbedtls/error.h" 19 20 #include <string.h> 21 22 /* mbedtls_cipher_values_from_psa() below only checks if the proper build symbols 23 * are enabled, but it does not provide any compatibility check between them 24 * (i.e. if the specified key works with the specified algorithm). This helper 25 * function is meant to provide this support. 26 * mbedtls_cipher_info_from_psa() might be used for the same purpose, but it 27 * requires CIPHER_C to be enabled. 28 */ 29 static psa_status_t mbedtls_cipher_validate_values( 30 psa_algorithm_t alg, 31 psa_key_type_t key_type) 32 { 33 /* Reduce code size - hinting to the compiler about what it can assume allows the compiler to 34 eliminate bits of the logic below. */ 35 #if !defined(PSA_WANT_KEY_TYPE_AES) 36 MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_AES); 37 #endif 38 #if !defined(PSA_WANT_KEY_TYPE_ARIA) 39 MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_ARIA); 40 #endif 41 #if !defined(PSA_WANT_KEY_TYPE_CAMELLIA) 42 MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CAMELLIA); 43 #endif 44 #if !defined(PSA_WANT_KEY_TYPE_CHACHA20) 45 MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CHACHA20); 46 #endif 47 #if !defined(PSA_WANT_KEY_TYPE_DES) 48 MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_DES); 49 #endif 50 #if !defined(PSA_WANT_ALG_CCM) 51 MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0)); 52 #endif 53 #if !defined(PSA_WANT_ALG_GCM) 54 MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0)); 55 #endif 56 #if !defined(PSA_WANT_ALG_STREAM_CIPHER) 57 MBEDTLS_ASSUME(alg != PSA_ALG_STREAM_CIPHER); 58 #endif 59 #if !defined(PSA_WANT_ALG_CHACHA20_POLY1305) 60 MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0)); 61 #endif 62 #if !defined(PSA_WANT_ALG_CCM_STAR_NO_TAG) 63 MBEDTLS_ASSUME(alg != PSA_ALG_CCM_STAR_NO_TAG); 64 #endif 65 #if !defined(PSA_WANT_ALG_CTR) 66 MBEDTLS_ASSUME(alg != PSA_ALG_CTR); 67 #endif 68 #if !defined(PSA_WANT_ALG_CFB) 69 MBEDTLS_ASSUME(alg != PSA_ALG_CFB); 70 #endif 71 #if !defined(PSA_WANT_ALG_OFB) 72 MBEDTLS_ASSUME(alg != PSA_ALG_OFB); 73 #endif 74 #if !defined(PSA_WANT_ALG_ECB_NO_PADDING) 75 MBEDTLS_ASSUME(alg != PSA_ALG_ECB_NO_PADDING); 76 #endif 77 #if !defined(PSA_WANT_ALG_CBC_NO_PADDING) 78 MBEDTLS_ASSUME(alg != PSA_ALG_CBC_NO_PADDING); 79 #endif 80 #if !defined(PSA_WANT_ALG_CBC_PKCS7) 81 MBEDTLS_ASSUME(alg != PSA_ALG_CBC_PKCS7); 82 #endif 83 #if !defined(PSA_WANT_ALG_CMAC) 84 MBEDTLS_ASSUME(alg != PSA_ALG_CMAC); 85 #endif 86 87 if (alg == PSA_ALG_STREAM_CIPHER || 88 alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0)) { 89 if (key_type == PSA_KEY_TYPE_CHACHA20) { 90 return PSA_SUCCESS; 91 } 92 } 93 94 if (alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0) || 95 alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0) || 96 alg == PSA_ALG_CCM_STAR_NO_TAG) { 97 if (key_type == PSA_KEY_TYPE_AES || 98 key_type == PSA_KEY_TYPE_ARIA || 99 key_type == PSA_KEY_TYPE_CAMELLIA) { 100 return PSA_SUCCESS; 101 } 102 } 103 104 if (alg == PSA_ALG_CTR || 105 alg == PSA_ALG_CFB || 106 alg == PSA_ALG_OFB || 107 alg == PSA_ALG_XTS || 108 alg == PSA_ALG_ECB_NO_PADDING || 109 alg == PSA_ALG_CBC_NO_PADDING || 110 alg == PSA_ALG_CBC_PKCS7 || 111 alg == PSA_ALG_CMAC) { 112 if (key_type == PSA_KEY_TYPE_AES || 113 key_type == PSA_KEY_TYPE_ARIA || 114 key_type == PSA_KEY_TYPE_DES || 115 key_type == PSA_KEY_TYPE_CAMELLIA) { 116 return PSA_SUCCESS; 117 } 118 } 119 120 return PSA_ERROR_NOT_SUPPORTED; 121 } 122 123 psa_status_t mbedtls_cipher_values_from_psa( 124 psa_algorithm_t alg, 125 psa_key_type_t key_type, 126 size_t *key_bits, 127 mbedtls_cipher_mode_t *mode, 128 mbedtls_cipher_id_t *cipher_id) 129 { 130 mbedtls_cipher_id_t cipher_id_tmp; 131 /* Only DES modifies key_bits */ 132 #if !defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) 133 (void) key_bits; 134 #endif 135 136 if (PSA_ALG_IS_AEAD(alg)) { 137 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0); 138 } 139 140 if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg)) { 141 switch (alg) { 142 #if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER) 143 case PSA_ALG_STREAM_CIPHER: 144 *mode = MBEDTLS_MODE_STREAM; 145 break; 146 #endif 147 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CTR) 148 case PSA_ALG_CTR: 149 *mode = MBEDTLS_MODE_CTR; 150 break; 151 #endif 152 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CFB) 153 case PSA_ALG_CFB: 154 *mode = MBEDTLS_MODE_CFB; 155 break; 156 #endif 157 #if defined(MBEDTLS_PSA_BUILTIN_ALG_OFB) 158 case PSA_ALG_OFB: 159 *mode = MBEDTLS_MODE_OFB; 160 break; 161 #endif 162 #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING) 163 case PSA_ALG_ECB_NO_PADDING: 164 *mode = MBEDTLS_MODE_ECB; 165 break; 166 #endif 167 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) 168 case PSA_ALG_CBC_NO_PADDING: 169 *mode = MBEDTLS_MODE_CBC; 170 break; 171 #endif 172 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7) 173 case PSA_ALG_CBC_PKCS7: 174 *mode = MBEDTLS_MODE_CBC; 175 break; 176 #endif 177 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG) 178 case PSA_ALG_CCM_STAR_NO_TAG: 179 *mode = MBEDTLS_MODE_CCM_STAR_NO_TAG; 180 break; 181 #endif 182 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) 183 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0): 184 *mode = MBEDTLS_MODE_CCM; 185 break; 186 #endif 187 #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) 188 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0): 189 *mode = MBEDTLS_MODE_GCM; 190 break; 191 #endif 192 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) 193 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0): 194 *mode = MBEDTLS_MODE_CHACHAPOLY; 195 break; 196 #endif 197 default: 198 return PSA_ERROR_NOT_SUPPORTED; 199 } 200 } else if (alg == PSA_ALG_CMAC) { 201 *mode = MBEDTLS_MODE_ECB; 202 } else { 203 return PSA_ERROR_NOT_SUPPORTED; 204 } 205 206 switch (key_type) { 207 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES) 208 case PSA_KEY_TYPE_AES: 209 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES; 210 break; 211 #endif 212 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA) 213 case PSA_KEY_TYPE_ARIA: 214 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA; 215 break; 216 #endif 217 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) 218 case PSA_KEY_TYPE_DES: 219 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES, 220 * and 192 for three-key Triple-DES. */ 221 if (*key_bits == 64) { 222 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES; 223 } else { 224 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES; 225 } 226 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm, 227 * but two-key Triple-DES is functionally three-key Triple-DES 228 * with K1=K3, so that's how we present it to mbedtls. */ 229 if (*key_bits == 128) { 230 *key_bits = 192; 231 } 232 break; 233 #endif 234 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA) 235 case PSA_KEY_TYPE_CAMELLIA: 236 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA; 237 break; 238 #endif 239 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20) 240 case PSA_KEY_TYPE_CHACHA20: 241 cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20; 242 break; 243 #endif 244 default: 245 return PSA_ERROR_NOT_SUPPORTED; 246 } 247 if (cipher_id != NULL) { 248 *cipher_id = cipher_id_tmp; 249 } 250 251 return mbedtls_cipher_validate_values(alg, key_type); 252 } 253 254 #if defined(MBEDTLS_CIPHER_C) 255 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa( 256 psa_algorithm_t alg, 257 psa_key_type_t key_type, 258 size_t key_bits, 259 mbedtls_cipher_id_t *cipher_id) 260 { 261 mbedtls_cipher_mode_t mode; 262 psa_status_t status; 263 mbedtls_cipher_id_t cipher_id_tmp = MBEDTLS_CIPHER_ID_NONE; 264 265 status = mbedtls_cipher_values_from_psa(alg, key_type, &key_bits, &mode, &cipher_id_tmp); 266 if (status != PSA_SUCCESS) { 267 return NULL; 268 } 269 if (cipher_id != NULL) { 270 *cipher_id = cipher_id_tmp; 271 } 272 273 return mbedtls_cipher_info_from_values(cipher_id_tmp, (int) key_bits, mode); 274 } 275 #endif /* MBEDTLS_CIPHER_C */ 276 277 #if defined(MBEDTLS_PSA_BUILTIN_CIPHER) 278 279 static psa_status_t psa_cipher_setup( 280 mbedtls_psa_cipher_operation_t *operation, 281 const psa_key_attributes_t *attributes, 282 const uint8_t *key_buffer, size_t key_buffer_size, 283 psa_algorithm_t alg, 284 mbedtls_operation_t cipher_operation) 285 { 286 int ret = 0; 287 size_t key_bits; 288 const mbedtls_cipher_info_t *cipher_info = NULL; 289 psa_key_type_t key_type = attributes->type; 290 291 (void) key_buffer_size; 292 293 mbedtls_cipher_init(&operation->ctx.cipher); 294 295 operation->alg = alg; 296 key_bits = attributes->bits; 297 cipher_info = mbedtls_cipher_info_from_psa(alg, key_type, 298 key_bits, NULL); 299 if (cipher_info == NULL) { 300 return PSA_ERROR_NOT_SUPPORTED; 301 } 302 303 ret = mbedtls_cipher_setup(&operation->ctx.cipher, cipher_info); 304 if (ret != 0) { 305 goto exit; 306 } 307 308 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) 309 if (key_type == PSA_KEY_TYPE_DES && key_bits == 128) { 310 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */ 311 uint8_t keys[24]; 312 memcpy(keys, key_buffer, 16); 313 memcpy(keys + 16, key_buffer, 8); 314 ret = mbedtls_cipher_setkey(&operation->ctx.cipher, 315 keys, 316 192, cipher_operation); 317 } else 318 #endif 319 { 320 ret = mbedtls_cipher_setkey(&operation->ctx.cipher, key_buffer, 321 (int) key_bits, cipher_operation); 322 } 323 if (ret != 0) { 324 goto exit; 325 } 326 327 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \ 328 defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7) 329 switch (alg) { 330 case PSA_ALG_CBC_NO_PADDING: 331 ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher, 332 MBEDTLS_PADDING_NONE); 333 break; 334 case PSA_ALG_CBC_PKCS7: 335 ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher, 336 MBEDTLS_PADDING_PKCS7); 337 break; 338 default: 339 /* The algorithm doesn't involve padding. */ 340 ret = 0; 341 break; 342 } 343 if (ret != 0) { 344 goto exit; 345 } 346 #endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING || 347 MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */ 348 349 operation->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 : 350 PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type)); 351 operation->iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg); 352 353 exit: 354 return mbedtls_to_psa_error(ret); 355 } 356 357 psa_status_t mbedtls_psa_cipher_encrypt_setup( 358 mbedtls_psa_cipher_operation_t *operation, 359 const psa_key_attributes_t *attributes, 360 const uint8_t *key_buffer, size_t key_buffer_size, 361 psa_algorithm_t alg) 362 { 363 return psa_cipher_setup(operation, attributes, 364 key_buffer, key_buffer_size, 365 alg, MBEDTLS_ENCRYPT); 366 } 367 368 psa_status_t mbedtls_psa_cipher_decrypt_setup( 369 mbedtls_psa_cipher_operation_t *operation, 370 const psa_key_attributes_t *attributes, 371 const uint8_t *key_buffer, size_t key_buffer_size, 372 psa_algorithm_t alg) 373 { 374 return psa_cipher_setup(operation, attributes, 375 key_buffer, key_buffer_size, 376 alg, MBEDTLS_DECRYPT); 377 } 378 379 psa_status_t mbedtls_psa_cipher_set_iv( 380 mbedtls_psa_cipher_operation_t *operation, 381 const uint8_t *iv, size_t iv_length) 382 { 383 if (iv_length != operation->iv_length) { 384 return PSA_ERROR_INVALID_ARGUMENT; 385 } 386 387 return mbedtls_to_psa_error( 388 mbedtls_cipher_set_iv(&operation->ctx.cipher, 389 iv, iv_length)); 390 } 391 392 #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING) 393 /** Process input for which the algorithm is set to ECB mode. 394 * 395 * This requires manual processing, since the PSA API is defined as being 396 * able to process arbitrary-length calls to psa_cipher_update() with ECB mode, 397 * but the underlying mbedtls_cipher_update only takes full blocks. 398 * 399 * \param ctx The mbedtls cipher context to use. It must have been 400 * set up for ECB. 401 * \param[in] input The input plaintext or ciphertext to process. 402 * \param input_length The number of bytes to process from \p input. 403 * This does not need to be aligned to a block boundary. 404 * If there is a partial block at the end of the input, 405 * it is stored in \p ctx for future processing. 406 * \param output The buffer where the output is written. It must be 407 * at least `BS * floor((p + input_length) / BS)` bytes 408 * long, where `p` is the number of bytes in the 409 * unprocessed partial block in \p ctx (with 410 * `0 <= p <= BS - 1`) and `BS` is the block size. 411 * \param output_length On success, the number of bytes written to \p output. 412 * \c 0 on error. 413 * 414 * \return #PSA_SUCCESS or an error from a hardware accelerator 415 */ 416 static psa_status_t psa_cipher_update_ecb( 417 mbedtls_cipher_context_t *ctx, 418 const uint8_t *input, 419 size_t input_length, 420 uint8_t *output, 421 size_t *output_length) 422 { 423 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 424 size_t block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info); 425 size_t internal_output_length = 0; 426 *output_length = 0; 427 428 if (input_length == 0) { 429 status = PSA_SUCCESS; 430 goto exit; 431 } 432 433 if (ctx->unprocessed_len > 0) { 434 /* Fill up to block size, and run the block if there's a full one. */ 435 size_t bytes_to_copy = block_size - ctx->unprocessed_len; 436 437 if (input_length < bytes_to_copy) { 438 bytes_to_copy = input_length; 439 } 440 441 memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), 442 input, bytes_to_copy); 443 input_length -= bytes_to_copy; 444 input += bytes_to_copy; 445 ctx->unprocessed_len += bytes_to_copy; 446 447 if (ctx->unprocessed_len == block_size) { 448 status = mbedtls_to_psa_error( 449 mbedtls_cipher_update(ctx, 450 ctx->unprocessed_data, 451 block_size, 452 output, &internal_output_length)); 453 454 if (status != PSA_SUCCESS) { 455 goto exit; 456 } 457 458 output += internal_output_length; 459 *output_length += internal_output_length; 460 ctx->unprocessed_len = 0; 461 } 462 } 463 464 while (input_length >= block_size) { 465 /* Run all full blocks we have, one by one */ 466 status = mbedtls_to_psa_error( 467 mbedtls_cipher_update(ctx, input, 468 block_size, 469 output, &internal_output_length)); 470 471 if (status != PSA_SUCCESS) { 472 goto exit; 473 } 474 475 input_length -= block_size; 476 input += block_size; 477 478 output += internal_output_length; 479 *output_length += internal_output_length; 480 } 481 482 if (input_length > 0) { 483 /* Save unprocessed bytes for later processing */ 484 memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), 485 input, input_length); 486 ctx->unprocessed_len += input_length; 487 } 488 489 status = PSA_SUCCESS; 490 491 exit: 492 return status; 493 } 494 #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */ 495 496 psa_status_t mbedtls_psa_cipher_update( 497 mbedtls_psa_cipher_operation_t *operation, 498 const uint8_t *input, size_t input_length, 499 uint8_t *output, size_t output_size, size_t *output_length) 500 { 501 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 502 size_t expected_output_size; 503 504 if (!PSA_ALG_IS_STREAM_CIPHER(operation->alg)) { 505 /* Take the unprocessed partial block left over from previous 506 * update calls, if any, plus the input to this call. Remove 507 * the last partial block, if any. You get the data that will be 508 * output in this call. */ 509 expected_output_size = 510 (operation->ctx.cipher.unprocessed_len + input_length) 511 / operation->block_length * operation->block_length; 512 } else { 513 expected_output_size = input_length; 514 } 515 516 if (output_size < expected_output_size) { 517 return PSA_ERROR_BUFFER_TOO_SMALL; 518 } 519 520 #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING) 521 if (operation->alg == PSA_ALG_ECB_NO_PADDING) { 522 /* mbedtls_cipher_update has an API inconsistency: it will only 523 * process a single block at a time in ECB mode. Abstract away that 524 * inconsistency here to match the PSA API behaviour. */ 525 status = psa_cipher_update_ecb(&operation->ctx.cipher, 526 input, 527 input_length, 528 output, 529 output_length); 530 } else 531 #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */ 532 if (input_length == 0) { 533 /* There is no input, nothing to be done */ 534 *output_length = 0; 535 status = PSA_SUCCESS; 536 } else { 537 status = mbedtls_to_psa_error( 538 mbedtls_cipher_update(&operation->ctx.cipher, input, 539 input_length, output, output_length)); 540 541 if (*output_length > output_size) { 542 return PSA_ERROR_CORRUPTION_DETECTED; 543 } 544 } 545 546 return status; 547 } 548 549 psa_status_t mbedtls_psa_cipher_finish( 550 mbedtls_psa_cipher_operation_t *operation, 551 uint8_t *output, size_t output_size, size_t *output_length) 552 { 553 psa_status_t status = PSA_ERROR_GENERIC_ERROR; 554 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH]; 555 556 if (operation->ctx.cipher.unprocessed_len != 0) { 557 if (operation->alg == PSA_ALG_ECB_NO_PADDING || 558 operation->alg == PSA_ALG_CBC_NO_PADDING) { 559 status = PSA_ERROR_INVALID_ARGUMENT; 560 goto exit; 561 } 562 } 563 564 status = mbedtls_to_psa_error( 565 mbedtls_cipher_finish(&operation->ctx.cipher, 566 temp_output_buffer, 567 output_length)); 568 if (status != PSA_SUCCESS) { 569 goto exit; 570 } 571 572 if (*output_length == 0) { 573 ; /* Nothing to copy. Note that output may be NULL in this case. */ 574 } else if (output_size >= *output_length) { 575 memcpy(output, temp_output_buffer, *output_length); 576 } else { 577 status = PSA_ERROR_BUFFER_TOO_SMALL; 578 } 579 580 exit: 581 mbedtls_platform_zeroize(temp_output_buffer, 582 sizeof(temp_output_buffer)); 583 584 return status; 585 } 586 587 psa_status_t mbedtls_psa_cipher_abort( 588 mbedtls_psa_cipher_operation_t *operation) 589 { 590 /* Sanity check (shouldn't happen: operation->alg should 591 * always have been initialized to a valid value). */ 592 if (!PSA_ALG_IS_CIPHER(operation->alg)) { 593 return PSA_ERROR_BAD_STATE; 594 } 595 596 mbedtls_cipher_free(&operation->ctx.cipher); 597 598 return PSA_SUCCESS; 599 } 600 601 psa_status_t mbedtls_psa_cipher_encrypt( 602 const psa_key_attributes_t *attributes, 603 const uint8_t *key_buffer, 604 size_t key_buffer_size, 605 psa_algorithm_t alg, 606 const uint8_t *iv, 607 size_t iv_length, 608 const uint8_t *input, 609 size_t input_length, 610 uint8_t *output, 611 size_t output_size, 612 size_t *output_length) 613 { 614 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 615 mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT; 616 size_t update_output_length, finish_output_length; 617 618 status = mbedtls_psa_cipher_encrypt_setup(&operation, attributes, 619 key_buffer, key_buffer_size, 620 alg); 621 if (status != PSA_SUCCESS) { 622 goto exit; 623 } 624 625 if (iv_length > 0) { 626 status = mbedtls_psa_cipher_set_iv(&operation, iv, iv_length); 627 if (status != PSA_SUCCESS) { 628 goto exit; 629 } 630 } 631 632 status = mbedtls_psa_cipher_update(&operation, input, input_length, 633 output, output_size, 634 &update_output_length); 635 if (status != PSA_SUCCESS) { 636 goto exit; 637 } 638 639 status = mbedtls_psa_cipher_finish( 640 &operation, 641 mbedtls_buffer_offset(output, update_output_length), 642 output_size - update_output_length, &finish_output_length); 643 if (status != PSA_SUCCESS) { 644 goto exit; 645 } 646 647 *output_length = update_output_length + finish_output_length; 648 649 exit: 650 if (status == PSA_SUCCESS) { 651 status = mbedtls_psa_cipher_abort(&operation); 652 } else { 653 mbedtls_psa_cipher_abort(&operation); 654 } 655 656 return status; 657 } 658 659 psa_status_t mbedtls_psa_cipher_decrypt( 660 const psa_key_attributes_t *attributes, 661 const uint8_t *key_buffer, 662 size_t key_buffer_size, 663 psa_algorithm_t alg, 664 const uint8_t *input, 665 size_t input_length, 666 uint8_t *output, 667 size_t output_size, 668 size_t *output_length) 669 { 670 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 671 mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT; 672 size_t olength, accumulated_length; 673 674 status = mbedtls_psa_cipher_decrypt_setup(&operation, attributes, 675 key_buffer, key_buffer_size, 676 alg); 677 if (status != PSA_SUCCESS) { 678 goto exit; 679 } 680 681 if (operation.iv_length > 0) { 682 status = mbedtls_psa_cipher_set_iv(&operation, 683 input, operation.iv_length); 684 if (status != PSA_SUCCESS) { 685 goto exit; 686 } 687 } 688 689 status = mbedtls_psa_cipher_update( 690 &operation, 691 mbedtls_buffer_offset_const(input, operation.iv_length), 692 input_length - operation.iv_length, 693 output, output_size, &olength); 694 if (status != PSA_SUCCESS) { 695 goto exit; 696 } 697 698 accumulated_length = olength; 699 700 status = mbedtls_psa_cipher_finish( 701 &operation, 702 mbedtls_buffer_offset(output, accumulated_length), 703 output_size - accumulated_length, &olength); 704 if (status != PSA_SUCCESS) { 705 goto exit; 706 } 707 708 *output_length = accumulated_length + olength; 709 710 exit: 711 if (status == PSA_SUCCESS) { 712 status = mbedtls_psa_cipher_abort(&operation); 713 } else { 714 mbedtls_psa_cipher_abort(&operation); 715 } 716 717 return status; 718 } 719 #endif /* MBEDTLS_PSA_BUILTIN_CIPHER */ 720 721 #endif /* MBEDTLS_PSA_CRYPTO_C */ 722