# AES Key Wrapping

NIST specifies two mechanisms for wrapping (encrypting) symmetric keys using another key. The first (and older, more widely supported) method requires the input be a multiple of 8 bytes long. The other allows any length input, though only up to 2**32 bytes.

These algorithms are described in NIST SP 800-38F, and RFCs 3394 and 5649.

This API, defined in `nist_keywrap.h`, first became available in version 2.4.0

These functions take an arbitrary 128-bit block cipher object, which must already have been keyed with the key encryption key. NIST only allows these functions with AES, but any 128-bit cipher will do and some other implementations (such as in OpenSSL) do also allow other ciphers. Use AES for best interop.

std::vector<uint8_t> `nist_key_wrap`(const uint8_t input[], size_t input_len, const BlockCipher &bc)

  This performs KW (key wrap) mode. The input must be a multiple of 8 bytes long.

secure_vector<uint8_t> `nist_key_unwrap`(const uint8_t input[], size_t input_len, const BlockCipher &bc)

  This unwraps the result of nist_key_wrap, or throw Invalid_Authentication_Tag on error.

std::vector<uint8_t> `nist_key_wrap_padded`(const uint8_t input[], size_t input_len, const BlockCipher &bc)

  This performs KWP (key wrap with padding) mode. The input can be any length.

secure_vector<uint8_t> `nist_key_unwrap_padded`(const uint8_t input[], size_t input_len, const BlockCipher &bc)

  This unwraps the result of nist_key_wrap_padded, or throws Invalid_Authentication_Tag on error.

## RFC 3394 Interface

This is an older interface that was first available (with slight changes) in 1.10, and available in its current form since 2.0 release. It uses a 128-bit, 192-bit, or 256-bit key to encrypt an input key. AES is always used. The input must be a multiple of 8 bytes; if not an exception is thrown.

This interface is defined in `rfc3394.h`.

secure_vector<uint8_t> `rfc3394_keywrap`(const secure_vector<uint8_t> &key, const SymmetricKey &kek)

  Wrap the input key using kek (the key encryption key), and return the result. It will be 8 bytes longer than the input key.

secure_vector<uint8_t> `rfc3394_keyunwrap`(const secure_vector<uint8_t> &key, const SymmetricKey &kek)

  Unwrap a key wrapped with rfc3394_keywrap.