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