CTR-mode encryption (EverCrypt_CTR.h)


Using encryption without a MAC is potentially dangerous. We recommend users stick with the AEAD API.


This API is a work-in-progress and is not fully verified. If you need it for something serious, let us know and we’ll prioritize.

  • It doesn’t multiplex across all implementations of Chacha
  • It doesn’t offer complete encryption, only block-by-block
  • It has no streaming API

This API is:

  • agile
  • multiplexing: portable C (Chacha); AESNI + CLMUL (AES128, AES256)
  • stateful

Possible values for the agility argument (Hacl_Spec.h) :

#define Spec_Agile_Cipher_AES128 0
#define Spec_Agile_Cipher_AES256 1
#define Spec_Agile_Cipher_CHACHA20 2

Supported values for the agility argument: all

State management

Clients are first expected to allocate persistent state via create_in, which stores the expanded key along with the current value of the counter.

  Spec_Agile_Cipher_cipher_alg a,
  EverCrypt_CTR_state_s **dst,
  uint8_t *k,
  uint8_t *iv,
  uint32_t iv_len,
  uint32_t c

The expected usage for create_in is similar to EverCrypt_AEAD_create_in, except arbitrary-length IVs are not supported; IV lengths must satisfy the nounce_bound predicate from Spec.Agile.CTR.fsti. Clients are also expected to pass the initial value of the counter.

State can be reset to a different IV and counter value using the init function. (This function really should be called reset.)

  EverCrypt_CTR_state_s *p,
  uint8_t *k,
  uint8_t *iv,
  uint32_t iv_len,
  uint32_t c

State must be called via free.

CTR mode of operation

The update_block function encrypts a block-sized piece of data using the CTR mode, and internally increments the state by one.

void EverCrypt_CTR_update_block(EverCrypt_CTR_state_s *p, uint8_t *dst, uint8_t *src);