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