silk.crypto.aes_wrap.
Wrap keys with the AES key wrap algorithms of RFC 3394 and RFC 5649 (NIST SP 800-38F KW, KWP).
When to use#
Use AesKeyWrap to encrypt one key under another where a format names AES key wrap, such as
CMS, JOSE A128KW, or Node's id-aes128-wrap and id-aes128-wrap-pad.
Details#
The key-encryption key is 16, 24, or 32 bytes. AesKeyWrap.wrap takes a multiple of 8 bytes,
at least 16, and adds 8 bytes. AesKeyWrap.wrapPadded takes any nonzero length, pads it to a
multiple of 8, and adds 8 bytes. Unwrapping checks the integrity value, so a wrong key or a
changed input fails. The IV is 8 bytes for KW and 4 bytes for KWP; AesKeyWrap.defaultIv and
AesKeyWrap.defaultPaddedIv return the RFC values. Nothing allocates.
Errors#
The functions return an AesKeyWrapError. The checks on lengths come before the first write.
Unwrapping works in the output buffer, and on IntegrityCheckFailed it sets the bytes it used
back to zero.
Examples#
Wrap and unwrap a key#
import silk.crypto.aes_wrap { AesKeyWrap, AesKeyWrapError }
import silk.core.result { Result }
pub fn main() -> i32 {
let kek: [u8; 16] = [1; 16]
let secret: [u8; 16] = [2; 16]
let iv = AesKeyWrap.defaultIv()
let mut wrapped: [u8; 24] = [0; 24]
if let Result.Failure { error: _ } = AesKeyWrap.wrap(&kek, &iv, &secret, &mut wrapped) { return 1 }
let mut unwrapped: [u8; 16] = [0; 16]
return match AesKeyWrap.unwrap(&kek, &iv, &wrapped, &mut unwrapped) {
Result<usize, AesKeyWrapError>.Success { value } => if value == 16 && unwrapped[0] == 2 { 0 } else { 1 }
Result<usize, AesKeyWrapError>.Failure { error: _ } => 1
}
}Import as AesKeyWrap with import silk.crypto.aes_wrap { AesKeyWrap }.
Public declarations: 2.
AesKeyWrapError#
pub enum AesKeyWrapErrorThe reason that a key wrap call was rejected. The checks run in the order of the variants.
InvalidKeyLength#
InvalidKeyLengthThe key-encryption key is not 16, 24, or 32 bytes.
InvalidIvLength#
InvalidIvLengthThe IV is not 8 bytes (KW) or 4 bytes (KWP).
InvalidInputLength#
InvalidInputLengthThe input length is not one that the algorithm takes.
OutputTooSmall#
OutputTooSmallThe output is shorter than the bytes the call writes.
IntegrityCheckFailed#
IntegrityCheckFailedThe unwrapped integrity value does not match: the key is wrong or the input was changed.
Implementation Debug for AesKeyWrapError#
impl Debug for AesKeyWrapErrorOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the name of the variant, such as InvalidKeyLength.
AesKeyWrap#
pub struct AesKeyWrapFunctions that wrap and unwrap keys with AES (RFC 3394 KW and RFC 5649 KWP).
Details#
The key-encryption key is 16, 24, or 32 bytes. Wrapping adds 8 bytes. Nothing allocates.
Implementation AesKeyWrap#
impl AesKeyWrapAssociated function defaultIv#
pub fn defaultIv() -> [u8; 8]Returns the default KW IV of RFC 3394, A6A6A6A6A6A6A6A6.
Associated function defaultPaddedIv#
pub fn defaultPaddedIv() -> [u8; 4]Returns the default KWP IV of RFC 5649, A65959A6.
Associated function wrap#
pub fn wrap(key: &[u8], iv: &[u8], input: &[u8], output: &mut [u8]) -> Result<usize, AesKeyWrapError>Wraps input (a multiple of 8 bytes, at least 16) under key with the 8-byte iv into the
first input.length + 8 bytes of output, and returns that length.
Errors#
InvalidKeyLengthifkeyis not 16, 24, or 32 bytes.InvalidIvLengthifivis not 8 bytes.InvalidInputLengthifinputis shorter than 16 bytes or not a multiple of 8.OutputTooSmallifoutputis shorter thaninput.length + 8.
Associated function unwrap#
pub fn unwrap(key: &[u8], iv: &[u8], input: &[u8], output: &mut [u8]) -> Result<usize, AesKeyWrapError>Unwraps input (a multiple of 8 bytes, at least 24) under key, checks it against the
8-byte iv, writes the key to the first input.length - 8 bytes of output, and returns
that length.
Errors#
InvalidKeyLengthifkeyis not 16, 24, or 32 bytes.InvalidIvLengthifivis not 8 bytes.InvalidInputLengthifinputis shorter than 24 bytes or not a multiple of 8.OutputTooSmallifoutputis shorter thaninput.length - 8.IntegrityCheckFailedif the integrity value is notiv. The written bytes are zero.
Associated function wrapPadded#
pub fn wrapPadded(key: &[u8], iv: &[u8], input: &[u8], output: &mut [u8]) -> Result<usize, AesKeyWrapError>Pads input (1 byte or more) to a multiple of 8, wraps it under key with the 4-byte iv
into output, and returns the wrapped length, which is the padded length plus 8.
Errors#
InvalidKeyLengthifkeyis not 16, 24, or 32 bytes.InvalidIvLengthifivis not 4 bytes.InvalidInputLengthifinputis empty or longer than 2^32 - 1 bytes.OutputTooSmallifoutputis shorter than the wrapped length.
Associated function unwrapPadded#
pub fn unwrapPadded(key: &[u8], iv: &[u8], input: &[u8], output: &mut [u8]) -> Result<usize, AesKeyWrapError>Unwraps input (a multiple of 8 bytes, at least 16) under key, checks the 4-byte iv,
the length, and the padding, writes the key to output, and returns its length.
Errors#
InvalidKeyLengthifkeyis not 16, 24, or 32 bytes.InvalidIvLengthifivis not 4 bytes.InvalidInputLengthifinputis shorter than 16 bytes or not a multiple of 8.OutputTooSmallifoutputis shorter thaninput.length - 8, the padded length.IntegrityCheckFailedif the IV, length, or padding is wrong. The bytes it used are zero.
Category: Cryptography.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2, x86_64-pc-windows-msvc, wasm64-unknown-unknown.