# `Cmsex.KeyWrap`
[🔗](https://github.com/openspb/cmsex/blob/v0.1.0/lib/cmsex/key_wrap.ex#L1)

The AES key wrap of RFC 3394, and AES key wrap with padding of RFC 5649.

CMS uses them to encrypt a content-encryption key with another key: the
key-encryption key of a KEKRecipientInfo, or the key that a
KeyAgreeRecipientInfo derives. They are written in Elixir over the AES
block cipher of `:crypto`.

The key-encryption key is 16, 24 or 32 bytes (AES-128, AES-192 or
AES-256). `wrap/2` takes key data of 16 bytes or more, in multiples of
8; `wrap_with_padding/2` takes any length from 1 byte. Unwrapping checks
the integrity value and returns `:error` when it does not match, which
happens with a wrong key-encryption key as well as with a changed
ciphertext; nothing tells the two apart.

    iex> kek = Base.decode16!("000102030405060708090A0B0C0D0E0F")
    iex> key = Base.decode16!("00112233445566778899AABBCCDDEEFF")
    iex> wrapped = Cmsex.KeyWrap.wrap(kek, key)
    iex> Base.encode16(wrapped)
    "1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5"
    iex> Cmsex.KeyWrap.unwrap(kek, wrapped)
    {:ok, key}

# `unwrap`

```elixir
@spec unwrap(binary(), binary()) :: {:ok, binary()} | :error
```

Unwraps `wrapped` with `kek` (RFC 3394, 2.2.2). Returns `:error` when the
integrity value does not match, or the ciphertext is not 24 bytes or
more in multiples of 8.

# `unwrap_with_padding`

```elixir
@spec unwrap_with_padding(binary(), binary()) :: {:ok, binary()} | :error
```

Unwraps `wrapped` with `kek` (RFC 5649, 4.2). Returns `:error` when the
integrity value or the padding does not check, or the ciphertext is not
16 bytes or more in multiples of 8.

# `wrap`

```elixir
@spec wrap(binary(), binary()) :: binary()
```

Wraps `key` with `kek` (RFC 3394, 2.2.1, with the default initial
value). Raises ArgumentError for a key-encryption key that is not an AES
key, or key data that is shorter than 16 bytes or not a multiple of 8.

# `wrap_with_padding`

```elixir
@spec wrap_with_padding(binary(), binary()) :: binary()
```

Wraps `key`, of any length from 1 byte, with `kek` (RFC 5649, 4.1).
Raises ArgumentError for a key-encryption key that is not an AES key, or
empty key data.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
