gose/cose/encrypt

COSE_Encrypt multi-recipient encryption and decryption (RFC 9052).

Example

import gose/algorithm
import gose/cose/encrypt
import gose/key

let k = key.generate_enc_key(algorithm.AesGcm(algorithm.Aes128))
let plaintext = <<"hello COSE":utf8>>

let assert Ok(message) = encrypt.new(algorithm.AesGcm(algorithm.Aes128))
let assert Ok(r) = encrypt.new_aes_kw_recipient(algorithm.Aes128, key: k)
let message = encrypt.add_recipient(message, r)
let assert Ok(encrypted) = encrypt.encrypt(message, plaintext)

let data = encrypt.serialize(encrypted)
let assert Ok(parsed) = encrypt.parse(data)
let assert Ok(decryptor) =
  encrypt.decryptor(
    algorithm.AesKeyWrap(algorithm.AesKw, algorithm.Aes128),
    algorithm.AesGcm(algorithm.Aes128),
    keys: [k],
  )
let assert Ok(decrypted) = encrypt.decrypt(decryptor, parsed)

Types

Recipient family phantom: AES Key Wrap.

pub type AesKw

A decryptor pinned to expected key encryption and content encryption algorithms.

pub opaque type Decryptor

Recipient family phantom: direct shared secret.

pub type Direct

Recipient family phantom: ECDH-ES (direct or with AES-KW).

pub type EcdhEs

ECDH-ES direct key agreement variant, distinguishing the HKDF hash used in COSE key derivation.

JOSE always uses Concat KDF with SHA-256 for ECDH-ES, so this distinction only exists in COSE.

pub type EcdhEsDirectVariant {
  EcdhEsHkdf256
  EcdhEsHkdf512
}

Constructors

  • EcdhEsHkdf256

    ECDH-ES + HKDF-256 (COSE algorithm -25)

  • EcdhEsHkdf512

    ECDH-ES + HKDF-512 (COSE algorithm -26)

A COSE_Encrypt message parameterized by encryption state.

pub opaque type Encrypt(state)

Phantom type for a COSE_Encrypt message that has been encrypted or parsed.

pub type Encrypted

A per-recipient builder parameterized by the recipient algorithm family.

pub opaque type Recipient(family)

Recipient family phantom: RSA-OAEP.

pub type Rsa

Phantom type for a COSE_Encrypt message that has not yet been encrypted.

pub type Unencrypted

Values

pub fn add_recipient(
  message: Encrypt(Unencrypted),
  recipient: Recipient(family),
) -> Encrypt(Unencrypted)

Add a built recipient to the message.

pub fn content_type(
  message: Encrypt(Encrypted),
) -> Result(cose.ContentType, gose.GoseError)

Extract the content type from the message headers.

pub fn critical(
  message: Encrypt(Encrypted),
) -> Result(List(Int), gose.GoseError)

Extract the critical header labels from the message headers.

pub fn decrypt(
  decryptor: Decryptor,
  message: Encrypt(Encrypted),
) -> Result(BitArray, gose.GoseError)

Decrypt a COSE_Encrypt message.

pub fn decrypt_with_aad(
  decryptor: Decryptor,
  message message: Encrypt(Encrypted),
  aad aad: BitArray,
) -> Result(BitArray, gose.GoseError)

Decrypt with externally-supplied AAD.

pub fn decryptor(
  key_alg: algorithm.KeyEncryptionAlg,
  content_alg: algorithm.ContentAlg,
  keys keys: List(key.Key(BitArray)),
) -> Result(Decryptor, gose.GoseError)

Build a decryptor pinned to expected algorithms and keys.

For EcdhEs(EcdhEsDirect), use ecdh_es_direct_decryptor instead so the HKDF variant (HKDF-256 or HKDF-512) is chosen explicitly.

pub fn ecdh_es_direct_decryptor(
  variant: EcdhEsDirectVariant,
  content_alg: algorithm.ContentAlg,
  keys keys: List(key.Key(BitArray)),
) -> Result(Decryptor, gose.GoseError)

Build a decryptor for ECDH-ES direct with a specific HKDF variant.

Use this instead of decryptor when you need to decrypt messages encrypted with ECDH-ES+HKDF-512 (COSE algorithm -26).

pub fn encrypt(
  message: Encrypt(Unencrypted),
  plaintext plaintext: BitArray,
) -> Result(Encrypt(Encrypted), gose.GoseError)

Encrypt the plaintext for all added recipients.

Reads aad from the builder state set via with_aad.

pub fn kid(
  message: Encrypt(Encrypted),
) -> Result(BitArray, gose.GoseError)

Extract the key ID from the message headers.

pub fn new(
  enc: algorithm.ContentAlg,
) -> Result(Encrypt(Unencrypted), gose.GoseError)

Create a new COSE_Encrypt message with the given content encryption algorithm.

pub fn new_aes_kw_recipient(
  size: algorithm.AesKeySize,
  key key: key.Key(BitArray),
) -> Result(Recipient(AesKw), gose.GoseError)

Build an AES Key Wrap recipient.

pub fn new_direct_recipient(
  key key: key.Key(BitArray),
) -> Result(Recipient(Direct), gose.GoseError)

Build a direct-shared-secret recipient.

pub fn new_ecdh_es_aes_kw_recipient(
  size: algorithm.AesKeySize,
  key key: key.Key(BitArray),
) -> Result(Recipient(EcdhEs), gose.GoseError)

Build an ECDH-ES + AES-KW recipient.

pub fn new_ecdh_es_direct_recipient(
  variant: EcdhEsDirectVariant,
  key key: key.Key(BitArray),
) -> Result(Recipient(EcdhEs), gose.GoseError)

Build an ECDH-ES direct recipient with a specific HKDF variant.

pub fn new_rsa_recipient(
  rsa_alg: algorithm.RsaEncryptionAlg,
  key key: key.Key(BitArray),
) -> Result(Recipient(Rsa), gose.GoseError)

Build an RSA-OAEP recipient.

pub fn parse(
  data: BitArray,
) -> Result(Encrypt(Encrypted), gose.GoseError)

Decode a CBOR-encoded COSE_Encrypt message, accepting both tagged and untagged forms.

pub fn protected_headers(
  message: Encrypt(Encrypted),
) -> List(cose.Header)

Return the raw protected headers.

pub fn serialize(message: Encrypt(Encrypted)) -> BitArray

Encode an encrypted message as an untagged CBOR COSE_Encrypt array.

pub fn serialize_tagged(message: Encrypt(Encrypted)) -> BitArray

Encode an encrypted message as a CBOR-tagged (tag 96) COSE_Encrypt structure.

pub fn unprotected_headers(
  message: Encrypt(Encrypted),
) -> List(cose.Header)

Return the raw unprotected headers.

pub fn with_aad(
  message: Encrypt(Unencrypted),
  aad aad: BitArray,
) -> Encrypt(Unencrypted)

Set external additional authenticated data (AAD) for the encryption operation.

pub fn with_apu(
  r: Recipient(EcdhEs),
  apu: BitArray,
) -> Recipient(EcdhEs)

Set the PartyU identity (apu) for an ECDH-ES recipient.

pub fn with_apv(
  r: Recipient(EcdhEs),
  apv: BitArray,
) -> Recipient(EcdhEs)

Set the PartyV identity (apv) for an ECDH-ES recipient.

pub fn with_content_type(
  message: Encrypt(Unencrypted),
  ct ct: cose.ContentType,
) -> Encrypt(Unencrypted)

Add a content type to the protected headers.

RFC 9052 permits either bucket. Encrypted messages place it in protected so it is covered by the AEAD authentication.

pub fn with_critical(
  message: Encrypt(Unencrypted),
  labels: List(Int),
) -> Encrypt(Unencrypted)

Add critical header labels to the protected headers.

pub fn with_kid(
  message: Encrypt(Unencrypted),
  kid: BitArray,
) -> Encrypt(Unencrypted)

Add a key ID to the unprotected headers.

Search Document