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