Welcome to mirror list, hosted at ThFree Co, Russian Federation.

psa_crypto_core.h « library - github.com/Mbed-TLS/mbedtls.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 1edd63e256b24e37e554a73552b1f06792bf0eec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
/*
 *  PSA crypto core internal interfaces
 */
/*
 *  Copyright The Mbed TLS Contributors
 *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
 */

#ifndef PSA_CRYPTO_CORE_H
#define PSA_CRYPTO_CORE_H

/*
 * Include the build-time configuration information header. Here, we do not
 * include `"mbedtls/build_info.h"` directly but `"psa/build_info.h"`, which
 * is basically just an alias to it. This is to ease the maintenance of the
 * TF-PSA-Crypto repository which has a different build system and
 * configuration.
 */
#include "psa/build_info.h"

#include "psa/crypto.h"
#include "psa/crypto_se_driver.h"

/**
 * Tell if PSA is ready for this hash.
 *
 * \note            For now, only checks the state of the driver subsystem,
 *                  not the algorithm. Might do more in the future.
 *
 * \param hash_alg  The hash algorithm (ignored for now).
 *
 * \return 1 if the driver subsytem is ready, 0 otherwise.
 */
int psa_can_do_hash(psa_algorithm_t hash_alg);

/**
 * Tell if PSA is ready for this cipher.
 *
 * \note            For now, only checks the state of the driver subsystem,
 *                  not the algorithm. Might do more in the future.
 *
 * \param cipher_alg  The cipher algorithm (ignored for now).
 *
 * \return 1 if the driver subsytem is ready, 0 otherwise.
 */
int psa_can_do_cipher(psa_key_type_t key_type, psa_algorithm_t cipher_alg);

typedef enum {
    PSA_SLOT_EMPTY = 0,
    PSA_SLOT_FILLING,
    PSA_SLOT_FULL,
    PSA_SLOT_PENDING_DELETION,
} psa_key_slot_state_t;

/** The data structure representing a key slot, containing key material
 * and metadata for one key.
 */
typedef struct {
    psa_core_key_attributes_t attr;

    /*
     * The current state of the key slot, as described in
     * docs/architecture/psa-thread-safety/psa-thread-safety.md.
     *
     * Library functions can modify the state of a key slot by calling
     * psa_key_slot_state_transition.
     *
     * The state variable is used to help determine whether library functions
     * which operate on the slot succeed. For example, psa_finish_key_creation,
     * which transfers the state of a slot from PSA_SLOT_FILLING to
     * PSA_SLOT_FULL, must fail with error code PSA_ERROR_CORRUPTION_DETECTED
     * if the state of the slot is not PSA_SLOT_FILLING.
     *
     * Library functions which traverse the array of key slots only consider
     * slots that are in a suitable state for the function.
     * For example, psa_get_and_lock_key_slot_in_memory, which finds a slot
     * containing a given key ID, will only check slots whose state variable is
     * PSA_SLOT_FULL. */
    psa_key_slot_state_t state;

    /*
     * Number of functions registered as reading the material in the key slot.
     *
     * Library functions must not write directly to registered_readers
     *
     * A function must call psa_register_read(slot) before reading the current
     * contents of the slot for an operation.
     * They then must call psa_unregister_read(slot) once they have finished
     * reading the current contents of the slot.
     * A function must call psa_key_slot_has_readers(slot) to check if
     * the slot is in use for reading.
     *
     * This counter is used to prevent resetting the key slot while the library
     * may access it. For example, such control is needed in the following
     * scenarios:
     * . In case of key slot starvation, all key slots contain the description
     *   of a key, and the library asks for the description of a persistent
     *   key not present in the key slots, the key slots currently accessed by
     *   the library cannot be reclaimed to free a key slot to load the
     *   persistent key.
     * . In case of a multi-threaded application where one thread asks to close
     *   or purge or destroy a key while it is in use by the library through
     *   another thread. */
    size_t registered_readers;

    /* Dynamically allocated key data buffer.
     * Format as specified in psa_export_key(). */
    struct key_data {
        uint8_t *data;
        size_t bytes;
    } key;
} psa_key_slot_t;

/* A mask of key attribute flags used only internally.
 * Currently there aren't any. */
#define PSA_KA_MASK_INTERNAL_ONLY (     \
        0)

/** Test whether a key slot has any registered readers.
 *
 * \param[in] slot      The key slot to test.
 *
 * \return 1 if the slot has any registered readers, 0 otherwise.
 */
static inline int psa_key_slot_has_readers(const psa_key_slot_t *slot)
{
    return slot->registered_readers > 0;
}

/** Retrieve flags from psa_key_slot_t::attr::core::flags.
 *
 * \param[in] slot      The key slot to query.
 * \param mask          The mask of bits to extract.
 *
 * \return The key attribute flags in the given slot,
 *         bitwise-anded with \p mask.
 */
static inline uint16_t psa_key_slot_get_flags(const psa_key_slot_t *slot,
                                              uint16_t mask)
{
    return slot->attr.flags & mask;
}

/** Set flags in psa_key_slot_t::attr::core::flags.
 *
 * \param[in,out] slot  The key slot to modify.
 * \param mask          The mask of bits to modify.
 * \param value         The new value of the selected bits.
 */
static inline void psa_key_slot_set_flags(psa_key_slot_t *slot,
                                          uint16_t mask,
                                          uint16_t value)
{
    slot->attr.flags = ((~mask & slot->attr.flags) |
                        (mask & value));
}

/** Turn on flags in psa_key_slot_t::attr::core::flags.
 *
 * \param[in,out] slot  The key slot to modify.
 * \param mask          The mask of bits to set.
 */
static inline void psa_key_slot_set_bits_in_flags(psa_key_slot_t *slot,
                                                  uint16_t mask)
{
    slot->attr.flags |= mask;
}

/** Turn off flags in psa_key_slot_t::attr::core::flags.
 *
 * \param[in,out] slot  The key slot to modify.
 * \param mask          The mask of bits to clear.
 */
static inline void psa_key_slot_clear_bits(psa_key_slot_t *slot,
                                           uint16_t mask)
{
    slot->attr.flags &= ~mask;
}

#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
/** Get the SE slot number of a key from the key slot storing its description.
 *
 * \param[in]  slot  The key slot to query. This must be a key slot storing
 *                   the description of a key of a dynamically registered
 *                   secure element, otherwise the behaviour is undefined.
 */
static inline psa_key_slot_number_t psa_key_slot_get_slot_number(
    const psa_key_slot_t *slot)
{
    return *((psa_key_slot_number_t *) (slot->key.data));
}
#endif

/** Completely wipe a slot in memory, including its policy.
 *
 * Persistent storage is not affected.
 * Sets the slot's state to PSA_SLOT_EMPTY.
 *
 * \param[in,out] slot  The key slot to wipe.
 *
 * \retval #PSA_SUCCESS
 *         The slot has been successfully wiped.
 * \retval #PSA_ERROR_CORRUPTION_DETECTED
 *         The slot's state was PSA_SLOT_FULL or PSA_SLOT_PENDING_DELETION, and
 *         the amount of registered readers was not equal to 1. Or,
 *         the slot's state was PSA_SLOT_EMPTY. Or,
 *         the slot's state was PSA_SLOT_FILLING, and the amount
 *         of registered readers was not equal to 0.
 */
psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot);

/** Try to allocate a buffer to an empty key slot.
 *
 * \param[in,out] slot          Key slot to attach buffer to.
 * \param[in] buffer_length     Requested size of the buffer.
 *
 * \retval #PSA_SUCCESS
 *         The buffer has been successfully allocated.
 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
 *         Not enough memory was available for allocation.
 * \retval #PSA_ERROR_ALREADY_EXISTS
 *         Trying to allocate a buffer to a non-empty key slot.
 */
psa_status_t psa_allocate_buffer_to_slot(psa_key_slot_t *slot,
                                         size_t buffer_length);

/** Wipe key data from a slot. Preserves metadata such as the policy. */
psa_status_t psa_remove_key_data_from_memory(psa_key_slot_t *slot);

/** Copy key data (in export format) into an empty key slot.
 *
 * This function assumes that the slot does not contain
 * any key material yet. On failure, the slot content is unchanged.
 *
 * \param[in,out] slot          Key slot to copy the key into.
 * \param[in] data              Buffer containing the key material.
 * \param data_length           Size of the key buffer.
 *
 * \retval #PSA_SUCCESS
 *         The key has been copied successfully.
 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
 *         Not enough memory was available for allocation of the
 *         copy buffer.
 * \retval #PSA_ERROR_ALREADY_EXISTS
 *         There was other key material already present in the slot.
 */
psa_status_t psa_copy_key_material_into_slot(psa_key_slot_t *slot,
                                             const uint8_t *data,
                                             size_t data_length);

/** Convert an Mbed TLS error code to a PSA error code
 *
 * \note This function is provided solely for the convenience of
 *       Mbed TLS and may be removed at any time without notice.
 *
 * \param ret           An Mbed TLS-thrown error code
 *
 * \return              The corresponding PSA error code
 */
psa_status_t mbedtls_to_psa_error(int ret);

/** Import a key in binary format.
 *
 * \note The signature of this function is that of a PSA driver
 *       import_key entry point. This function behaves as an import_key
 *       entry point as defined in the PSA driver interface specification for
 *       transparent drivers.
 *
 * \param[in]  attributes       The attributes for the key to import.
 * \param[in]  data             The buffer containing the key data in import
 *                              format.
 * \param[in]  data_length      Size of the \p data buffer in bytes.
 * \param[out] key_buffer       The buffer to contain the key data in output
 *                              format upon successful return.
 * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes. This
 *                              size is greater or equal to \p data_length.
 * \param[out] key_buffer_length  The length of the data written in \p
 *                                key_buffer in bytes.
 * \param[out] bits             The key size in number of bits.
 *
 * \retval #PSA_SUCCESS  The key was imported successfully.
 * \retval #PSA_ERROR_INVALID_ARGUMENT
 *         The key data is not correctly formatted.
 * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
 * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
 */
psa_status_t psa_import_key_into_slot(
    const psa_key_attributes_t *attributes,
    const uint8_t *data, size_t data_length,
    uint8_t *key_buffer, size_t key_buffer_size,
    size_t *key_buffer_length, size_t *bits);

/** Export a key in binary format
 *
 * \note The signature of this function is that of a PSA driver export_key
 *       entry point. This function behaves as an export_key entry point as
 *       defined in the PSA driver interface specification.
 *
 * \param[in]  attributes       The attributes for the key to export.
 * \param[in]  key_buffer       Material or context of the key to export.
 * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes.
 * \param[out] data             Buffer where the key data is to be written.
 * \param[in]  data_size        Size of the \p data buffer in bytes.
 * \param[out] data_length      On success, the number of bytes written in
 *                              \p data
 *
 * \retval #PSA_SUCCESS  The key was exported successfully.
 * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
 * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
 * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
 * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
 * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
 */
psa_status_t psa_export_key_internal(
    const psa_key_attributes_t *attributes,
    const uint8_t *key_buffer, size_t key_buffer_size,
    uint8_t *data, size_t data_size, size_t *data_length);

/** Export a public key or the public part of a key pair in binary format.
 *
 * \note The signature of this function is that of a PSA driver
 *       export_public_key entry point. This function behaves as an
 *       export_public_key entry point as defined in the PSA driver interface
 *       specification.
 *
 * \param[in]  attributes       The attributes for the key to export.
 * \param[in]  key_buffer       Material or context of the key to export.
 * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes.
 * \param[out] data             Buffer where the key data is to be written.
 * \param[in]  data_size        Size of the \p data buffer in bytes.
 * \param[out] data_length      On success, the number of bytes written in
 *                              \p data
 *
 * \retval #PSA_SUCCESS  The public key was exported successfully.
 * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
 * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
 * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
 * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
 * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
 */
psa_status_t psa_export_public_key_internal(
    const psa_key_attributes_t *attributes,
    const uint8_t *key_buffer, size_t key_buffer_size,
    uint8_t *data, size_t data_size, size_t *data_length);

/**
 * \brief Generate a key.
 *
 * \note The signature of the function is that of a PSA driver generate_key
 *       entry point.
 *
 * \param[in]  attributes         The attributes for the key to generate.
 * \param[out] key_buffer         Buffer where the key data is to be written.
 * \param[in]  key_buffer_size    Size of \p key_buffer in bytes.
 * \param[out] key_buffer_length  On success, the number of bytes written in
 *                                \p key_buffer.
 *
 * \retval #PSA_SUCCESS
 *         The key was generated successfully.
 * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
 * \retval #PSA_ERROR_NOT_SUPPORTED
 *         Key size in bits or type not supported.
 * \retval #PSA_ERROR_BUFFER_TOO_SMALL
 *         The size of \p key_buffer is too small.
 */
psa_status_t psa_generate_key_internal(const psa_key_attributes_t *attributes,
                                       uint8_t *key_buffer,
                                       size_t key_buffer_size,
                                       size_t *key_buffer_length);

/** Sign a message with a private key. For hash-and-sign algorithms,
 *  this includes the hashing step.
 *
 * \note The signature of this function is that of a PSA driver
 *       sign_message entry point. This function behaves as a sign_message
 *       entry point as defined in the PSA driver interface specification for
 *       transparent drivers.
 *
 * \note This function will call the driver for psa_sign_hash
 *       and go through driver dispatch again.
 *
 * \param[in]  attributes       The attributes of the key to use for the
 *                              operation.
 * \param[in]  key_buffer       The buffer containing the key context.
 * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes.
 * \param[in]  alg              A signature algorithm that is compatible with
 *                              the type of the key.
 * \param[in]  input            The input message to sign.
 * \param[in]  input_length     Size of the \p input buffer in bytes.
 * \param[out] signature        Buffer where the signature is to be written.
 * \param[in]  signature_size   Size of the \p signature buffer in bytes.
 * \param[out] signature_length On success, the number of bytes
 *                              that make up the returned signature value.
 *
 * \retval #PSA_SUCCESS \emptydescription
 * \retval #PSA_ERROR_BUFFER_TOO_SMALL
 *         The size of the \p signature buffer is too small. You can
 *         determine a sufficient buffer size by calling
 *         #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
 *         where \c key_type and \c key_bits are the type and bit-size
 *         respectively of the key.
 * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
 * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
 * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
 * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
 */
psa_status_t psa_sign_message_builtin(
    const psa_key_attributes_t *attributes,
    const uint8_t *key_buffer, size_t key_buffer_size,
    psa_algorithm_t alg, const uint8_t *input, size_t input_length,
    uint8_t *signature, size_t signature_size, size_t *signature_length);

/** Verify the signature of a message with a public key, using
 *  a hash-and-sign verification algorithm.
 *
 * \note The signature of this function is that of a PSA driver
 *       verify_message entry point. This function behaves as a verify_message
 *       entry point as defined in the PSA driver interface specification for
 *       transparent drivers.
 *
 * \note This function will call the driver for psa_verify_hash
 *       and go through driver dispatch again.
 *
 * \param[in]  attributes       The attributes of the key to use for the
 *                              operation.
 * \param[in]  key_buffer       The buffer containing the key context.
 * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes.
 * \param[in]  alg              A signature algorithm that is compatible with
 *                              the type of the key.
 * \param[in]  input            The message whose signature is to be verified.
 * \param[in]  input_length     Size of the \p input buffer in bytes.
 * \param[in]  signature        Buffer containing the signature to verify.
 * \param[in]  signature_length Size of the \p signature buffer in bytes.
 *
 * \retval #PSA_SUCCESS
 *         The signature is valid.
 * \retval #PSA_ERROR_INVALID_SIGNATURE
 *         The calculation was performed successfully, but the passed
 *         signature is not a valid signature.
 * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
 * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
 */
psa_status_t psa_verify_message_builtin(
    const psa_key_attributes_t *attributes,
    const uint8_t *key_buffer, size_t key_buffer_size,
    psa_algorithm_t alg, const uint8_t *input, size_t input_length,
    const uint8_t *signature, size_t signature_length);

/** Sign an already-calculated hash with a private key.
 *
 * \note The signature of this function is that of a PSA driver
 *       sign_hash entry point. This function behaves as a sign_hash
 *       entry point as defined in the PSA driver interface specification for
 *       transparent drivers.
 *
 * \param[in]  attributes       The attributes of the key to use for the
 *                              operation.
 * \param[in]  key_buffer       The buffer containing the key context.
 * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes.
 * \param[in]  alg              A signature algorithm that is compatible with
 *                              the type of the key.
 * \param[in]  hash             The hash or message to sign.
 * \param[in]  hash_length      Size of the \p hash buffer in bytes.
 * \param[out] signature        Buffer where the signature is to be written.
 * \param[in]  signature_size   Size of the \p signature buffer in bytes.
 * \param[out] signature_length On success, the number of bytes
 *                              that make up the returned signature value.
 *
 * \retval #PSA_SUCCESS \emptydescription
 * \retval #PSA_ERROR_BUFFER_TOO_SMALL
 *         The size of the \p signature buffer is too small. You can
 *         determine a sufficient buffer size by calling
 *         #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
 *         where \c key_type and \c key_bits are the type and bit-size
 *         respectively of the key.
 * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
 * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
 * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
 * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
 */
psa_status_t psa_sign_hash_builtin(
    const psa_key_attributes_t *attributes,
    const uint8_t *key_buffer, size_t key_buffer_size,
    psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
    uint8_t *signature, size_t signature_size, size_t *signature_length);

/**
 * \brief Verify the signature a hash or short message using a public key.
 *
 * \note The signature of this function is that of a PSA driver
 *       verify_hash entry point. This function behaves as a verify_hash
 *       entry point as defined in the PSA driver interface specification for
 *       transparent drivers.
 *
 * \param[in]  attributes       The attributes of the key to use for the
 *                              operation.
 * \param[in]  key_buffer       The buffer containing the key context.
 * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes.
 * \param[in]  alg              A signature algorithm that is compatible with
 *                              the type of the key.
 * \param[in]  hash             The hash or message whose signature is to be
 *                              verified.
 * \param[in]  hash_length      Size of the \p hash buffer in bytes.
 * \param[in]  signature        Buffer containing the signature to verify.
 * \param[in]  signature_length Size of the \p signature buffer in bytes.
 *
 * \retval #PSA_SUCCESS
 *         The signature is valid.
 * \retval #PSA_ERROR_INVALID_SIGNATURE
 *         The calculation was performed successfully, but the passed
 *         signature is not a valid signature.
 * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
 * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
 */
psa_status_t psa_verify_hash_builtin(
    const psa_key_attributes_t *attributes,
    const uint8_t *key_buffer, size_t key_buffer_size,
    psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
    const uint8_t *signature, size_t signature_length);

/**
 * \brief Validate the key bit size for unstructured keys.
 *
 * \note  Check that the bit size is acceptable for a given key type for
 *        unstructured keys.
 *
 * \param[in]  type  The key type
 * \param[in]  bits  The number of bits of the key
 *
 * \retval #PSA_SUCCESS
 *         The key type and size are valid.
 * \retval #PSA_ERROR_INVALID_ARGUMENT
 *         The size in bits of the key is not valid.
 * \retval #PSA_ERROR_NOT_SUPPORTED
 *         The type and/or the size in bits of the key or the combination of
 *         the two is not supported.
 */
psa_status_t psa_validate_unstructured_key_bit_size(psa_key_type_t type,
                                                    size_t bits);

/** Perform a key agreement and return the raw shared secret, using
    built-in raw key agreement functions.
 *
 * \note The signature of this function is that of a PSA driver
 *       key_agreement entry point. This function behaves as a key_agreement
 *       entry point as defined in the PSA driver interface specification for
 *       transparent drivers.
 *
 * \param[in]  attributes           The attributes of the key to use for the
 *                                  operation.
 * \param[in]  key_buffer           The buffer containing the private key
 *                                  context.
 * \param[in]  key_buffer_size      Size of the \p key_buffer buffer in
 *                                  bytes.
 * \param[in]  alg                  A key agreement algorithm that is
 *                                  compatible with the type of the key.
 * \param[in]  peer_key             The buffer containing the key context
 *                                  of the peer's public key.
 * \param[in]  peer_key_length      Size of the \p peer_key buffer in
 *                                  bytes.
 * \param[out] shared_secret        The buffer to which the shared secret
 *                                  is to be written.
 * \param[in]  shared_secret_size   Size of the \p shared_secret buffer in
 *                                  bytes.
 * \param[out] shared_secret_length On success, the number of bytes that make
 *                                  up the returned shared secret.
 * \retval #PSA_SUCCESS
 *         Success. Shared secret successfully calculated.
 * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
 * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
 * \retval #PSA_ERROR_INVALID_ARGUMENT
 *         \p alg is not a key agreement algorithm, or
 *         \p private_key is not compatible with \p alg,
 *         or \p peer_key is not valid for \p alg or not compatible with
 *         \p private_key.
 * \retval #PSA_ERROR_BUFFER_TOO_SMALL
 *         \p shared_secret_size is too small
 * \retval #PSA_ERROR_NOT_SUPPORTED
 *         \p alg is not a supported key agreement algorithm.
 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
 * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
 * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
 * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
 * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
 * \retval #PSA_ERROR_BAD_STATE \emptydescription
 */
psa_status_t psa_key_agreement_raw_builtin(
    const psa_key_attributes_t *attributes,
    const uint8_t *key_buffer,
    size_t key_buffer_size,
    psa_algorithm_t alg,
    const uint8_t *peer_key,
    size_t peer_key_length,
    uint8_t *shared_secret,
    size_t shared_secret_size,
    size_t *shared_secret_length);

/**
 * \brief Set the maximum number of ops allowed to be executed by an
 *        interruptible function in a single call.
 *
 * \note The signature of this function is that of a PSA driver
 *       interruptible_set_max_ops entry point. This function behaves as an
 *       interruptible_set_max_ops entry point as defined in the PSA driver
 *       interface specification for transparent drivers.
 *
 * \param[in]  max_ops          The maximum number of ops to be executed in a
 *                              single call, this can be a number from 0 to
 *                              #PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED, where 0
 *                              is obviously the least amount of work done per
 *                              call.
 */
void mbedtls_psa_interruptible_set_max_ops(uint32_t max_ops);

/**
 * \brief Get the maximum number of ops allowed to be executed by an
 *        interruptible function in a single call.
 *
 * \note The signature of this function is that of a PSA driver
 *       interruptible_get_max_ops entry point. This function behaves as an
 *       interruptible_get_max_ops entry point as defined in the PSA driver
 *       interface specification for transparent drivers.
 *
 * \return                      Maximum number of ops allowed to be executed
 *                              by an interruptible function in a single call.
 */
uint32_t mbedtls_psa_interruptible_get_max_ops(void);

/**
 * \brief Get the number of ops that a hash signing operation has taken for the
 *        previous call. If no call or work has taken place, this will return
 *        zero.
 *
 * \note The signature of this function is that of a PSA driver
 *       sign_hash_get_num_ops entry point. This function behaves as an
 *       sign_hash_get_num_ops entry point as defined in the PSA driver
 *       interface specification for transparent drivers.
 *
 * \param   operation           The \c
 *                              mbedtls_psa_sign_hash_interruptible_operation_t
 *                              to use. This must be initialized first.
 *
 * \return                      Number of ops that were completed
 *                              in the last call to \c
 *                              mbedtls_psa_sign_hash_complete().
 */
uint32_t mbedtls_psa_sign_hash_get_num_ops(
    const mbedtls_psa_sign_hash_interruptible_operation_t *operation);

/**
 * \brief Get the number of ops that a hash verification operation has taken for
 *        the previous call. If no call or work has taken place, this will
 *        return zero.
 *
 * \note The signature of this function is that of a PSA driver
 *       verify_hash_get_num_ops entry point. This function behaves as an
 *       verify_hash_get_num_ops entry point as defined in the PSA driver
 *       interface specification for transparent drivers.
 *
 * \param   operation           The \c
 *                              mbedtls_psa_verify_hash_interruptible_operation_t
 *                              to use. This must be initialized first.
 *
 * \return                      Number of ops that were completed
 *                              in the last call to \c
 *                              mbedtls_psa_verify_hash_complete().
 */
uint32_t mbedtls_psa_verify_hash_get_num_ops(
    const mbedtls_psa_verify_hash_interruptible_operation_t *operation);

/**
 * \brief  Start signing a hash or short message with a private key, in an
 *         interruptible manner.
 *
 * \note The signature of this function is that of a PSA driver
 *       sign_hash_start entry point. This function behaves as a
 *       sign_hash_start entry point as defined in the PSA driver interface
 *       specification for transparent drivers.
 *
 * \param[in]  operation        The \c
 *                              mbedtls_psa_sign_hash_interruptible_operation_t
 *                              to use. This must be initialized first.
 * \param[in]  attributes       The attributes of the key to use for the
 *                              operation.
 * \param[in]  key_buffer       The buffer containing the key context.
 * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes.
 * \param[in]  alg              A signature algorithm that is compatible with
 *                              the type of the key.
 * \param[in] hash              The hash or message to sign.
 * \param hash_length           Size of the \p hash buffer in bytes.
 *
 * \retval #PSA_SUCCESS
 *         The operation started successfully - call \c psa_sign_hash_complete()
 *         with the same context to complete the operation
 * \retval #PSA_ERROR_INVALID_ARGUMENT
 *         An unsupported, incorrectly formatted or incorrect type of key was
 *         used.
 * \retval #PSA_ERROR_NOT_SUPPORTED Either no internal interruptible operations
 *         are currently supported, or the key type is currently unsupported.
 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
 *         There was insufficient memory to load the key representation.
 */
psa_status_t mbedtls_psa_sign_hash_start(
    mbedtls_psa_sign_hash_interruptible_operation_t *operation,
    const psa_key_attributes_t *attributes, const uint8_t *key_buffer,
    size_t key_buffer_size, psa_algorithm_t alg,
    const uint8_t *hash, size_t hash_length);

/**
 * \brief Continue and eventually complete the action of signing a hash or
 *        short message with a private key, in an interruptible manner.
 *
 * \note The signature of this function is that of a PSA driver
 *       sign_hash_complete entry point. This function behaves as a
 *       sign_hash_complete entry point as defined in the PSA driver interface
 *       specification for transparent drivers.
 *
 * \param[in]  operation        The \c
 *                              mbedtls_psa_sign_hash_interruptible_operation_t
 *                              to use. This must be initialized first.
 *
 * \param[out] signature        Buffer where the signature is to be written.
 * \param signature_size        Size of the \p signature buffer in bytes. This
 *                              must be appropriate for the selected
 *                              algorithm and key.
 * \param[out] signature_length On success, the number of bytes that make up
 *                              the returned signature value.
 *
 * \retval #PSA_SUCCESS
 *         Operation completed successfully
 *
 * \retval #PSA_OPERATION_INCOMPLETE
 *         Operation was interrupted due to the setting of \c
 *         psa_interruptible_set_max_ops(), there is still work to be done,
 *         please call this function again with the same operation object.
 *
 * \retval #PSA_ERROR_BUFFER_TOO_SMALL
 *         The size of the \p signature buffer is too small. You can
 *         determine a sufficient buffer size by calling
 *         #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
 *         where \c key_type and \c key_bits are the type and bit-size
 *         respectively of \p key.
 *
 * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
 * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
 * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
 * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
 */
psa_status_t mbedtls_psa_sign_hash_complete(
    mbedtls_psa_sign_hash_interruptible_operation_t *operation,
    uint8_t *signature, size_t signature_size,
    size_t *signature_length);

/**
 * \brief Abort a sign hash operation.
 *
 * \note The signature of this function is that of a PSA driver sign_hash_abort
 *       entry point. This function behaves as a sign_hash_abort entry point as
 *       defined in the PSA driver interface specification for transparent
 *       drivers.
 *
 * \param[in]  operation        The \c
 *                              mbedtls_psa_sign_hash_interruptible_operation_t
 *                              to abort.
 *
 * \retval #PSA_SUCCESS
 *         The operation was aborted successfully.
 */
psa_status_t mbedtls_psa_sign_hash_abort(
    mbedtls_psa_sign_hash_interruptible_operation_t *operation);

/**
 * \brief  Start reading and verifying a hash or short message, in an
 *         interruptible manner.
 *
 * \note The signature of this function is that of a PSA driver
 *       verify_hash_start entry point. This function behaves as a
 *       verify_hash_start entry point as defined in the PSA driver interface
 *       specification for transparent drivers.
 *
 * \param[in]  operation        The \c
 *                              mbedtls_psa_verify_hash_interruptible_operation_t
 *                              to use. This must be initialized first.
 * \param[in]  attributes       The attributes of the key to use for the
 *                              operation.
 * \param[in]  key_buffer       The buffer containing the key context.
 * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes.
 * \param[in]  alg              A signature algorithm that is compatible with
 *                              the type of the key.
 * \param[in] hash              The hash whose signature is to be verified.
 * \param hash_length           Size of the \p hash buffer in bytes.
 * \param[in] signature         Buffer containing the signature to verify.
 * \param signature_length      Size of the \p signature buffer in bytes.
 *
 * \retval #PSA_SUCCESS
 *         The operation started successfully - call \c psa_sign_hash_complete()
 *         with the same context to complete the operation
 * \retval #PSA_ERROR_INVALID_ARGUMENT
 *         An unsupported or incorrect type of key was used.
 * \retval #PSA_ERROR_NOT_SUPPORTED
 *        Either no internal interruptible operations are currently supported,
 *         or the key type is currently unsupported.
 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
 *        There was insufficient memory either to load the key representation,
 *        or to prepare the operation.
 */
psa_status_t mbedtls_psa_verify_hash_start(
    mbedtls_psa_verify_hash_interruptible_operation_t *operation,
    const psa_key_attributes_t *attributes,
    const uint8_t *key_buffer, size_t key_buffer_size,
    psa_algorithm_t alg,
    const uint8_t *hash, size_t hash_length,
    const uint8_t *signature, size_t signature_length);

/**
 * \brief Continue and eventually complete the action of signing a hash or
 *        short message with a private key, in an interruptible manner.
 *
 * \note The signature of this function is that of a PSA driver
 *       sign_hash_complete entry point. This function behaves as a
 *       sign_hash_complete entry point as defined in the PSA driver interface
 *       specification for transparent drivers.
 *
 * \param[in]  operation        The \c
 *                              mbedtls_psa_sign_hash_interruptible_operation_t
 *                              to use. This must be initialized first.
 *
 * \retval #PSA_SUCCESS
 *         Operation completed successfully, and the passed signature is valid.
 *
 * \retval #PSA_OPERATION_INCOMPLETE
 *         Operation was interrupted due to the setting of \c
 *         psa_interruptible_set_max_ops(), there is still work to be done,
 *         please call this function again with the same operation object.
 *
 * \retval #PSA_ERROR_INVALID_SIGNATURE
 *         The calculation was performed successfully, but the passed
 *         signature is not a valid signature.
 *
 * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
 * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
 */
psa_status_t mbedtls_psa_verify_hash_complete(
    mbedtls_psa_verify_hash_interruptible_operation_t *operation);

/**
 * \brief Abort a verify signed hash operation.
 *
 * \note The signature of this function is that of a PSA driver
 *       verify_hash_abort entry point. This function behaves as a
 *       verify_hash_abort entry point as defined in the PSA driver interface
 *       specification for transparent drivers.
 *
 * \param[in]  operation        The \c
 *                              mbedtls_psa_verify_hash_interruptible_operation_t
 *                              to abort.
 *
 * \retval #PSA_SUCCESS
 *         The operation was aborted successfully.
 */
psa_status_t mbedtls_psa_verify_hash_abort(
    mbedtls_psa_verify_hash_interruptible_operation_t *operation);

#endif /* PSA_CRYPTO_CORE_H */