• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  PSA crypto core internal interfaces
3  */
4 /*
5  *  Copyright The Mbed TLS Contributors
6  *  SPDX-License-Identifier: Apache-2.0
7  *
8  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
9  *  not use this file except in compliance with the License.
10  *  You may obtain a copy of the License at
11  *
12  *  http://www.apache.org/licenses/LICENSE-2.0
13  *
14  *  Unless required by applicable law or agreed to in writing, software
15  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  *  See the License for the specific language governing permissions and
18  *  limitations under the License.
19  */
20 
21 #ifndef PSA_CRYPTO_CORE_H
22 #define PSA_CRYPTO_CORE_H
23 
24 #include "mbedtls/build_info.h"
25 
26 #include "psa/crypto.h"
27 #include "psa/crypto_se_driver.h"
28 
29 /** Constant-time buffer comparison
30  *
31  * \param[in]  a    Left-hand buffer for comparison.
32  * \param[in]  b    Right-hand buffer for comparison.
33  * \param n         Amount of bytes to compare.
34  *
35  * \return 0 if the buffer contents are equal, non-zero otherwise
36  */
mbedtls_psa_safer_memcmp(const uint8_t * a,const uint8_t * b,size_t n)37 static inline int mbedtls_psa_safer_memcmp(
38     const uint8_t *a, const uint8_t *b, size_t n )
39 {
40     size_t i;
41     unsigned char diff = 0;
42 
43     for( i = 0; i < n; i++ )
44         diff |= a[i] ^ b[i];
45 
46     return( diff );
47 }
48 
49 /** The data structure representing a key slot, containing key material
50  * and metadata for one key.
51  */
52 typedef struct
53 {
54     psa_core_key_attributes_t attr;
55 
56     /*
57      * Number of locks on the key slot held by the library.
58      *
59      * This counter is incremented by one each time a library function
60      * retrieves through one of the dedicated internal API a pointer to the
61      * key slot.
62      *
63      * This counter is decremented by one each time a library function stops
64      * accessing the key slot and states it by calling the
65      * psa_unlock_key_slot() API.
66      *
67      * This counter is used to prevent resetting the key slot while the library
68      * may access it. For example, such control is needed in the following
69      * scenarios:
70      * . In case of key slot starvation, all key slots contain the description
71      *   of a key, and the library asks for the description of a persistent
72      *   key not present in the key slots, the key slots currently accessed by
73      *   the library cannot be reclaimed to free a key slot to load the
74      *   persistent key.
75      * . In case of a multi-threaded application where one thread asks to close
76      *   or purge or destroy a key while it is in used by the library through
77      *   another thread.
78      */
79     size_t lock_count;
80 
81     /* Dynamically allocated key data buffer.
82      * Format as specified in psa_export_key(). */
83     struct key_data
84     {
85         uint8_t *data;
86         size_t bytes;
87     } key;
88 } psa_key_slot_t;
89 
90 /* A mask of key attribute flags used only internally.
91  * Currently there aren't any. */
92 #define PSA_KA_MASK_INTERNAL_ONLY (     \
93         0 )
94 
95 /** Test whether a key slot is occupied.
96  *
97  * A key slot is occupied iff the key type is nonzero. This works because
98  * no valid key can have 0 as its key type.
99  *
100  * \param[in] slot      The key slot to test.
101  *
102  * \return 1 if the slot is occupied, 0 otherwise.
103  */
psa_is_key_slot_occupied(const psa_key_slot_t * slot)104 static inline int psa_is_key_slot_occupied( const psa_key_slot_t *slot )
105 {
106     return( slot->attr.type != 0 );
107 }
108 
109 /** Test whether a key slot is locked.
110  *
111  * A key slot is locked iff its lock counter is strictly greater than 0.
112  *
113  * \param[in] slot  The key slot to test.
114  *
115  * \return 1 if the slot is locked, 0 otherwise.
116  */
psa_is_key_slot_locked(const psa_key_slot_t * slot)117 static inline int psa_is_key_slot_locked( const psa_key_slot_t *slot )
118 {
119     return( slot->lock_count > 0 );
120 }
121 
122 /** Retrieve flags from psa_key_slot_t::attr::core::flags.
123  *
124  * \param[in] slot      The key slot to query.
125  * \param mask          The mask of bits to extract.
126  *
127  * \return The key attribute flags in the given slot,
128  *         bitwise-anded with \p mask.
129  */
psa_key_slot_get_flags(const psa_key_slot_t * slot,uint16_t mask)130 static inline uint16_t psa_key_slot_get_flags( const psa_key_slot_t *slot,
131                                                uint16_t mask )
132 {
133     return( slot->attr.flags & mask );
134 }
135 
136 /** Set flags in psa_key_slot_t::attr::core::flags.
137  *
138  * \param[in,out] slot  The key slot to modify.
139  * \param mask          The mask of bits to modify.
140  * \param value         The new value of the selected bits.
141  */
psa_key_slot_set_flags(psa_key_slot_t * slot,uint16_t mask,uint16_t value)142 static inline void psa_key_slot_set_flags( psa_key_slot_t *slot,
143                                            uint16_t mask,
144                                            uint16_t value )
145 {
146     slot->attr.flags = ( ( ~mask & slot->attr.flags ) |
147                               ( mask & value ) );
148 }
149 
150 /** Turn on flags in psa_key_slot_t::attr::core::flags.
151  *
152  * \param[in,out] slot  The key slot to modify.
153  * \param mask          The mask of bits to set.
154  */
psa_key_slot_set_bits_in_flags(psa_key_slot_t * slot,uint16_t mask)155 static inline void psa_key_slot_set_bits_in_flags( psa_key_slot_t *slot,
156                                                    uint16_t mask )
157 {
158     slot->attr.flags |= mask;
159 }
160 
161 /** Turn off flags in psa_key_slot_t::attr::core::flags.
162  *
163  * \param[in,out] slot  The key slot to modify.
164  * \param mask          The mask of bits to clear.
165  */
psa_key_slot_clear_bits(psa_key_slot_t * slot,uint16_t mask)166 static inline void psa_key_slot_clear_bits( psa_key_slot_t *slot,
167                                             uint16_t mask )
168 {
169     slot->attr.flags &= ~mask;
170 }
171 
172 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
173 /** Get the SE slot number of a key from the key slot storing its description.
174  *
175  * \param[in]  slot  The key slot to query. This must be a key slot storing
176  *                   the description of a key of a dynamically registered
177  *                   secure element, otherwise the behaviour is undefined.
178  */
psa_key_slot_get_slot_number(const psa_key_slot_t * slot)179 static inline psa_key_slot_number_t psa_key_slot_get_slot_number(
180     const psa_key_slot_t *slot )
181 {
182     return( *( (psa_key_slot_number_t *)( slot->key.data ) ) );
183 }
184 #endif
185 
186 /** Completely wipe a slot in memory, including its policy.
187  *
188  * Persistent storage is not affected.
189  *
190  * \param[in,out] slot  The key slot to wipe.
191  *
192  * \retval #PSA_SUCCESS
193  *         Success. This includes the case of a key slot that was
194  *         already fully wiped.
195  * \retval #PSA_ERROR_CORRUPTION_DETECTED
196  */
197 psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot );
198 
199 /** Try to allocate a buffer to an empty key slot.
200  *
201  * \param[in,out] slot          Key slot to attach buffer to.
202  * \param[in] buffer_length     Requested size of the buffer.
203  *
204  * \retval #PSA_SUCCESS
205  *         The buffer has been successfully allocated.
206  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
207  *         Not enough memory was available for allocation.
208  * \retval #PSA_ERROR_ALREADY_EXISTS
209  *         Trying to allocate a buffer to a non-empty key slot.
210  */
211 psa_status_t psa_allocate_buffer_to_slot( psa_key_slot_t *slot,
212                                           size_t buffer_length );
213 
214 /** Wipe key data from a slot. Preserves metadata such as the policy. */
215 psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot );
216 
217 /** Copy key data (in export format) into an empty key slot.
218  *
219  * This function assumes that the slot does not contain
220  * any key material yet. On failure, the slot content is unchanged.
221  *
222  * \param[in,out] slot          Key slot to copy the key into.
223  * \param[in] data              Buffer containing the key material.
224  * \param data_length           Size of the key buffer.
225  *
226  * \retval #PSA_SUCCESS
227  *         The key has been copied successfully.
228  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
229  *         Not enough memory was available for allocation of the
230  *         copy buffer.
231  * \retval #PSA_ERROR_ALREADY_EXISTS
232  *         There was other key material already present in the slot.
233  */
234 psa_status_t psa_copy_key_material_into_slot( psa_key_slot_t *slot,
235                                               const uint8_t *data,
236                                               size_t data_length );
237 
238 /** Convert an mbed TLS error code to a PSA error code
239  *
240  * \note This function is provided solely for the convenience of
241  *       Mbed TLS and may be removed at any time without notice.
242  *
243  * \param ret           An mbed TLS-thrown error code
244  *
245  * \return              The corresponding PSA error code
246  */
247 psa_status_t mbedtls_to_psa_error( int ret );
248 
249 /** Get Mbed TLS cipher information given the cipher algorithm PSA identifier
250  *  as well as the PSA type and size of the key to be used with the cipher
251  *  algorithm.
252  *
253  * \param       alg        PSA cipher algorithm identifier
254  * \param       key_type   PSA key type
255  * \param       key_bits   Size of the key in bits
256  * \param[out]  cipher_id  Mbed TLS cipher algorithm identifier
257  *
258  * \return  The Mbed TLS cipher information of the cipher algorithm.
259  *          \c NULL if the PSA cipher algorithm is not supported.
260  */
261 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
262     psa_algorithm_t alg, psa_key_type_t key_type, size_t key_bits,
263     mbedtls_cipher_id_t *cipher_id );
264 
265 /** Import a key in binary format.
266  *
267  * \note The signature of this function is that of a PSA driver
268  *       import_key entry point. This function behaves as an import_key
269  *       entry point as defined in the PSA driver interface specification for
270  *       transparent drivers.
271  *
272  * \param[in]  attributes       The attributes for the key to import.
273  * \param[in]  data             The buffer containing the key data in import
274  *                              format.
275  * \param[in]  data_length      Size of the \p data buffer in bytes.
276  * \param[out] key_buffer       The buffer to contain the key data in output
277  *                              format upon successful return.
278  * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes. This
279  *                              size is greater or equal to \p data_length.
280  * \param[out] key_buffer_length  The length of the data written in \p
281  *                                key_buffer in bytes.
282  * \param[out] bits             The key size in number of bits.
283  *
284  * \retval #PSA_SUCCESS  The key was imported successfully.
285  * \retval #PSA_ERROR_INVALID_ARGUMENT
286  *         The key data is not correctly formatted.
287  * \retval #PSA_ERROR_NOT_SUPPORTED
288  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
289  * \retval #PSA_ERROR_CORRUPTION_DETECTED
290  */
291 psa_status_t psa_import_key_into_slot(
292     const psa_key_attributes_t *attributes,
293     const uint8_t *data, size_t data_length,
294     uint8_t *key_buffer, size_t key_buffer_size,
295     size_t *key_buffer_length, size_t *bits );
296 
297 /** Export a key in binary format
298  *
299  * \note The signature of this function is that of a PSA driver export_key
300  *       entry point. This function behaves as an export_key entry point as
301  *       defined in the PSA driver interface specification.
302  *
303  * \param[in]  attributes       The attributes for the key to export.
304  * \param[in]  key_buffer       Material or context of the key to export.
305  * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes.
306  * \param[out] data             Buffer where the key data is to be written.
307  * \param[in]  data_size        Size of the \p data buffer in bytes.
308  * \param[out] data_length      On success, the number of bytes written in
309  *                              \p data
310  *
311  * \retval #PSA_SUCCESS  The key was exported successfully.
312  * \retval #PSA_ERROR_NOT_SUPPORTED
313  * \retval #PSA_ERROR_COMMUNICATION_FAILURE
314  * \retval #PSA_ERROR_HARDWARE_FAILURE
315  * \retval #PSA_ERROR_CORRUPTION_DETECTED
316  * \retval #PSA_ERROR_STORAGE_FAILURE
317  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
318  */
319 psa_status_t psa_export_key_internal(
320     const psa_key_attributes_t *attributes,
321     const uint8_t *key_buffer, size_t key_buffer_size,
322     uint8_t *data, size_t data_size, size_t *data_length );
323 
324 /** Export a public key or the public part of a key pair in binary format.
325  *
326  * \note The signature of this function is that of a PSA driver
327  *       export_public_key entry point. This function behaves as an
328  *       export_public_key entry point as defined in the PSA driver interface
329  *       specification.
330  *
331  * \param[in]  attributes       The attributes for the key to export.
332  * \param[in]  key_buffer       Material or context of the key to export.
333  * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes.
334  * \param[out] data             Buffer where the key data is to be written.
335  * \param[in]  data_size        Size of the \p data buffer in bytes.
336  * \param[out] data_length      On success, the number of bytes written in
337  *                              \p data
338  *
339  * \retval #PSA_SUCCESS  The public key was exported successfully.
340  * \retval #PSA_ERROR_NOT_SUPPORTED
341  * \retval #PSA_ERROR_COMMUNICATION_FAILURE
342  * \retval #PSA_ERROR_HARDWARE_FAILURE
343  * \retval #PSA_ERROR_CORRUPTION_DETECTED
344  * \retval #PSA_ERROR_STORAGE_FAILURE
345  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
346  */
347 psa_status_t psa_export_public_key_internal(
348     const psa_key_attributes_t *attributes,
349     const uint8_t *key_buffer, size_t key_buffer_size,
350     uint8_t *data, size_t data_size, size_t *data_length );
351 
352 /**
353  * \brief Generate a key.
354  *
355  * \note The signature of the function is that of a PSA driver generate_key
356  *       entry point.
357  *
358  * \param[in]  attributes         The attributes for the key to generate.
359  * \param[out] key_buffer         Buffer where the key data is to be written.
360  * \param[in]  key_buffer_size    Size of \p key_buffer in bytes.
361  * \param[out] key_buffer_length  On success, the number of bytes written in
362  *                                \p key_buffer.
363  *
364  * \retval #PSA_SUCCESS
365  *         The key was generated successfully.
366  * \retval #PSA_ERROR_INVALID_ARGUMENT
367  * \retval #PSA_ERROR_NOT_SUPPORTED
368  *         Key size in bits or type not supported.
369  * \retval #PSA_ERROR_BUFFER_TOO_SMALL
370  *         The size of \p key_buffer is too small.
371  */
372 psa_status_t psa_generate_key_internal( const psa_key_attributes_t *attributes,
373                                         uint8_t *key_buffer,
374                                         size_t key_buffer_size,
375                                         size_t *key_buffer_length );
376 
377 /** Sign a message with a private key. For hash-and-sign algorithms,
378  *  this includes the hashing step.
379  *
380  * \note The signature of this function is that of a PSA driver
381  *       sign_message entry point. This function behaves as a sign_message
382  *       entry point as defined in the PSA driver interface specification for
383  *       transparent drivers.
384  *
385  * \note This function will call the driver for psa_sign_hash
386  *       and go through driver dispatch again.
387  *
388  * \param[in]  attributes       The attributes of the key to use for the
389  *                              operation.
390  * \param[in]  key_buffer       The buffer containing the key context.
391  * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes.
392  * \param[in]  alg              A signature algorithm that is compatible with
393  *                              the type of the key.
394  * \param[in]  input            The input message to sign.
395  * \param[in]  input_length     Size of the \p input buffer in bytes.
396  * \param[out] signature        Buffer where the signature is to be written.
397  * \param[in]  signature_size   Size of the \p signature buffer in bytes.
398  * \param[out] signature_length On success, the number of bytes
399  *                              that make up the returned signature value.
400  *
401  * \retval #PSA_SUCCESS
402  * \retval #PSA_ERROR_BUFFER_TOO_SMALL
403  *         The size of the \p signature buffer is too small. You can
404  *         determine a sufficient buffer size by calling
405  *         #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
406  *         where \c key_type and \c key_bits are the type and bit-size
407  *         respectively of the key.
408  * \retval #PSA_ERROR_NOT_SUPPORTED
409  * \retval #PSA_ERROR_INVALID_ARGUMENT
410  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
411  * \retval #PSA_ERROR_CORRUPTION_DETECTED
412  * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
413  */
414 psa_status_t psa_sign_message_builtin(
415     const psa_key_attributes_t *attributes,
416     const uint8_t *key_buffer, size_t key_buffer_size,
417     psa_algorithm_t alg, const uint8_t *input, size_t input_length,
418     uint8_t *signature, size_t signature_size, size_t *signature_length );
419 
420 /** Verify the signature of a message with a public key, using
421  *  a hash-and-sign verification algorithm.
422  *
423  * \note The signature of this function is that of a PSA driver
424  *       verify_message entry point. This function behaves as a verify_message
425  *       entry point as defined in the PSA driver interface specification for
426  *       transparent drivers.
427  *
428  * \note This function will call the driver for psa_verify_hash
429  *       and go through driver dispatch again.
430  *
431  * \param[in]  attributes       The attributes of the key to use for the
432  *                              operation.
433  * \param[in]  key_buffer       The buffer containing the key context.
434  * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes.
435  * \param[in]  alg              A signature algorithm that is compatible with
436  *                              the type of the key.
437  * \param[in]  input            The message whose signature is to be verified.
438  * \param[in]  input_length     Size of the \p input buffer in bytes.
439  * \param[in]  signature        Buffer containing the signature to verify.
440  * \param[in]  signature_length Size of the \p signature buffer in bytes.
441  *
442  * \retval #PSA_SUCCESS
443  *         The signature is valid.
444  * \retval #PSA_ERROR_INVALID_SIGNATURE
445  *         The calculation was performed successfully, but the passed
446  *         signature is not a valid signature.
447  * \retval #PSA_ERROR_NOT_SUPPORTED
448  * \retval #PSA_ERROR_INVALID_ARGUMENT
449  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
450  */
451 psa_status_t psa_verify_message_builtin(
452     const psa_key_attributes_t *attributes,
453     const uint8_t *key_buffer, size_t key_buffer_size,
454     psa_algorithm_t alg, const uint8_t *input, size_t input_length,
455     const uint8_t *signature, size_t signature_length );
456 
457 /** Sign an already-calculated hash with a private key.
458  *
459  * \note The signature of this function is that of a PSA driver
460  *       sign_hash entry point. This function behaves as a sign_hash
461  *       entry point as defined in the PSA driver interface specification for
462  *       transparent drivers.
463  *
464  * \param[in]  attributes       The attributes of the key to use for the
465  *                              operation.
466  * \param[in]  key_buffer       The buffer containing the key context.
467  * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes.
468  * \param[in]  alg              A signature algorithm that is compatible with
469  *                              the type of the key.
470  * \param[in]  hash             The hash or message to sign.
471  * \param[in]  hash_length      Size of the \p hash buffer in bytes.
472  * \param[out] signature        Buffer where the signature is to be written.
473  * \param[in]  signature_size   Size of the \p signature buffer in bytes.
474  * \param[out] signature_length On success, the number of bytes
475  *                              that make up the returned signature value.
476  *
477  * \retval #PSA_SUCCESS
478  * \retval #PSA_ERROR_BUFFER_TOO_SMALL
479  *         The size of the \p signature buffer is too small. You can
480  *         determine a sufficient buffer size by calling
481  *         #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
482  *         where \c key_type and \c key_bits are the type and bit-size
483  *         respectively of the key.
484  * \retval #PSA_ERROR_NOT_SUPPORTED
485  * \retval #PSA_ERROR_INVALID_ARGUMENT
486  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
487  * \retval #PSA_ERROR_CORRUPTION_DETECTED
488  * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
489  */
490 psa_status_t psa_sign_hash_builtin(
491     const psa_key_attributes_t *attributes,
492     const uint8_t *key_buffer, size_t key_buffer_size,
493     psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
494     uint8_t *signature, size_t signature_size, size_t *signature_length );
495 
496 /**
497  * \brief Verify the signature a hash or short message using a public key.
498  *
499  * \note The signature of this function is that of a PSA driver
500  *       verify_hash entry point. This function behaves as a verify_hash
501  *       entry point as defined in the PSA driver interface specification for
502  *       transparent drivers.
503  *
504  * \param[in]  attributes       The attributes of the key to use for the
505  *                              operation.
506  * \param[in]  key_buffer       The buffer containing the key context.
507  * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes.
508  * \param[in]  alg              A signature algorithm that is compatible with
509  *                              the type of the key.
510  * \param[in]  hash             The hash or message whose signature is to be
511  *                              verified.
512  * \param[in]  hash_length      Size of the \p hash buffer in bytes.
513  * \param[in]  signature        Buffer containing the signature to verify.
514  * \param[in]  signature_length Size of the \p signature buffer in bytes.
515  *
516  * \retval #PSA_SUCCESS
517  *         The signature is valid.
518  * \retval #PSA_ERROR_INVALID_SIGNATURE
519  *         The calculation was performed successfully, but the passed
520  *         signature is not a valid signature.
521  * \retval #PSA_ERROR_NOT_SUPPORTED
522  * \retval #PSA_ERROR_INVALID_ARGUMENT
523  * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
524  */
525 psa_status_t psa_verify_hash_builtin(
526     const psa_key_attributes_t *attributes,
527     const uint8_t *key_buffer, size_t key_buffer_size,
528     psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
529     const uint8_t *signature, size_t signature_length );
530 
531 /**
532  * \brief Validate the key bit size for unstructured keys.
533  *
534  * \note  Check that the bit size is acceptable for a given key type for
535  *        unstructured keys.
536  *
537  * \param[in]  type  The key type
538  * \param[in]  bits  The number of bits of the key
539  *
540  * \retval #PSA_SUCCESS
541  *         The key type and size are valid.
542  * \retval #PSA_ERROR_INVALID_ARGUMENT
543  *         The size in bits of the key is not valid.
544  * \retval #PSA_ERROR_NOT_SUPPORTED
545  *         The type and/or the size in bits of the key or the combination of
546  *         the two is not supported.
547  */
548 psa_status_t psa_validate_unstructured_key_bit_size( psa_key_type_t type,
549                                                      size_t bits );
550 #endif /* PSA_CRYPTO_CORE_H */
551