10.7 Key wrapping¶
Key wrapping is the process of encrypting a key, so that the resulting ciphertext can be stored, or transported, in a form that maintains the confidentiality of the key material. Key unwrapping reverses this process, extracting the key from the ciphertext. Some key-wrapping schemes also provide integrity protection, to ensure that modification of the ciphertext can be detected.
Some key-wrapping algorithms operate on arbitrary data, and provide authenticated encryption that is specifically designed for key values.
For example, the AES Key-wrap algorithm AES-KW.
For this type of algorithm, the Crypto API provides a simple pair of functions, psa_unwrap_key() and psa_wrap_key(), that unwrap or wrap key data in the default export format.
When using one of these key-wrapping algorithms, the key attributes are managed by the application.
Note
Other key-wrapping schemes define both the format of the wrapped key material and the algorithm that is used to perform the wrapping. For example PKCS#8 defines EncryptedPrivateKeyInfo, which is also described in Asymmetric Key Packages [RFC5958]. Wrapped-key formats typically encode the key type and wrapping algorithm within the output data, and can also include other key attributes. This version of the Crypto API does not support these key-wrapping schemes, but this is planned for a future version.
10.7.1 Key-wrapping algorithms¶
PSA_ALG_KW (macro)¶
A key-wrapping algorithm based on the NIST Key Wrap (KW) mode of a block cipher.
Added in version 1.4.
#define PSA_ALG_KW ((psa_algorithm_t)0x0B400100)
KW is defined for block ciphers that have a 128-bit block size. The underlying block cipher is determined by the key type.
Keys to be wrapped must have a length equal to a multiple of the ‘semi-block’ size for the block cipher. That is, a multiple of 8 bytes.
To wrap keys that are not a multiple of the semi-block size, PSA_ALG_KWP can be used.
This is the NIST Key Wrap algorithm, using any block-cipher that operates on 128-bit blocks, as defined in NIST Special Publication 800-38F: Recommendation for Block Cipher Modes of Operation: Methods for Key Wrapping [SP800-38F]. A definition of AES-KW is also found in Advanced Encryption Standard (AES) Key Wrap Algorithm [RFC3394].
Compatible key types
PSA_ALG_KWP (macro)¶
A key-wrapping algorithm based on the NIST Key Wrap with Padding (KWP) mode of a block cipher.
Added in version 1.4.
#define PSA_ALG_KWP ((psa_algorithm_t)0x0BC00200)
KWP is defined for block ciphers that have a 128-bit block size. The underlying block cipher is determined by the key type.
This algorithm can wrap a key of any length.
This is the NIST Key Wrap with Padding algorithm, using any block-cipher that operates on 128-bit blocks, as defined in NIST Special Publication 800-38F: Recommendation for Block Cipher Modes of Operation: Methods for Key Wrapping [SP800-38F]. A definition of AES-KWP is also found in Advanced Encryption Standard (AES) Key Wrap with Padding Algorithm [RFC5649].
Compatible key types
10.7.2 Key wrapping functions¶
psa_unwrap_key (function)¶
Unwrap and import a key using a specified wrapping key.
Added in version 1.4.
psa_status_t psa_unwrap_key(const psa_key_attributes_t * attributes, psa_key_id_t wrapping_key, psa_algorithm_t alg, const uint8_t * data, size_t data_length, psa_key_id_t * key);
Parameters
attributesThe attributes for the new key.
The following attributes are required for all keys:
The key type determines how the decrypted
databuffer is interpreted.
The following attributes must be set for keys used in cryptographic operations:
The key permitted-algorithm policy, see Permitted algorithms.
The key usage flags, see Key usage flags.
The following attributes must be set for keys that do not use the default volatile lifetime:
The key lifetime, see Key lifetimes.
The key identifier is required for a key with a persistent lifetime, see Key identifiers.
The following attributes are optional:
If the key size is nonzero, it must be equal to the key size determined from
data.
Note
This is an input parameter: it is not updated with the final key attributes. The final attributes of the new key can be queried by calling
psa_get_key_attributes()with the key’s identifier.wrapping_keyIdentifier of the key to use for the unwrapping operation. It must permit the usage
PSA_KEY_USAGE_UNWRAP.algThe key-wrapping algorithm: a value of type
psa_algorithm_tsuch thatPSA_ALG_IS_KEY_WRAP(alg)is true.dataBuffer containing the wrapped key data. The content of this buffer is unwrapped using the algorithm
alg, and then interpreted according to the type declared inattributes.data_lengthSize of the
databuffer in bytes.keyOn success, an identifier for the newly created key.
PSA_KEY_ID_NULLon failure.
Returns: psa_status_t
PSA_SUCCESSSuccess. If the key is persistent, the key material and the key’s metadata have been saved to persistent storage.
PSA_ERROR_BAD_STATEThe library requires initializing by a call to
psa_crypto_init().PSA_ERROR_INVALID_HANDLEwrapping_keyis not a valid key identifier.PSA_ERROR_NOT_PERMITTEDThe following conditions can result in this error:
The wrapping key does not have the
PSA_KEY_USAGE_UNWRAPflag, or it does not permit the requested algorithm.The implementation does not permit creating a key with the specified attributes due to some implementation-specific policy.
PSA_ERROR_INVALID_SIGNATUREThe wrapped key data could not be authenticated.
PSA_ERROR_ALREADY_EXISTSThis is an attempt to create a persistent key, and there is already a persistent key with the given identifier.
PSA_ERROR_INVALID_ARGUMENTThe following conditions can result in this error:
algis not a key-wrapping algorithm.wrapping_keyis not compatible withalg.The key type is invalid.
The key size is nonzero, and is incompatible with the wrapped key data in
data.The key lifetime is invalid.
The key identifier is not valid for the key lifetime.
The key usage flags include invalid values.
The key’s permitted-usage algorithm is invalid.
The key attributes, as a whole, are invalid.
The key data is not correctly formatted for the key type.
PSA_ERROR_NOT_SUPPORTEDThe following conditions can result in this error:
algis not supported or is not a key-wrapping algorithm.wrapping_keyis not supported for use withalg.The key attributes, as a whole, are not supported, either by the implementation in general or in the specified storage location.
PSA_ERROR_INSUFFICIENT_MEMORYPSA_ERROR_INSUFFICIENT_STORAGEPSA_ERROR_COMMUNICATION_FAILUREPSA_ERROR_CORRUPTION_DETECTEDPSA_ERROR_STORAGE_FAILUREPSA_ERROR_DATA_CORRUPTPSA_ERROR_DATA_INVALID
Description
The key is unwrapped and extracted from the provided data buffer. Its location, policy, and type are taken from attributes.
The wrapped key data determines the key size.
:code:psa_get_key_bits(attributes) must either match the determined key size or be 0.
Implementations must reject an attempt to unwrap a key if the determined key size is 0.
Note
A call to psa_unwrap_key() first applies the decryption procedure associated with the key-wrapping algorithm alg, using the wrapping_key key, to the supplied data buffer.
The resulting plaintext is retained within the cryptoprocessor, and used with the provided attributes to create a key, as if they were inputs to psa_import_key().
Note
The Crypto API does not support asymmetric private key objects outside of a key pair. When unwrapping a private key, the corresponding key-pair type is created. If the imported key data does not contain the public key, then the implementation will reconstruct the public key from the private key as needed.
Implementation note
It is recommended that the implementation supports unwrapping any key data that can be produced by a call to psa_wrap_key(), with the same key-wrapping algorithm and key, and matching key attributes.
It is recommended that implementations reject wrapped key data if it might be erroneous, for example, if it is the wrong type or is truncated.
psa_wrap_key (function)¶
Wrap and export a key using a specified wrapping key.
Added in version 1.4.
psa_status_t psa_wrap_key(psa_key_id_t wrapping_key, psa_algorithm_t alg, psa_key_id_t key, uint8_t * data, size_t data_size, size_t * data_length);
Parameters
wrapping_keyIdentifier of the key to use for the wrapping operation. It must permit the usage
PSA_KEY_USAGE_WRAP.algThe key-wrapping algorithm: a value of type
psa_algorithm_tsuch thatPSA_ALG_IS_KEY_WRAP(alg)is true.keyIdentifier of the key to wrap. It must permit the usage
PSA_KEY_USAGE_EXPORT.dataBuffer where the wrapped key data is to be written.
data_sizeSize of the
databuffer in bytes. This must be appropriate for the key:The required output size is
PSA_WRAP_KEY_OUTPUT_SIZE(wrap_key_type,alg,type,bits), wherewrap_key_typeis the type of the wrapping key,algis the key-wrapping algorithm,typeis the type of the key being wrapped, andbitsis the bit-size of the key being wrapped.PSA_WRAP_KEY_PAIR_MAX_SIZEevaluates to the maximum wrapped output size of any supported key pair, in any supported combination of key-wrapping algorithm and wrapping-key type.This API defines no maximum size for wrapped symmetric keys. Arbitrarily large data items can be stored in the key store, for example certificates that correspond to a stored private key or input material for key derivation.
data_lengthOn success, the number of bytes that make up the wrapped key data.
Returns: psa_status_t
PSA_SUCCESSSuccess. The first
(*data_length)bytes ofdatacontain the wrapped key.PSA_ERROR_BAD_STATEThe library requires initializing by a call to
psa_crypto_init().PSA_ERROR_INVALID_HANDLEThe following conditions can result in this error:
wrapping_keyis not a valid key identifier.keyis not a valid key identifier.
PSA_ERROR_NOT_PERMITTEDThe following conditions can result in this error:
The wrapping key does not have the
PSA_KEY_USAGE_WRAPflag, or it does not permit the requested algorithm.The key to be wrapped does not have the
PSA_KEY_USAGE_EXPORTflag.
PSA_ERROR_BUFFER_TOO_SMALLThe size of the
databuffer is too small.PSA_WRAP_KEY_OUTPUT_SIZE()orPSA_WRAP_KEY_PAIR_MAX_SIZEcan be used to determine a sufficient buffer size.PSA_ERROR_INVALID_ARGUMENTThe following conditions can result in this error:
algis not a key-wrapping algorithm.wrapping_keyis not compatible withalg.keyhas a size that is not valid foralg.
PSA_ERROR_NOT_SUPPORTEDThe following conditions can result in this error:
algis not supported or is not a key-wrapping algorithm.wrapping_keyis not supported for use withalg.The storage location of
keydoes not support export of the key.The implementation does not support export of keys with the type of
key.
PSA_ERROR_INSUFFICIENT_MEMORYPSA_ERROR_COMMUNICATION_FAILUREPSA_ERROR_CORRUPTION_DETECTEDPSA_ERROR_STORAGE_FAILUREPSA_ERROR_DATA_CORRUPTPSA_ERROR_DATA_INVALID
Description
Wrap a key from the key store into a data buffer using a specified key-wrapping algorithm and key-wrapping key.
On success, the output contains the wrapped key value.
The policy of the key to be wrapped must have the usage flag PSA_KEY_USAGE_EXPORT set.
The output of this function can be passed to psa_unwrap_key(), specifying the same algorithm and wrapping key, with the same attributes as key, to create an equivalent key object.
Note
A call to psa_wrap_key() first evaluates the key data for key, as if psa_export_key() is called, but retaining the key data within the cryptoprocessor.
If this succeeds, the encryption procedure associated with the key-wrapping algorithm alg, using the wrapping_key key, is applied to the key data.
The resulting ciphertext is then returned.
10.7.3 Support macros¶
PSA_WRAP_KEY_OUTPUT_SIZE (macro)¶
Sufficient output buffer size for psa_wrap_key().
Added in version 1.4.
#define PSA_WRAP_KEY_OUTPUT_SIZE(wrap_key_type, alg, key_type, key_bits) \ /* implementation-defined value */
Parameters
wrap_key_typeA supported key-wrapping key type.
algA supported key-wrapping algorithm.
key_typeA supported key type.
key_bitsThe size of the key in bits.
Returns
If the parameters are valid and supported, return a buffer size in bytes that guarantees that psa_wrap_key() will not fail with PSA_ERROR_BUFFER_TOO_SMALL. If the parameters are a valid combination that is not supported by the implementation, this macro must return either a sensible size or 0. If the parameters are not valid, the return value is unspecified.
Description
See also PSA_WRAP_KEY_PAIR_MAX_SIZE.
PSA_WRAP_KEY_PAIR_MAX_SIZE (macro)¶
Sufficient buffer size for wrapping any asymmetric key pair.
Added in version 1.4.
#define PSA_WRAP_KEY_PAIR_MAX_SIZE /* implementation-defined value */
This value must be a sufficient buffer size when calling psa_wrap_key() to export any asymmetric key pair that is supported by the implementation, regardless of the exact key type and key size.
See also PSA_WRAP_KEY_OUTPUT_SIZE().