Skip to content

Commit 6b12d53

Browse files
Declare key material wrapping functions
Declare functions to wrap and unwrap key material in standard formats. Declare an algorithm category for key wrapping. Declare a corresponding usage flag.
1 parent 983840e commit 6b12d53

File tree

3 files changed

+172
-0
lines changed

3 files changed

+172
-0
lines changed

include/psa/crypto.h

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,6 +1029,117 @@ psa_status_t psa_get_wrapped_key_attributes(const uint8_t *data,
10291029
size_t data_length,
10301030
psa_key_attributes_t *attributes);
10311031

1032+
/**
1033+
* \brief Export key material in wrapped form.
1034+
*
1035+
* A wrapped form of the key material preserves the confidentiality
1036+
* and authenticity of the key material. In practical terms, the key
1037+
* material is encrypted and authenticated.
1038+
*
1039+
* The policy on the key must have the usage flag
1040+
* #PSA_KEY_USAGE_EXPORT_WRAPPED set.
1041+
*
1042+
* \param wrapping_key Handle to the key to wrap with.
1043+
* \param alg The key wrapping algorithm to compute
1044+
* (\c PSA_ALG_XXX value such that
1045+
* #PSA_ALG_IS_KEY_WRAP(\p alg) is true).
1046+
* \param handle Handle to the key whose material is to be
1047+
* exported in wrapped form.
1048+
* \param[out] data Buffer where the wrapped key data is to be written.
1049+
* \param data_size Size of the \p data buffer in bytes.
1050+
* \param[out] data_length On success, the number of bytes
1051+
* that make up the wrapped key data.
1052+
*
1053+
* \retval #PSA_SUCCESS
1054+
* \retval #PSA_ERROR_INVALID_HANDLE
1055+
* One or both of \p handle and \p wrapping_key is not a valid
1056+
* handle to a key.
1057+
* \retval #PSA_ERROR_NOT_PERMITTED
1058+
* The key \p handle does not have the #PSA_KEY_USAGE_BACKUP flag.
1059+
* \retval #PSA_ERROR_INVALID_ARGUMENT
1060+
* \p wrapping_key does not support wrapping key material.
1061+
* \retval #PSA_ERROR_NOT_SUPPORTED
1062+
* \p wrapping_key does not support wrapping the key designated
1063+
* by \p handle.
1064+
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
1065+
* The size of the \p data buffer is too small. You can determine a
1066+
* sufficient buffer size by calling
1067+
* #PSA_WRAP_KEY_MATERIAL_OUTPUT_SIZE(\p alg, \c type, \c bits)
1068+
* where \c type is the key type of \p handle
1069+
* and \c bits is the key size of \p handle in bits.
1070+
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
1071+
* \retval #PSA_ERROR_HARDWARE_FAILURE
1072+
* \retval #PSA_ERROR_CORRUPTION_DETECTED
1073+
* \retval #PSA_ERROR_STORAGE_FAILURE
1074+
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
1075+
* \retval #PSA_ERROR_BAD_STATE
1076+
* The library has not been previously initialized by psa_crypto_init().
1077+
* It is implementation-dependent whether a failure to initialize
1078+
* results in this error code.
1079+
*/
1080+
psa_status_t psa_wrap_key_material(psa_key_handle_t wrapping_key,
1081+
psa_algorithm_t alg,
1082+
psa_key_handle_t handle,
1083+
uint8_t *data,
1084+
size_t data_size,
1085+
size_t *data_length);
1086+
1087+
/**
1088+
* \brief Import wrapped key material.
1089+
*
1090+
* \param wrapping_key Handle to the key to unwrap with.
1091+
* \param alg The key unwrapping algorithm to compute
1092+
* (\c PSA_ALG_XXX value such that
1093+
* #PSA_ALG_IS_KEY_WRAP(\p alg) is true).
1094+
* \param[in] attributes The attributes for the new key.
1095+
* They are used in the same way as by
1096+
* psa_import_key().
1097+
* \param[in] data Buffer containing the key data. The expected
1098+
* format of this buffer depends on the wrapping
1099+
* key and on the type declared in \p attributes.
1100+
* \param data_length Size of the \p data buffer in bytes.
1101+
* \param[out] handle On success, a handle to the newly created key.
1102+
* \c 0 on failure.
1103+
*
1104+
* \retval #PSA_SUCCESS
1105+
* Success.
1106+
* If the unwrapped key is persistent, the key material and the
1107+
* key's metadata have been saved to persistent storage.
1108+
* \retval #PSA_ERROR_ALREADY_EXISTS
1109+
* This is an attempt to create a persistent key, and there is
1110+
* already a persistent key with the given identifier.
1111+
* \retval #PSA_ERROR_INVALID_ARGUMENT
1112+
* The key attributes, as a whole, are invalid.
1113+
* \retval #PSA_ERROR_INVALID_ARGUMENT
1114+
* The key data is not correctly formatted.
1115+
* \retval #PSA_ERROR_INVALID_ARGUMENT
1116+
* The size in \p attributes is nonzero and does not match the size
1117+
* of the key data.
1118+
* \retval #PSA_ERROR_INVALID_ARGUMENT
1119+
* \p wrapping_key does not support unwrapping keys with metadata.
1120+
* \retval #PSA_ERROR_INVALID_SIGNATURE
1121+
* \p data is not a valid wrapped key for \p wrapping_key.
1122+
* \retval #PSA_ERROR_NOT_SUPPORTED
1123+
* Some of the metadata in either \p attributes or \p data is
1124+
* not supported.
1125+
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
1126+
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
1127+
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
1128+
* \retval #PSA_ERROR_STORAGE_FAILURE
1129+
* \retval #PSA_ERROR_HARDWARE_FAILURE
1130+
* \retval #PSA_ERROR_CORRUPTION_DETECTED
1131+
* \retval #PSA_ERROR_BAD_STATE
1132+
* The library has not been previously initialized by psa_crypto_init().
1133+
* It is implementation-dependent whether a failure to initialize
1134+
* results in this error code.
1135+
*/
1136+
psa_status_t psa_unwrap_key_material(psa_key_handle_t wrapping_key,
1137+
psa_algorithm_t alg,
1138+
const psa_key_attributes_t *attributes,
1139+
const uint8_t *data,
1140+
size_t data_length,
1141+
psa_key_handle_t *handle);
1142+
10321143

10331144

10341145
/**@}*/

include/psa/crypto_sizes.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,4 +684,30 @@
684684
#define PSA_WRAP_KEY_WITH_POLICY_OUTPUT_SIZE(key_type, key_bits) \
685685
0u /*not implemented yet*/
686686

687+
/** Sufficient output buffer size for psa_wrap_key_material().
688+
*
689+
* This macro returns a compile-time constant if its arguments are
690+
* compile-time constants.
691+
*
692+
* \warning This function may call its arguments multiple times or
693+
* zero times, so you should not pass arguments that contain
694+
* side effects.
695+
*
696+
* \param alg The key wrapping algorithm.
697+
* \param key_type A supported key type.
698+
* \param key_bits The size of the key in bits.
699+
*
700+
* \return If the parameters are valid and supported, return
701+
* a buffer size in bytes that guarantees that
702+
* psa_wrap_key_material() will not fail with
703+
* #PSA_ERROR_BUFFER_TOO_SMALL.
704+
* If the parameters are a valid combination that is not supported
705+
* by the implementation, this macro shall return either a
706+
* sensible size or 0.
707+
* If the parameters are not valid, the
708+
* return value is unspecified.
709+
*/
710+
#define PSA_WRAP_KEY_MATERIAL_OUTPUT_SIZE(alg, key_type, key_bits) \
711+
0u /*not implemented yet*/
712+
687713
#endif /* PSA_CRYPTO_SIZES_H */

include/psa/crypto_values.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,7 @@
615615
#define PSA_ALG_CATEGORY_MAC ((psa_algorithm_t)0x02000000)
616616
#define PSA_ALG_CATEGORY_CIPHER ((psa_algorithm_t)0x04000000)
617617
#define PSA_ALG_CATEGORY_AEAD ((psa_algorithm_t)0x06000000)
618+
#define PSA_ALG_CATEGORY_WRAP ((psa_algorithm_t)0x0e000000)
618619
#define PSA_ALG_CATEGORY_SIGN ((psa_algorithm_t)0x10000000)
619620
#define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION ((psa_algorithm_t)0x12000000)
620621
#define PSA_ALG_CATEGORY_KEY_DERIVATION ((psa_algorithm_t)0x20000000)
@@ -672,6 +673,17 @@
672673
#define PSA_ALG_IS_AEAD(alg) \
673674
(((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_AEAD)
674675

676+
/** Whether the specified algorithm is a key wrapping algorithm.
677+
*
678+
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
679+
*
680+
* \return 1 if \p alg is a key wrapping algorithm, 0 otherwise.
681+
* This macro may return either 0 or 1 if \p alg is not a supported
682+
* algorithm identifier.
683+
*/
684+
#define PSA_ALG_IS_KEY_WRAP(alg) \
685+
(((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_WRAP)
686+
675687
/** Whether the specified algorithm is a public-key signature algorithm.
676688
*
677689
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
@@ -1622,6 +1634,29 @@
16221634
*/
16231635
#define PSA_KEY_USAGE_COPY ((psa_key_usage_t)0x00000002)
16241636

1637+
/** Whether the key material may be exported in wrapped form.
1638+
*
1639+
* This flag allows the use of psa_wrap_key_material() on the given key,
1640+
* with any suitable wrapping key.
1641+
*
1642+
* A wrapped form of the key material preserves the confidentiality
1643+
* and authenticity of the key material. In practical terms, the key
1644+
* material is encrypted and authenticated.
1645+
*
1646+
* A wrapped form does not preserve the key metadata in general, so it is up
1647+
* to the application to ensure that the key is unwrapped with the correct
1648+
* type and policy.
1649+
*
1650+
* \note Given that a wrapped key can be unwrapped with a different policy,
1651+
* which may include #PSA_KEY_USAGE_EXPORT, there is often no
1652+
* security advantage to allowing the key usage
1653+
* #PSA_KEY_USAGE_EXPORT_WRAPPED but not #PSA_KEY_USAGE_EXPORT.
1654+
* However implementations may impose restrictions on keys that
1655+
* are created through unwrapping with a particular key, in which
1656+
* case unwrapping could preserve the non-extractibility of a key.
1657+
*/
1658+
#define PSA_KEY_USAGE_EXPORT_WRAPPED ((psa_key_usage_t)0x00000010)
1659+
16251660
/** Whether the key object may be saved outside the device in wrapped form.
16261661
* This is also known as key binding.
16271662
*

0 commit comments

Comments
 (0)