Add AEADs for AES-CTR with HMAC-SHA256.

Change-Id: Id035d2c6ab9c6ae034326c313ffe35e0d035dec1
Reviewed-on: https://boringssl-review.googlesource.com/3911
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/cipher/aead_test.c b/crypto/cipher/aead_test.c
index 33e260a..833efa4 100644
--- a/crypto/cipher/aead_test.c
+++ b/crypto/cipher/aead_test.c
@@ -251,6 +251,10 @@
     aead = EVP_aead_aes_128_key_wrap();
   } else if (strcmp(argv[1], "aes-256-key-wrap") == 0) {
     aead = EVP_aead_aes_256_key_wrap();
+  } else if (strcmp(argv[1], "aes-128-ctr-hmac-sha256") == 0) {
+    aead = EVP_aead_aes_128_ctr_hmac_sha256();
+  } else if (strcmp(argv[1], "aes-256-ctr-hmac-sha256") == 0) {
+    aead = EVP_aead_aes_256_ctr_hmac_sha256();
   } else {
     fprintf(stderr, "Unknown AEAD: %s\n", argv[1]);
     return 2;
diff --git a/crypto/cipher/e_aes.c b/crypto/cipher/e_aes.c
index 47b8320..21f4065 100644
--- a/crypto/cipher/e_aes.c
+++ b/crypto/cipher/e_aes.c
@@ -57,8 +57,10 @@
 #include <openssl/modes.h>
 #include <openssl/obj.h>
 #include <openssl/rand.h>
+#include <openssl/sha.h>
 
 #include "internal.h"
+#include "../internal.h"
 #include "../modes/internal.h"
 
 #if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
@@ -1396,6 +1398,283 @@
 
 const EVP_AEAD *EVP_aead_aes_256_key_wrap(void) { return &aead_aes_256_key_wrap; }
 
+
+#define EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN SHA256_DIGEST_LENGTH
+#define EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN 12
+
+struct aead_aes_ctr_hmac_sha256_ctx {
+  union {
+    double align;
+    AES_KEY ks;
+  } ks;
+  ctr128_f ctr;
+  block128_f block;
+  SHA256_CTX inner_init_state;
+  SHA256_CTX outer_init_state;
+  uint8_t tag_len;
+};
+
+static void hmac_init(SHA256_CTX *out_inner, SHA256_CTX *out_outer,
+                      const uint8_t hmac_key[32]) {
+  static const size_t hmac_key_len = 32;
+  uint8_t block[SHA256_CBLOCK];
+  memcpy(block, hmac_key, hmac_key_len);
+  memset(block + hmac_key_len, 0x36, sizeof(block) - hmac_key_len);
+
+  unsigned i;
+  for (i = 0; i < hmac_key_len; i++) {
+    block[i] ^= 0x36;
+  }
+
+  SHA256_Init(out_inner);
+  SHA256_Update(out_inner, block, sizeof(block));
+
+  memset(block + hmac_key_len, 0x5c, sizeof(block) - hmac_key_len);
+  for (i = 0; i < hmac_key_len; i++) {
+    block[i] ^= (0x36 ^ 0x5c);
+  }
+
+  SHA256_Init(out_outer);
+  SHA256_Update(out_outer, block, sizeof(block));
+}
+
+static int aead_aes_ctr_hmac_sha256_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
+                                         size_t key_len, size_t tag_len) {
+  struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx;
+  static const size_t hmac_key_len = 32;
+
+  if (key_len < hmac_key_len) {
+    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
+                      CIPHER_R_BAD_KEY_LENGTH);
+    return 0; /* EVP_AEAD_CTX_init should catch this. */
+  }
+
+  const size_t aes_key_len = key_len - hmac_key_len;
+  if (aes_key_len != 16 && aes_key_len != 32) {
+    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
+                      CIPHER_R_BAD_KEY_LENGTH);
+    return 0; /* EVP_AEAD_CTX_init should catch this. */
+  }
+
+  if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) {
+    tag_len = EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN;
+  }
+
+  if (tag_len > EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN) {
+    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
+                      CIPHER_R_TAG_TOO_LARGE);
+    return 0;
+  }
+
+  aes_ctx = OPENSSL_malloc(sizeof(struct aead_aes_ctr_hmac_sha256_ctx));
+  if (aes_ctx == NULL) {
+    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
+                      ERR_R_MALLOC_FAILURE);
+    return 0;
+  }
+
+  aes_ctx->ctr =
+      aes_ctr_set_key(&aes_ctx->ks.ks, NULL, &aes_ctx->block, key, aes_key_len);
+  aes_ctx->tag_len = tag_len;
+  hmac_init(&aes_ctx->inner_init_state, &aes_ctx->outer_init_state,
+            key + aes_key_len);
+
+  ctx->aead_state = aes_ctx;
+
+  return 1;
+}
+
+static void aead_aes_ctr_hmac_sha256_cleanup(EVP_AEAD_CTX *ctx) {
+  struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx = ctx->aead_state;
+  OPENSSL_cleanse(aes_ctx, sizeof(struct aead_aes_ctr_hmac_sha256_ctx));
+  OPENSSL_free(aes_ctx);
+}
+
+static void hmac_update_uint64(SHA256_CTX *sha256, uint64_t value) {
+  unsigned i;
+  uint8_t bytes[8];
+
+  for (i = 0; i < sizeof(bytes); i++) {
+    bytes[i] = value & 0xff;
+    value >>= 8;
+  }
+  SHA256_Update(sha256, bytes, sizeof(bytes));
+}
+
+static void hmac_calculate(uint8_t out[SHA256_DIGEST_LENGTH],
+                           const SHA256_CTX *inner_init_state,
+                           const SHA256_CTX *outer_init_state,
+                           const uint8_t *ad, size_t ad_len,
+                           const uint8_t *nonce, const uint8_t *ciphertext,
+                           size_t ciphertext_len) {
+  SHA256_CTX sha256;
+  memcpy(&sha256, inner_init_state, sizeof(sha256));
+  hmac_update_uint64(&sha256, ad_len);
+  hmac_update_uint64(&sha256, ciphertext_len);
+  SHA256_Update(&sha256, nonce, EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN);
+  SHA256_Update(&sha256, ad, ad_len);
+
+  /* Pad with zeros to the end of the SHA-256 block. */
+  const unsigned num_padding =
+      (SHA256_CBLOCK - ((sizeof(uint64_t)*2 +
+                         EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN + ad_len) %
+                        SHA256_CBLOCK)) %
+      SHA256_CBLOCK;
+  uint8_t padding[SHA256_CBLOCK];
+  memset(padding, 0, num_padding);
+  SHA256_Update(&sha256, padding, num_padding);
+
+  SHA256_Update(&sha256, ciphertext, ciphertext_len);
+
+  uint8_t inner_digest[SHA256_DIGEST_LENGTH];
+  SHA256_Final(inner_digest, &sha256);
+
+  memcpy(&sha256, outer_init_state, sizeof(sha256));
+  SHA256_Update(&sha256, inner_digest, sizeof(inner_digest));
+  SHA256_Final(out, &sha256);
+}
+
+static void aead_aes_ctr_hmac_sha256_crypt(
+    const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx, uint8_t *out,
+    const uint8_t *in, size_t len, const uint8_t *nonce) {
+  /* Since the AEAD operation is one-shot, keeping a buffer of unused keystream
+   * bytes is pointless. However, |CRYPTO_ctr128_encrypt| requires it. */
+  uint8_t partial_block_buffer[AES_BLOCK_SIZE];
+  unsigned partial_block_offset = 0;
+  memset(partial_block_buffer, 0, sizeof(partial_block_buffer));
+
+  uint8_t counter[AES_BLOCK_SIZE];
+  memcpy(counter, nonce, EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN);
+  memset(counter + EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN, 0, 4);
+
+  if (aes_ctx->ctr) {
+    CRYPTO_ctr128_encrypt_ctr32(in, out, len, &aes_ctx->ks.ks, counter,
+                                partial_block_buffer, &partial_block_offset,
+                                aes_ctx->ctr);
+  } else {
+    CRYPTO_ctr128_encrypt(in, out, len, &aes_ctx->ks.ks, counter,
+                          partial_block_buffer, &partial_block_offset,
+                          aes_ctx->block);
+  }
+}
+
+static int aead_aes_ctr_hmac_sha256_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
+                                         size_t *out_len, size_t max_out_len,
+                                         const uint8_t *nonce, size_t nonce_len,
+                                         const uint8_t *in, size_t in_len,
+                                         const uint8_t *ad, size_t ad_len) {
+  const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx = ctx->aead_state;
+  const uint64_t in_len_64 = in_len;
+
+  if (in_len + aes_ctx->tag_len < in_len ||
+      /* This input is so large it would overflow the 32-bit block counter. */
+      in_len_64 >= (OPENSSL_U64(1) << 32) * AES_BLOCK_SIZE) {
+    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_seal,
+                      CIPHER_R_TOO_LARGE);
+    return 0;
+  }
+
+  if (max_out_len < in_len + aes_ctx->tag_len) {
+    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_seal,
+                      CIPHER_R_BUFFER_TOO_SMALL);
+    return 0;
+  }
+
+  if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) {
+    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_seal,
+                      CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+    return 0;
+  }
+
+  aead_aes_ctr_hmac_sha256_crypt(aes_ctx, out, in, in_len, nonce);
+
+  uint8_t hmac_result[SHA256_DIGEST_LENGTH];
+  hmac_calculate(hmac_result, &aes_ctx->inner_init_state,
+                 &aes_ctx->outer_init_state, ad, ad_len, nonce, out, in_len);
+  memcpy(out + in_len, hmac_result, aes_ctx->tag_len);
+  *out_len = in_len + aes_ctx->tag_len;
+
+  return 1;
+}
+
+static int aead_aes_ctr_hmac_sha256_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
+                                         size_t *out_len, size_t max_out_len,
+                                         const uint8_t *nonce, size_t nonce_len,
+                                         const uint8_t *in, size_t in_len,
+                                         const uint8_t *ad, size_t ad_len) {
+  const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx = ctx->aead_state;
+  size_t plaintext_len;
+
+  if (in_len < aes_ctx->tag_len) {
+    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
+                      CIPHER_R_BAD_DECRYPT);
+    return 0;
+  }
+
+  plaintext_len = in_len - aes_ctx->tag_len;
+
+  if (max_out_len < plaintext_len) {
+    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
+                      CIPHER_R_BUFFER_TOO_SMALL);
+    return 0;
+  }
+
+  if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) {
+    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
+                      CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+    return 0;
+  }
+
+  uint8_t hmac_result[SHA256_DIGEST_LENGTH];
+  hmac_calculate(hmac_result, &aes_ctx->inner_init_state,
+                 &aes_ctx->outer_init_state, ad, ad_len, nonce, in,
+                 plaintext_len);
+  if (CRYPTO_memcmp(hmac_result, in + plaintext_len, aes_ctx->tag_len) != 0) {
+    OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
+                      CIPHER_R_BAD_DECRYPT);
+    return 0;
+  }
+
+  aead_aes_ctr_hmac_sha256_crypt(aes_ctx, out, in, plaintext_len, nonce);
+
+  *out_len = plaintext_len;
+  return 1;
+}
+
+static const EVP_AEAD aead_aes_128_ctr_hmac_sha256 = {
+    16 /* AES key */ + 32 /* HMAC key */,
+    12,                                       /* nonce length */
+    EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN,     /* overhead */
+    EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN,     /* max tag length */
+
+    aead_aes_ctr_hmac_sha256_init,
+    NULL /* init_with_direction */,
+    aead_aes_ctr_hmac_sha256_cleanup,
+    aead_aes_ctr_hmac_sha256_seal,
+    aead_aes_ctr_hmac_sha256_open,
+};
+
+static const EVP_AEAD aead_aes_256_ctr_hmac_sha256 = {
+    32 /* AES key */ + 32 /* HMAC key */,
+    12,                                       /* nonce length */
+    EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN,     /* overhead */
+    EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN,     /* max tag length */
+
+    aead_aes_ctr_hmac_sha256_init,
+    NULL /* init_with_direction */,
+    aead_aes_ctr_hmac_sha256_cleanup,
+    aead_aes_ctr_hmac_sha256_seal,
+    aead_aes_ctr_hmac_sha256_open,
+};
+
+const EVP_AEAD *EVP_aead_aes_128_ctr_hmac_sha256(void) {
+  return &aead_aes_128_ctr_hmac_sha256;
+}
+
+const EVP_AEAD *EVP_aead_aes_256_ctr_hmac_sha256(void) {
+  return &aead_aes_256_ctr_hmac_sha256;
+}
+
 int EVP_has_aes_hardware(void) {
 #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
   return aesni_capable() && crypto_gcm_clmul_enabled();
diff --git a/crypto/cipher/test/aes_128_ctr_hmac_sha256.txt b/crypto/cipher/test/aes_128_ctr_hmac_sha256.txt
new file mode 100644
index 0000000..d4803a0
--- /dev/null
+++ b/crypto/cipher/test/aes_128_ctr_hmac_sha256.txt
@@ -0,0 +1,336 @@
+KEY: 067b841a2540cb467b75f2188f5da4b5aeb7e0e44582a2b668b5b1ff39e21c4e65745470fb1be1aa909c62fabcf0e6ac
+NONCE: 10e0ecb00da5345127407150
+IN: 
+AD: 
+CT: 
+TAG: a82a891565e466957ad5a499d45b579d31acaf582f54d518f8f9c128936dac4c
+
+KEY: c9d9ef2c808c3f8b22f659c12147104b08cec2390a84f0c4b887ca4c247c8c9dd45e72f48b30b67a8545750387232344
+NONCE: 58bddf96158a3a588bf3ec05
+IN: 
+AD: 5d
+CT: 
+TAG: 3580c1601d1c9a5b1595d3dee35b0cd9e1b115d8b0abee557b2c207b8d0df5ee
+
+KEY: f755dc6786e21f39b595389a51d36673e1ffb94ffc066c03873eb31839be6fa319fd31c8bea29f03ff28831861e60b6e
+NONCE: bd6c80797f1f4c563b06fd3b
+IN: 
+AD: 78d88005136e312639572343a2d0daf7483d8235291ee3ac002469456b075243dc03380c387030d546c2b1
+CT: 
+TAG: dede80d810fc449a769c79a5ecd2c0d68e9e0fae567781e623ab2098c88d8a86
+
+KEY: 43a0a28fef8b89b8fb0f76de01d802935ad561e27ca9c9fa629347be676a6af758501b6a652f369045da5fef751b56bb
+NONCE: 0f6472f1e589c16ca5ad45b2
+IN: 
+AD: 78e4eafccfc87631f0314c442ba4c07bca36f996a5b3408f9e445d6009a87ded16b33a4af9537a4619cab70d
+CT: 
+TAG: 11fa62dd8374aabe728ebf7e9aa1c02cf8f2dbc29f9aaf1940313f0b7c3e0301
+
+KEY: acf8e5f1bd64e6289370650b5b3fd773320025c8b229fd335d9461768cd0a17b4bcc946919932efdc9fc84a7f50768bf
+NONCE: 1aecfc90d28bcdcc5a8e3578
+IN: 
+AD: 6daedbdc69133b56f6a8f098f9f70cdb7e129e51115df385a6d86204a53412cd999cf2e69f45e168efed4742b6
+CT: 
+TAG: fbe0511ba0ec5709def9966a9b05facf171cddd81ee2cd56e7afc867af465f31
+
+KEY: 2773c92e6cddc9a5e5dcaf3893080fd2153f009d807df0b175c76615645f2087539e299d8411b27badb749a9845c5e29
+NONCE: 6d04ed129299651aec0465f8
+IN: 
+AD: 44219577e361a7a4681172d120a2d653a53ec74bc487ccde4954835943bca413d55c65dc665310148654d8c1e2e6bc2f06ec344473120ad1f95739b993a57f9ec0b3299cc088f385894fff876fc2ce8ce6b77ca253f177ba615101e84e17ad0e60704cff195dcd50eb48c77de409797e0b1c8c4c5b9215a4a0399954a008267b
+CT: 
+TAG: 6ab61ac4493e58e48d071d994a000f1c1f498d22f83c8d2af56b03c155afc57e
+
+KEY: 23189bf23bc4b734410d1c7ae321c42e144a25347a8029bb925e3d8ac1b92f4eb97227c1dece86ae9dea7d127eb33f9b
+NONCE: 30681944cd5d78f46d36ed8a
+IN: 59
+AD: 
+CT: 92
+TAG: 986aa8438da3cf4a98f478f90d24908c6a4e848f299873e649b256f5499d89d9
+
+KEY: 463d1148325c5f57af670877068a78203571b8b19f40e9f0373156b7448ab315df86c77d7c85ba6e54b9bc329399f687
+NONCE: cc9d015a4b5a888b36b14d05
+IN: 28
+AD: 6a
+CT: 05
+TAG: f66e8dc794b142944fa46d5c04a3e3fe00291668374846d763f2beeffd4ca4a0
+
+KEY: 937eaab44e7c7d2cd5bbb053c12e6255e0aaa42cbe7d83025b7a2887eff8f098d019c80af849b0ed7da54a5ba5b39200
+NONCE: 2b160d24df579836e1572ea2
+IN: 9a
+AD: 35841a33ba3a6ed3d89a1f76d06c61613d09834847e5a41f8616748e30c14335e5baa43d49fceaf85aeb22
+CT: 80
+TAG: 5e5799c147be0329dbcabf7ecdba6ac595ebc2d06b9d757426fbb31e8b39f62a
+
+KEY: 68a746f382fcc11c02af7b352b9d710c137a9f59bc5886dc374ca88cdc01b86fe5678fde16cfa846846539f67a429276
+NONCE: b94346c033ac1a3d709c4f09
+IN: ad
+AD: ad61c9168debf9974e19759088944e888346aff99f3e2e4522549c8ae332a0f41922972fb7c1d5ff24e7ae4b
+CT: 46
+TAG: 62ae92ff64710a9f260da2562e246356e9d749c3584fb9f40d9572307ccbbd31
+
+KEY: 6622579d1d6350fd5dff432b69d172cc51f99bdaff50b0a1c0f4cda8d5904581ba8657ba61c6936407243d7fb64b00da
+NONCE: a880caa7157a13540d2b724f
+IN: 2a
+AD: 95a23eafcff892deecaf093109d30290d819851ad5c91061510e54baa2b039b114c815da20f0e3ba2ba4875bdd
+CT: ce
+TAG: 33f09666f9fd1d92f137d9f3f7092b47b2bd71a7e3139dcd19a803a6b17f2a3a
+
+KEY: 91ce9dd87c7d11d2c4da41863b6851c40fba786a612e0fbf0d1956a71286dfc61fa10bf7d148cecd72b6ceeb82b68d3f
+NONCE: a50dc3d8fd63d3076cc70ff6
+IN: da
+AD: 9ce8e1a777c159ec775abbd67d85e84f3550c3296e848dec18b61bbd713a98a033805bfe6e2f2a011dd7fd754708e524168142aeee579cae19c7eab78fa7c42fa335f0c725baf556160beef9e4afd1050a2c8813be6bd14cc6982116d0229d53e9b4de923abf6ba99bdffe1d5f21748ae74caddb077d9f7488b394436222beca
+CT: 2b
+TAG: 1541cd745bc0259dd72a212474f5c7b8c121dd0289d674e5ba8d56a220d1f1d0
+
+KEY: 1ad577d3b47e3fff8528e336a43a7ffef72f811e05b5c69ccfe777b10f29061e289178e394a1c87ba483c7f98ea5431d
+NONCE: 1fcaa4757a9e48ed2cb3be62
+IN: 46d30dac550103006c292a9ac05d31
+AD: 
+CT: 37616eba30c55595fa0ad5d50f91ca
+TAG: 5c3ac4010f75adf90f81e775b07ab939e7551a9b8e0486ba33766728ed498245
+
+KEY: 6df310dc1847b42c68e50b03d154b73d7f3823354b32759c5369bce1a1b4cd63ccdb911c2dc792acf84b8b8f3fdfb89d
+NONCE: 92e6759a31dd556ff9124d73
+IN: 6daba76658db642209e276ff7c8d46
+AD: 32
+CT: ce1814c03037078b6be3252460af48
+TAG: 46e61913f2a1ff6e77faade9a7cd37a82eff3ebec4276fbddff9266b9c9bd873
+
+KEY: f848c2300995f5c98dcd0db24574d7c61459ca64c084421c6ad156e80e398904417ee745245ddae91be20fb07e66bdb6
+NONCE: 3b177e11063445717f417d14
+IN: bbf225131c821a6a60817cc65bf699
+AD: 4c5ab4fdbe0018344629349feed5d8c3ae0c5b64f2b093576a2aaa1225e7a50eca01a9962c9b4f8fc5c12a
+CT: 1538957e78f3ab0fed77906153d715
+TAG: 2c7760d47407ad7b0d5b85fa4967eaa7b6c0bb6eb16619adde7a191abfdf3da3
+
+KEY: d406cac07630ce2c071732a0ec95f55123486d2677465768dc7db13f90902cf172f92e19f57f5cf7c68cd7bde7ee4b4b
+NONCE: 766aede0120b634a4be6fa12
+IN: 3804d40090a38d4c97a5fff631068c
+AD: 7707b7d0f266284e84c2ecdd5a18832650c3e27d66697616c9e9bb2f8a09a3295de0119582ca3614b9608548
+CT: 91e96462a5dfbe8b7af201158a36dc
+TAG: 56623e5813070a0e2f5184aed83b9863301ca02e3108f7afc478d48305e397f8
+
+KEY: 42bb22a317ed9f9df8119746e9a1257217e5b0144051ca56f39587021d969bc0acc02795f3bd201031e8c05af08ad079
+NONCE: 0a9f6bace71a1ab21f4917df
+IN: 013f7b8c75307158f4f300450e7a78
+AD: cd95a649ae215fe73442a6991e157232cbcabecff6042b87d41557e35b97606d606c3ded54f5d3db7aa2773f67
+CT: e588dbcecbdb7667dccf7fe34f8387
+TAG: b04461748109ed9068c7e9c0446528ef09b01613c3b3aa1ffeed6685ebb550f5
+
+KEY: e1cfcbaba3a04b5108ce2a87099a6aae936ee38acd92b7e6b7df0e3bcb9ad18fc579b5d470ef3e04c23459f509852458
+NONCE: 112dd267174bcd81e6fbd924
+IN: 288a1e44b406aebec7b418674f81e7
+AD: 7809d8011c5a963df14fb8981e874119c60b7a9d897d13a05651759db5835deffdd991fbf98b9aa71c79e48bd701b228ba248b6bed874b02da7fcf28a04c38b81c0ff628846015258af30dbf28ea4f3283f664f888fca545f5fc57dccc4ad1dd476c52fba341182ecf783706c5c458bf0ee5ec83454afba78eb8b5ca17af88ec
+CT: 80f4e1012d76f6180ca00fd32c8fec
+TAG: 6de00bf2fd3c88ab34ca9390f7e559875e43e0f938303816a3a75a35729bc453
+
+KEY: 84172547d8608bd9e788a7bb60df2982963716e45f8e63f0c5033327d85c920c5e3776e314246b1694b739c39abfa29f
+NONCE: a3f1643bb504b7ce9e5b43c2
+IN: 7e76323eb13e64da9b240a57c95c855b
+AD: 
+CT: 966487c18f025d67b42a04c30d3ff4c3
+TAG: 8bb03d893f0ce8ea4a6a47245bc7f20c72acf8caa466edd01365d0f74c929463
+
+KEY: 02dee8f2e63b37fe3cbae9101fed0946e05e5090510bef3324a82e3f27456a45ab1b6cdeddb1fe515ad07aefeee6ccbc
+NONCE: 64723d21365d62926d5c2262
+IN: 4f1f132c50a01ad48882ce88655b33f7
+AD: d8
+CT: b102082e14cd9ecc0895f7a6f08ab522
+TAG: 2c09651c1a51cb8a375746236fe258a36e725936ccedbc4dfafee6c3084a4716
+
+KEY: 5db57cf6301bab815d38879b35c9db72fd40ac576d259ad5074d0828364050554e9fc08335b5f2bf066b09e50fbe6ba4
+NONCE: 36e5340d844de213c312177a
+IN: 41a6e910b14388740ea351eb1df980c9
+AD: 8316a6b9b155b2de5e724f7593ecdcee442eaef7b9ad204eda4744a5e648c2dd84f48ee81397e485953465
+CT: ee21d4d47042415ca27d2ecb11b13d79
+TAG: 5015da5a3339389d39d0fcafb56ef4005b342e69ba47930e84408d33aadf5f2a
+
+KEY: a493dd6de6fd6584599096442dd9345f6f2d8fc2d426c78eee2b992b4071aba4ce463f3ca293c84b2faf3e8644b6ec25
+NONCE: 4f9be6f788ee960adc650d86
+IN: 4de6e244251091cf13762d20685e9085
+AD: d15da312b7522c18384acdbf6348b5e105557f1790a6a203a65acd73397524681666743f3145048775ad84e3
+CT: bb1296457daa39d889c8f986938d6a39
+TAG: b93548cea90c34d03d6f5683ae2cc78814531b803d42cfe57623fd4bdc8f084c
+
+KEY: 8cc59ebe2c7375a70915c48d2978a1f720bc0aa2775ce9189ae7b3d5dda9a81e56cde0e0a29939599409b71f0b65f346
+NONCE: b0ab041f37ea1e594f1eddb3
+IN: cd0aeaf6806cb99e6bc1c8c5d830de8c
+AD: 8f4b5a9609df757826dbe7e51bb6a2c6f45f601263cf668836193513cf008ab6b36a7d5447039f1268821ec37e
+CT: 5d5375b9d9cff6d0c1dbd14221509a0d
+TAG: d8850bbc838e068b817c24d018f8f1e1cb8aac0a68392a700f48099f81b6c37c
+
+KEY: f3e9c507478d3f99dbf3e2421e45929b096ab3f3d4aa4ef9c338c5a1a2425c9936b7df602502d33cbafcf781350da77e
+NONCE: d4872a30c9d1fa9001a25afe
+IN: 25e05ea69a956b12a9be4ef03ae9d30c
+AD: 8b346c20e7c64b805d9c8d325829201753069c60b3f221f31474f55cb20315373ccd7c2a8f215e9efc407ae91b05d8b6d693a3780fdd65d7715cdded86c3d6204055812f3fce897f829d1df9ffaaf48885291701ac1765090c383162dd13d6bac88baa0cb2d748363bbb79843a1594ec6d8778854a63b7c9ffeb6d1fb17e90f1
+CT: 61325c7e0d29e9ad50b9c0fec02d7ef4
+TAG: 4b2d0caece46ce2496445883c03234e900189c22b54390b399d78ee4ebfbb7d4
+
+KEY: 3d9b651e65e9239c9e33aafb091b348161ab797901fd0468aedd014e4d5683c8f3f54f20ea6bb07bb25dd258df7bcd5e
+NONCE: 32bcf856a14437114e7814cc
+IN: 08a667c2923f87a7db6502478d32280bdc
+AD: 
+CT: 5e8e02cc91c732356bb9f1fc599426a379
+TAG: 5449e878d558beff4bc7dfbb5f0195444705cfb259773b4faec524fbaca37ea0
+
+KEY: 2124cedb5f3f2558f8b9a2304a29c0df6102333cb4aa10625aa82cd76ab645c73f3b7cbf7c96cacdcb9e0b738e40c042
+NONCE: 7ae419446a3a105beb2fbcc5
+IN: a305dc4a2e50cc8e7a65a4b10b73849636
+AD: 70
+CT: fcaea620f7e9ed1337214c4b432d9869d2
+TAG: bfc739c8504a4d9033ab1915f46c1bf65c5382fe9ed1c134026ba32c63ca131e
+
+KEY: b027feb1aced8fb3af27a9fd7f531c30991ec1abd9f230a3e5d6ee9fc6a77747013f8e14dcdbd07b0083d0ce23dfa711
+NONCE: a30a6520f933ff5265e6e305
+IN: a705f842d542cb6957fbce21854755c6dc
+AD: 447bdaf34dfab9cc3dd7777ebaf80077f391093bac9817bf02ad98db9d3f271282ecaf0ff19652f92076d1
+CT: 3ddcb07c121b498f1abb73bedb527d4df4
+TAG: 55957a0e884dea22d6ace10e5936cdac891f5b54225349ede5c44715f1064b5e
+
+KEY: ffefb7770a7cf125395703985823f3e926f3722ca0764518fd2b8996577bec03648c8d542af1c6e36b51174b0ba88316
+NONCE: 4c31394b4b24f6251a839891
+IN: f026a1d352c37b204c6c1138abee9a9a75
+AD: 1e7c0f71a3aacd87ea785521ea31f93b1efd0bdf97952e0b84ecd50c706806deffc19caea312b5a9988454d2
+CT: 23c8bae37db93ed9f55f2903e04b7c6a8e
+TAG: 89d0a7e7d921dea5bb54c28e79b612688e42506aa69b141de830c8d63bdefcee
+
+KEY: 453cf5e4f48ce5a961c94af0e1639c156965970f561ac17fe08d5b75975abe3db87412640972e463290800666be80441
+NONCE: b3e3f9708a86c7cdf139e496
+IN: 53f1b11de497cc6ecb411a777dc3d60197
+AD: afe29e074dcce850ac6640230e6b9f66a64587c5fbe8679144e065d3b1700c721833ba8f918e926c9142f5f362
+CT: 15d5f597be46a19566a72c5e843b77f70c
+TAG: a561c3375c096a116a721e9404e555a2deaf3f677a8611694281663274708f58
+
+KEY: 3d497f81d0652d475bcd85cf53bda13f79ef0afeaec09dd679a6e5ea58f87ba6576269f836096d5ac034594b17073331
+NONCE: 3fb1664830821e2b524890c8
+IN: bd75c313f5c8f6007a2185bc39d0af01bb
+AD: 50744ed959e2b8ba5b5f4807e2997ea0b96ebfcdeaa1c6b33853219844592e82ad67abf6ccbb272cfdba6a3e45c07fec4d4a0ebe4235f11d916771a764d9a129d39f6b84f0b5fb4cdf789ca2f5ea306b25d047a9b1a1e2e90905b6fba472e70b2fa25c96602cfa0031f31c68954d7487507081b8e70f8aa1342cb8b4a98ce9c2
+CT: abe3869ac43fd8b429ee8b8539c970bc86
+TAG: 33fcd301c2bf624bccb92a986c2dd5f2ecafc32649ff550eb5312fc81cbce46e
+
+KEY: 353c3e9f87b40fc0281869c68d9d9bee5c95771dd79998c059bc5ceda71f139fe447cfdf340e9eac57f232b9d230e45d
+NONCE: cc7a4b46b02f4e7f96fd34e3
+IN: 44bcb61332930f606276268ddbf3287bcaedb5b25704489cbee63ec839d7a69533dbfb6e95fe5b4694eb485beb1437f0777774868ecf45c8a5b3edafa1d62a
+AD: 
+CT: d038d67b8b690519fafa7467c9fb94135f9bf0bcd8247cd2c30da62ddf37a6d9a3a9bdcf8ec081fb4469c0fc2798e2e30afede7cda384438fd01e5d672dcb8
+TAG: db2c685a59cdf304c1fb57b66966a5ca1cc3536fe21eb1113c25868428640c7d
+
+KEY: 3b3786e38e110ec0c8b05fbdb3d9b6d117d1ebcdc0e7d942249fea6baafa31fe5caac227979fc833b104641e8e9ed01e
+NONCE: 53bf31912a3ededc01c91f84
+IN: 6de5890028382aafb186042864c5cca1a77ff80ba4f7f0942dcffa1579711093fb652c8d475dfca81a976be8ca77eb9c7a6b49dca1425610c945bf404ba65b
+AD: a9
+CT: 886939354fa117139f5e077baa186825ee7e2955c3a74f88af3a86b260ee9f9959a90409e7d602e36cea31e606aeaa8b9229e28f7fa58ace6fd217e5cce1e7
+TAG: 91a769003ec900dbb40ea9c9b959882d822421b510ba85ca826bc4af3b5c42e0
+
+KEY: 5a75c97f3583983bbc5eee4a882b766a6708d798a46f71e63b7509af69afd7cf86f9b42df04b626940914007078a8b9b
+NONCE: 426e8bcbcffb6b425706dae0
+IN: c24fa29a66197cad518c5a1a76abd9446a8f24c2dd81e953bfc5c00544c119d67986781a1c754224af234b0ec5e44e78610a4420eb78c283e9a56637c35c24
+AD: 6376835513967e4ccaff9a0c56b4d27a2bd0d013cd54abf95fe9a162d036af285ebc9567a16ed5abfa69aa
+CT: bc4daeef3ccdf9abdaa75591781685eee3fd7825bfe63132817a7e0f93817f22bfca30ed775a773f5bb290aac3a381a01085e861cab7b9fe4c5143138e17a5
+TAG: 79c779bfcb974ad9a8ac88dce5027df5691a3a1163a5d5893b4cdb1663b17aa1
+
+KEY: d1b301c029fe3b81e4b97e08e84dbc03b138f422161c0e74ccbda3172c034b99610f09a9e611f0e9a3ca40af4fcb3c56
+NONCE: 4032c79eb3ee4b63e44fa932
+IN: 71bcf5a5198787b85a66221c22e7bdb9d038dd3e10000555ec9271e54bfefc460ef4e71729ff7ae52859015b49f45df89ddf183fe1e19de3acb032dbaa4d57
+AD: f1cd18ff1e5ad2b65de41e083b5175966625ebebb3031e1027761e407dae4e8e193ffe7dea52ff61147f1b4e
+CT: 7c521a703b7d1cbd086bdc316d4f2ff0852c462eeaa1d7a586c561354be9ed412d9d9bd1f78cc85468750f1af09b7b17dc1ee84c926760d63504cd3a1dfa3a
+TAG: 831f3552890d997f0a8f2d832b6e92e26f6e865424699f0364a82d86ab7734d0
+
+KEY: fdd24bf37b36666a4f641115581ab4bd6b896dd3017006031b3675beed33f21a314363e3a07bbbf4359d9ac02eec847f
+NONCE: 7767cff1a096a9f7d8a9b32c
+IN: e62b7695dd41baf49d1b356e64c6d5504784380b75724b86f5f3185d1a530664aea0e5f9aeef347e1ea4754acaa7f3c233638db234c0e93db02e0bf988e7ab
+AD: 2d650f3daed2564b0df86fa23ed0343634663adfae2c422f80f9d5674bbb63e824f01ad3994834f889133bbc0e
+CT: a51f50a6ce77a22ec472bc18c37d08fb28e77efe55065b600e3edbd9ac97f0fd0eec93cd312ec7ef886cb04e1849526f0a38b14d862bcd578b99bf9a007c2e
+TAG: 89d83264364c9c84ba705e5549abcd496abed3900f65e3daa012275fed18a7da
+
+KEY: 0f88e2d00d2c4bd682f1591ea5f4c1a1090180e1195809cb363b27c863360a85b27814e6a724effa44f298430d6c9628
+NONCE: 6e2e62ecb2aa47c7e5921d25
+IN: 91efc710a57adb57017725cfa26d17d3e2993c5ee66942ca42e770a83763e9df8a455bd408dc1e2661cf301f1dd669cd6d5b4d92a886be0f54527779bae8f9
+AD: d060cbe84271e85f25a3dcb6dbf299551f0dcd5783e3df80468636e491c0100f3ec8316f24240482a88bc430a398b0ecaee5c48a274ffb2d835e200bc39ec0aa86a1c90c9e2dcb4217595d48826a81de90eb949846a33fc26bf8886ca0554e1b8f12cbeee36e65e33cbbf610c2d24264619fa93c44c88e0e3d9d368fdece461b
+CT: 10d99b98ed67d85a44fa57e706a8b028c61ef17f35f6713613d158cad90e826f90ef036a2190ba123f9b68b352ca94fbebf8ea947e569ad45f00e6a36975f8
+TAG: e345bebcc4a8ac01528bc5f317e5c378236b292c2baab6ae8654245da35d90d6
+
+KEY: 1ccec52c77239bdf6ca50e5b702943b23015d08cb1d9bac592b3dec4c96be904110713e52e114a8bc294df26530a758a
+NONCE: 38554b7c40027afe9721e14a
+IN: dac91fcdb3768df8d5ae9ddba1fe5917c084a5d9e6b14eee9a609cab2da34ec9f95cf2d10fff77108477e694c76f362e29b9a9287d8b190a748ed0a929967ff8
+AD: 
+CT: e6bcb38b3bfd0b428a14bb3aca01a4a9e54b0853f10bd7750f5bb58d0e7dd18006f8929d7d862e5d6601ef63be8442334b4d51a99219cfedaa31f7ab19028459
+TAG: c4f05d9415840c2325dabbcd12dbeda31e47637437514c606dedfb8ce622edd0
+
+KEY: c82ad4c6f248bc51d3a51b958ecc2460a3c64d669f6c485c2309d26abb3fa84644a0d8c28da8091f90184b53cd556413
+NONCE: 35a29938fb7a31225b08d0e4
+IN: bb0045cec5587e50b148b140b6969612425243ed1412e812aa9f4b471ed34ced6dfa9e0acf3e31455893e4ee7e66b4661c6e1f80b7d6f1159c11387ce579b80f
+AD: 12
+CT: 5f1854fc2fb11fd721755445a1efa5a28607a725ad71cda9a3464860a6a0efe3f58727c0e0cd315f867611232abd72034dfc2b9deace8cf6cb507b1cd4032b59
+TAG: e40429ca19a88da73a7654d7ed8e0621ac2e504b0245615e262ac70bd05a3f47
+
+KEY: b01bec74fe97e5af7db2a0b1432f8b4c069447d2b56dc2668371387f753b03465412213999d2394a4b79873db06c590a
+NONCE: fec7de97d54dec8d36c9f253
+IN: 88ab078d03ffacd128edbceea7ace2e6465f4076097445a5db7f0e61ed817b6e24f22874489049bee0c58d0aa2b42b4db0bbef6ec88d032da9c82ebef57c424d
+AD: cf0ceb3e80a76d1a75f6e070f5d3fee1cd1e2699434f96e7cb3adce12d4a3148dd433b08c68b9d66962f24
+CT: 8aa3c7478b0cd86fa30870957fb5307345f89346a869d508da9d3a4fe36fb3d6a9b0c3c1bc2d44c8ea31ec028012098d6032085af0b54603dc2fa65ff091fdd6
+TAG: acb670172ec3754064b366566bdccf5056eae132e2041f1a285c5883e7eff4f3
+
+KEY: 699a94f6e6eb457b186af58c25118fcea81c8f0ad265e7c16bd6cdca15c9db64bb9a537580ca0474a4b4d54d47412d88
+NONCE: ac3fb6525f4357d831529407
+IN: a7300aa94f3d357cdb272f0a739979e08aad9551dd3bfcd0b5aca6a0972a71b502639e79e1b9e0d22db2f3220b982800d9cebbac3d10d9bf86ea25d3d417fc57
+AD: 19c3d34bb9d57d0f63f14bdd3da06a43a5afe6a8c505f038cb403515876a2765c2d61aa7e4c84e11c999b81d
+CT: 8b472f1069ace78172611369b03073f751e5206dcd2ce3b45c431095f303e70c59bfad3af8006e66e4a68f8fa2ffa534bd76bdef089d07dd38988cbf723393c6
+TAG: 8e7c3c2c41b1117928ca1cd0cd48c25c319c18e009804c007d1aab0967c0d0d4
+
+KEY: f3a7b8c2a39531d5fb3c97bc9224168aa835973f48243d6f046d00937ed428e5d672e22af26e734f0c24f989fe62621a
+NONCE: 65c61af60769672f0eeda005
+IN: 59667fceb2594e002c844a47d2b3935d2c99570b1639f0887fb082499e1d36f9699ff9ef53be3b4236136aa9e441abdc63dfe536e6fc9fa8f332baa1dad577ad
+AD: f79036742501f1ac19dbb2984e09cf5000bc4bc0424082376c307b8f1e5bf74dd29c802139d7ea93d55d336464
+CT: 9375a81f016c2dc59a8e99dc33fc0db7ef99ab2f9ade4b0ba000a614ff2bd13bfbee2d4a2338109c98c1147edca6023cea43570adc503da98379326ace89d796
+TAG: f563869420699dfa0aa84751526bd75af1473bd88311001e49230b09b8ef2797
+
+KEY: 27611a8f11cb57d08648ec816b5f3c45882dae394200cdfc803d1a52bb03f225206574ea63b63423da6972bf5a994332
+NONCE: a7f617fe7a52dd76ee443dff
+IN: d6ccb950515a4a2de7c3cf5a73b568f32fe30567bb22b3b46feb7ef07205d3215a3d689b96d4b9dbaac5a5bd6ecac6ba50314b19b37179fff2557c869950e162
+AD: 777282a98b2f262ed9456fed3610a2028bcc4433eb8f028597d3bfa220bdb0c04882de03a276d0191cd1a125270ce1630c1b94e2ec0021ce5c494d2e0bdb8745e6e94a387cbb31a0898965174bcff8bba105f94dbf080059b49dee71c3194fefe679ef6c00065154ea809293b088c0c3f2ed7824aac72319a4c4ad85ea990844
+CT: 41eacc31aa3c3a282ae7638d48fc7541d2f129e4cb3455df7e60259be9a814c8e1642ea826ac1ec7ed1fcc216a6624e79845521e7a8b16702566f27f7a7f3317
+TAG: b959992feb7005410f9ea6963525e3d9244f038731ffab8da8c4ebc72489f17a
+
+KEY: 0d9322713cd132c339c38ec7a75862860de304c70486b89b0f587095c66bfd1abe56f0b34f9ca0dac577fd4262616600
+NONCE: 3298d02dd4eb85a98cb935e3
+IN: 5dfedb1d168fe262d35f78d797560b2634f71d40f438c21cdcb8e73cf9884c11570554f55a6abd23d0e7775a9ab385ae6c9bbd67f08d1aec57347a8fad5a4b8c7b042b03c25facbffc76f0b1ce2e6c07d427eaebe71255d661ac8e8bfe8867e2d947d496ce2318a601d0beed02426311ca678d036deb3b4c65b1f89bd644a410
+AD: 
+CT: ff09fe27f12a87d5208bf246378ee0740e848262442b8b9c7670c8a73fe6732192cde43c1a1246743ed49e15ec63c87dc06eb3e0c92c1f286108b2c7e0754dcf1b9c3fc87efe3683289daabf2db71d8742061f93098788c3c6f26328b86e358507a03af296d2c29009562cad3763399e0e2b89ed440f756c16214c8ab7ddfb84
+TAG: 5076c80fc76c67d6e4f9b9d470cc184db62ea7da49cae44cb3ce9e46c2f2ca9e
+
+KEY: 2695671fe86f1658d8b01ec856fb4c9d09a0c51a1b994fc87a3f72bec12052537b7429f11f7eb4aef0b128302ec8f336
+NONCE: 9739e577595418c47b9c10b7
+IN: c723c39be334a0761db795076e81e3dd85e37a57258c7e0e10fe0f48dc31bd5e683430aa70531b7c8e3a904e49bec838e760d07afa9f86b2cf78ae90f612c4560632acb7ea2d89fb1fd5396d0337111c429cdba99c6a52e863e8603aac24a83302ebf86ae69a212cb938e12085cbf73a28f75e4422995a5ec8705b12d4aa8b6d
+AD: 31
+CT: 1569b20732ee6395e605217e1cb419ce57496ba6f6e889bdfa3c93575e969eb7a0410c7930b7ea146e88577376d84f0e824b62890eb84bfe768a1513a12c2958ad1835bc1eabe602cf40f7812c7dd7da955567242cd7512090fca685fdd7306bd98a908b09464961114abbdcd610c153637400a1f81825cfdf06505947fe54ee
+TAG: d07e14a62a32ef1933abc2127cc5bfc1e43bbca663e460409c6faa3a4ccf99f3
+
+KEY: 1785ef6e7016733dd1952b3268639f231e7afa973c0a3db8780b81084c67a1783200149a1ed849ca8b5c14c7b1798b4b
+NONCE: cdf48b73c3c8d8625e52fe11
+IN: 14002f17e056d7f5524537cee6c2061e2741c01a6f9a82e2cb1747887875860d51bebf8d9b63950a051f6b228ad7567227f8a45b9fa7c4ab47eab410125303defa7e3141bd9bc5bf4ed56550801ff3bfc2dfaaf499c192b1e18879b2f59e1230778132818df8f6ad8a3dce9a1d11c98075b8b4e560edd9b5ea180f0424ab3706
+AD: a35e86e22e9a3df65e4c08e5175b4216fa9895a1be6252de911cf98349841494617eefaa007759dad7f337
+CT: 99eae989435578cb57715a7457da31b807b8078a59c2332a0a866eee9da5188baed3f517b6808095f0067e9b4b91cc1424a464f0a09fc946adbe4135a17b0e8e545d2046f81cdfdb233aa3520797319c0884ccbade8235c32d195e7b802017f88ddd86fb630de19eb97f4bf91029c001fc8f1cd2189a8ee6c120e9f1682a8703
+TAG: 1848f0b163e7b0d270e2a0ced288ea6525697170aae15038f3dcbb4ea49ef843
+
+KEY: ba9aed2bfa90eaed9b27a697bb44c715c0209cae6b2c4ddffc684bcf07ab51b0e096dbcfa26c18fc24b63408317da567
+NONCE: 4b850d6bfa64520f1aa1e79e
+IN: 5bcc2ea4d729c84340c5ceb827f239578971c595e915f0bd9d49ed51d723f8d0e8362e69fd11466230bda0dad57ad724307edcc621ebde1e57fa91fee206d81d2bb6ead94b4a804f74b6cae979f66bdfa4ad93d107ccf114c59cd3d261aa6e2fc0dfbd0df5f7c18e80d0699cc1712abbefab5029e35549d2919d0f937d444051
+AD: f80c759062e9ed0ee597406aedbcda9a14261d66a9546f1c939d20cb1d0d0974fe7a9b33d8c93287a6a8d60a
+CT: dae4fc873d302c51e55910e67482bb80ac68e9bc6ef77cb3e57a31d85fe75f9071d0b64026ba16d0b68fa9c0b7e958cf7682bcd329c4174ea0e3f3f9d2e65d82aae1350a53ea7cdcf9ab848b85cd731751f0e2917628e5066f5b1ddebc7dbda5d2d37e46a7a7ee62bb49c4431af730f9cd3da4c1d0e5f8593d8c99803f781bee
+TAG: 58b42e9117fc8cc2ba5cff74b0d92e8b381a444fa837018b15e9514fc4319fb4
+
+KEY: 37235623acb0d650f905f106dc3bfe6fd83192e53056de8795ed8d20c6e58e5efd84584007ecb17de9e76b392e12fcd7
+NONCE: dc441f1c743a92c4b975c6b6
+IN: 960ceb8d80774bd88b7c5f17042ad2e4baac71b4021c548458cffcd9a049291cb0df93076c115b54f9af878745acebc6e8f04666d053b1ed980728043c4fe7f67b2bcb0341d8a4973ed126342f9add14279f8402cbbffcecfc847379dca8a68ba4f2f26141acfca7f3ef558dbaf04629f0f46e43246b19d875be452f14e7bf56
+AD: 32579218062560f15ff966932838460f99099782e79f1f8c41cd9f6eb59b4c2c3d2dae9cd199fe66d74c7a9940
+CT: 49ad8e24a31e90ab1f8dc37dc51dff0f93f1420e79eb108f90f800274a5aa573f64e274cd52f1dbfdee363e4f86e1457bfb8f87ce57aefd34c3a5a3a93db4ebde3f73a3b4c202c993903ab378ae71042ad238e94f400c7ac1891a9890b19d445eb1db60773a3ea165f7c4b2bb2071faaf588daebac7ce09ebfc88f4d9232d9ca
+TAG: 82f908b837a5768598982f860ecea16aee84427371c4de1f1314749b70ffc173
+
+KEY: e7fc36c9fe87a38f9bb4ca67723267e80e16bf39740eb1090234a473d68aed9c96fe2f96e539795eb042276aec5d7505
+NONCE: 83d768746d40dcd695e49ff4
+IN: e61f0e02a70249b62ec9a8fdbaf6622c9c6316599daff421f1b19815707b67587d196b7e1452c7d7609f108ea946675ac5d97ed215b92a451aa6a11717ab7819f84848151007f37e2cdc8aa99969c3d5652aeeb65fc21b621865f47f44eb2c528ee1142d11f513761a6bb2d169126503db5b263a410cadd2773ff931a032a885
+AD: 59114e9f21b380ae6068609ac36688e6aa7c2533cbfe07013ad1b6663bfa42e39f20e62b45c0faa256c1d33caa9f59b1e30d8502bb7148d051451b3d0265cb9fd0d82e4f4e0489ac606956762d8e7b70abd7eca413ddb708f119c342b3d0d5df673769d8df281656d909b68b6f6438edd60339fd84ff69918b6036ad12a0a588
+CT: 4f12807736c9ab32a2be2e00c9a0236394a8bcfcec6037e7582af462a73bf10aa73bd90e2bc24b97f7001ccf653574aea294bc7b30b77540f475e0e846ab78ffcfa1fef28058e540fea43d9017d4efa05c837611b2eacf0034f26cb7903eff7874973c6da7843892bfc676170a75f839e297dc7f04c74b40f4bda20a45b2a352
+TAG: 9b05aab44ba4d1451f14e087be626232ed11c4ed04081f0d4d47ab593fc619b1
+
diff --git a/crypto/cipher/test/aes_256_ctr_hmac_sha256.txt b/crypto/cipher/test/aes_256_ctr_hmac_sha256.txt
new file mode 100644
index 0000000..2a72e1c
--- /dev/null
+++ b/crypto/cipher/test/aes_256_ctr_hmac_sha256.txt
@@ -0,0 +1,336 @@
+KEY: a5060fecb0a738d8ff6dd50009a757c6e58db73228534d03f32c26baa1c209f402c3e03a6947c1d9421d63ce43f6df26d30ce783f5ed0d6b88edd389d9f92d8d
+NONCE: b52227e92203630a79ec7f5c
+IN: 
+AD: 
+CT: 
+TAG: e61a28f5df7061b4236834d2034d2b62cb63c660b7de696c26b345e66b34d222
+
+KEY: d676047046bd5be9263ae39caaa0f688abb1bc67c083658894da6aeeff80b6d58ffc7ca1a1c88f49e629bf5544b2cc7669367202b158fce83fc4a4826dd90a7c
+NONCE: eabef87a00fd99ebb6ed6d25
+IN: 
+AD: 83
+CT: 
+TAG: 473cf728899cd5fdd54f18d6f934c3901f7ca118fc5ab2cbb837feefa7852a67
+
+KEY: 5eaef3b8e068fbb652bd37df4dfad6490095642cd49761a35476dffc2b5b5f75236d0351d96a9028660788893323a777ea8a2ac88bb5e500b334af02b1c2a648
+NONCE: 34d049342b9db5ffa039eac0
+IN: 
+AD: 7578949699d44dec9188a7f7e14b0a23637cddb9107dbb1f8e2a968aad0443356d7eeceff4316ba7b2e8fe
+CT: 
+TAG: 4d2612c21357638bada9290d2a272f10fb5f070337bf87bae396a1e7253633ae
+
+KEY: eb7b3d7eeb5f26010915a36837dc83da2bad07eba714566584bf1ce62fa9b61210b0ead7182bc28c8f0427699bf04786583fa32f3c3a8a6582cdc254930043bc
+NONCE: 3bee5ebcdfc72f4ab0023211
+IN: 
+AD: efecb57e79a326c6b2ce0ae74d7656992a005fbb8da5a55b9595fc5348a5489ee2e69541ec0e8a727a560625
+CT: 
+TAG: f457db1e274adabe5fc898fb1eb7c4a5a8e9a2b66f964d0958aa058c1f9e15ba
+
+KEY: 1c1abffa8a2667a8c1ab347860528162d316d58e3966050dc140fd360e6ff7c557520a8982aae97c5db5495d8951eaa485e1cac4cd8f448a13d071d759885474
+NONCE: 4fdce4e59bfdf5d9b57c78e9
+IN: 
+AD: 55125cefc919379b3b4b2a24ee1794f44ac66fd99b8b68f98d4abd45ba50a5b76e5375d08abe3b8b8d3c576bc8
+CT: 
+TAG: c021d2c73737e54ac6e7f61f9bb44818e5bdbf8d81d43842fd25a535790fafba
+
+KEY: 366cf53bc185473acf62610b74231e53aace84e9c5d6fbf71fc24db4f42956065d3eec01ecc72a6c89266565ff530075f4532c860e3192e866b41aee98c5c42a
+NONCE: 9ff54bd7b10f4fdfd8db76c7
+IN: 
+AD: 853ef59ae873bf0bfe1465e9dd8c2cddfcf123d213ba4f599d984e4ea69d3c85a23508ec7941ca740a9157ca2a788e9b519291240b307d6c5a8c6860a96b4be698659d19e31ab0ac7ae6ba31dcd609c1db67ad580fe4422e42d368c3e93a56f2a087b0d587188462310c2ebe58ecfcf7178412223808eeb2eda76446168730fe
+CT: 
+TAG: 12d869dc4bd4ac4ce9ed643cccda9e11a1ade65c76f7c1535fa4ec2bcc5eb4c3
+
+KEY: 147b41369bed390f0a9561586fd975474e3b3bbf7f7ebb7a35e5cc43b516c044dce93e154ac790a109709ac5299bb17b709a913d33fd57ebfef2b48ed66393b3
+NONCE: 85b81732d2863b41d2551763
+IN: 73
+AD: 
+CT: bc
+TAG: 47fd81f6eed8d3c66afe06d788ffe40717847785f4b4c617d75a11171690a60c
+
+KEY: 9bf35c1194659c1da634eab6707c55b853c8f61d087187162e926adbae02f8bd4d15bae5b05865d0e2236d64715fc39f32e4e3679a0309396c37eab13d1c637b
+NONCE: 8da14a98ee741a5fce0de732
+IN: 10
+AD: 8e
+CT: 17
+TAG: b76af41002a946af4947f98f42a873b7da0871f482990a70bda8f005274ca179
+
+KEY: 0befac10caec674c9f23676d121f065dbcc8c91852dd5eb4e80c41076995a2138077592fec665954d21fd6787234d32d3d54bf9c220cf2bf018b374bde29926e
+NONCE: a96bfb49f3a136840a0e32ff
+IN: 59
+AD: 236adab55e1bb8a8db384c01bb2afd30ff35da71f955fb217b8305a45ee075e7f8d863d4c0e5dbe36e297c
+CT: ac
+TAG: 7bb634357e0835b02a0642352a834ff6598c2ded1af8e8ab60b9ef0641fe863d
+
+KEY: acc672aecf6f10119ee77070abbc2b4fade7e910efd1f93a5716161f88606469a49df05b40332b390d3ac289abfdf6bf7c37c033b1671082922d939139de0d42
+NONCE: af0f57b55f1a73794b3ce5cc
+IN: ee
+AD: f385a50ef027e532635878a4df0deb23369774be47c42f17cbd44925b668f628338ea5f8256c5ad8219c13cf
+CT: 71
+TAG: 13a5296075ef23216c2f2e83b940d24e8e1e6a01967af96599360f11499ac0a6
+
+KEY: 6195ef5ce3ee01188c48b04ce7a28b3ddd04b78711a6d1233121fc8ec3db3a7a0e496d1b6a416675b1e666b9a3df167efb8ade29e4f22fc77111f32ba8bd1ec2
+NONCE: 092070b2f8b65fcfe646f6bc
+IN: 26
+AD: 98526dba4437d88f657c0b7ce2a2be44ef4951711a40747a7d14b195e4c0eae97247256bba7dbd93d6a8f738c1
+CT: 83
+TAG: b6aad3f91a26a38245031d6a7eb97be0d386939d4536b2a27c90a2ddb891de73
+
+KEY: 40335487f9958dfc00b76ff06dfec162ae5c6be4e26918bd12e3f21760cb0bd364521a11f5bfae11dee989627525ab5295ee404bce476c280d13d238dea1bd40
+NONCE: ecf77c7c827a34efd8cdf79d
+IN: 34
+AD: f6e661254bf235c7d5b8ee330cb754087480dec5fe4c31dee65d1ab4479642101404bb563522937fb2e41d3aa8a4d269a222e6e0bcfd07ec4b29c1185f99fff7cb5bd2ca8c5b38742270e586c8db19138b446833f2ee07a11dae5b6a1a4c28657f3380e84bffe1bafeccad57d9cfea3da7f728119ec5bb18b79e002954f4379c
+CT: 5c
+TAG: f3420d4cecae2c1ad79d977abbe408045bd87525c0da2b93e0af3e6c53ba7d74
+
+KEY: bf32ef44c7ca9851f397e70df736d7e0e6243cfd875ebb81d76ad7612dbcfd084cab6b0d67c6a6e8b567c93fd0c3abb78ae121fdb3051a62ccfa045692d3453c
+NONCE: 46e0cc64d6e431c1efc2bd2d
+IN: 959348a8ad6912d7d6c8eae52f19b1
+AD: 
+CT: 55e8cb6fd958f18b3c19451c5c79a7
+TAG: af09194071cb0ed4488d27e79700f938ce77386e5d772f9853b17b719f2b1ebc
+
+KEY: a6b5b8b051edf5cea0353ead88ea887fab048ef32f8303275e93d8f926da0d4b0e34b9447cf44fa70c24c9ab964380065398336bbb20be167fc6cd5e591ef50e
+NONCE: 371363612c4675a2e59ebd39
+IN: 443d16621b0cf9a12552216f9558ca
+AD: 32
+CT: b7f432eeda8e4b8a25f0445f17ca7c
+TAG: 649934922826febab4d59dfb52a7558e6d30d56e273602b98f3c55fd8e24f4da
+
+KEY: 075b75434269a3fcc57922ee8cc55b5bbe1b90516a3b71838ade73d41ed1d1f33ae1e0e86f88f6ed7e091cae3ccb05144b3ef239831554d6e79ff97c4d8f150e
+NONCE: 754d5c4ccbfb291133859de3
+IN: 62a151add825077c59459fbf82b708
+AD: c8db27487de71124a95eb6359270a8363908159200333b46ee74e2709b308878779686bd43c24e9ecabfc3
+CT: 2ffb9a9f65c9fe3daad13768ab56bf
+TAG: 4430a90fed7d4b5b2adf5a60d6854956be4feef497781ac7d864a04259e99516
+
+KEY: e787fdeca1095f2f2760a1c5e0f302e07d6b08de39ce31fe6a0db2f76e4626eb0968768ae04d37082c114573c307699707630b8c7ceef60abe3b7831d2adcd6e
+NONCE: 9dc9bcfe8b4e2ea059e349bb
+IN: 3ad57105144e544f95b82d485f80bb
+AD: 96bce5dcaf4a90f6638a7e30cfd840a1e8dbc60cb70ab9592803f8799f909cafe71a83c2d884e1e289cc61e7
+CT: e504109cdbf57b0e8a87080379e00d
+TAG: 1798a64b5261761ecd88f36eaf7f86ed3db62100aed20dc6e337bc93c459487e
+
+KEY: b43ab650bdd201cf05e0436afe89ac54867383f04c5ed2faea5db8e6784c720d905234f1f5443c550ca14edd8d697fa2d9e288aa58c9a337b30e6d41cfa56545
+NONCE: 4e3dd3efe527902b9de45a5f
+IN: e386663e249b241fb8249cfec33ac2
+AD: 3cf7a396e1bd034ea77a54ffca789f206f94263d90d98bf3e69cb42205fc5c95cfbd0481b0ec490ea447299159
+CT: 94aacf00092723e778d25ba78e9d27
+TAG: bd5fcf90b9532e7abfa858aed90d5170f08edcdd28ff2c673e0ab45b8c0a0f39
+
+KEY: b22a7c5bb38715025cd59cc0feed9ad8e51101200000168052b294fb1ead545a517dee636a7acd22b8283afb33d30adbe02c1c8557715eea7147f3d98a97cbb9
+NONCE: 3b4244c9ad9fedd3f10fdf7a
+IN: da79e1ed131856cec3250fde7bda4b
+AD: 4b77472ade3f06500169405b86a793d63cfa58f57bde0dd706f369b391142c2fa8a3e6345ccf0a9c29b2182f578e22f55c576f155a05be5e81997fbe06410034ecddd871e5ed94b5eeffc6dbd90a8e66449da01f8ef47d28a4a4bd253ffc427f868867c73b5c709b01732bd8035b1a23ff0a903def1eb136fc90d8b3c8279769
+CT: 5d8ad7abc047bfdf9d9cd0b0aaa53e
+TAG: 41d050d518d0e51ce16bc2920aa6c76eb8eabd4ed76373c59618c6354885f47a
+
+KEY: 04b3fd8126d65f851f47b3dea22cd6e32506f21effaa3e29820ac7825e01b51c5a2816f0298154f2d8addefa2fdc34c0635d4d6b80ad23eb320c4d4f2aa1de1c
+NONCE: fae1b1da40471dbdcec64d4e
+IN: 509f116ef7435b0640cf141d5b958aaf
+AD: 
+CT: ecf553eba80e6dd1fae2eab24d772a89
+TAG: 11473566e80cff5d7421f65949c34301f34de378e91ad50928cf2caeadc466d4
+
+KEY: 413d154dadc7d8869e9e0f24b3320019a04b7a37620dd9e7aa40b5c08d70dea03c12ccf7faad7009e972680e81544b647650c6ff033f56e5bcdac9a35bd7f804
+NONCE: 6a4404adae3f4a7bd2bef95c
+IN: 3539fe02b75981fad4f8762772b3c11f
+AD: eb
+CT: 3f8a96905609a4ef1a95fdb87337503d
+TAG: 8ee076fd624d90e1f6336a92165e80408ca6f0e165b201547d351177c95e8d51
+
+KEY: ddc10df673e720c00f28fdfb69f1b8fba99696f23b6f29704a0114444cc0c8a6c8606e8d37fa95aabfd65b29c655678fcec50966c8758a3fb15332a1854a8eac
+NONCE: 06331613842b4af86c13f8a2
+IN: 55d74bcfc3d1cfc716c6e6b7153c6369
+AD: acc264344ae79959f9dd5130664273ba6f345c3fc7bc33c6c1ce33312bfbd5f181a3c7a24f15e7acf72ccf
+CT: 20650d9e846eb42854692d438b21d5e8
+TAG: 973857523e7ff600cf9bcfcc98403b34ab38d939a6d76716beac42678ca5f5bd
+
+KEY: be0c884db54cf761fc24ff3dd572362910dedacece5e1d93a916df277f923f78e7dcd908e60beb0043503c5b4877a9d962a7de37cacc7387a7553949b52894ec
+NONCE: 3f027a93e2716668c7634195
+IN: 1ba8f3a87ac6738167aac1491b602ddd
+AD: d06dd1b9360a68afa3de5d239b6d91d212c5c555567545a4f133bf5a3b0f26addb9379e1cc1cd690cd427c57
+CT: 3596cc50ae72db932dd83bbc8661641d
+TAG: 44a1834b1587d0f88e34137dcebbca059dfb8f65ddab18f338a8a30152167be0
+
+KEY: 2ee848726730c64332877a4f88ad7fb241a73b71fbee8eeb4d9d6485855ea32b487e03968e1a7b9e8ac8ab7fbd84257efbce0aa207aeefa67302d5847e0d9c05
+NONCE: 526b0a79b6359d133ad51011
+IN: a0c0477e8a9ebfd275b674ed33230d42
+AD: ded2f0f3f28aea28b17aa58d4b906c6a9b3078f97ffe95b7e161b0c3dbf66879bea7603a046da4945c802ac8b3
+CT: b1691c8275f12f7d9af85e71dde9dd5d
+TAG: 65a5742dcbc49295c4805387e0a15f986ae47e51add9389dfabb6468a6e83013
+
+KEY: f4a7c0e29ff510c034778e47bb30a468a92140a707936d381b1554d421af107c578e74c53ea08c7f7d93cf67612061359ae458408a9c79250f776ca4192016c0
+NONCE: 025bc10dc99346c4d0766a7d
+IN: d449a2e812429beb5c466d344f5b5eec
+AD: 304dbf9a59bfd33b777d8dec9dddce4c365e72aed851210eb964c1da18119bd13248266a67408e88ac2eadfc54def0fb57f23743d376b11293377565d253d2bffe0309f2946cb78d4e9536dde4691fe1eef9ce2dc916a773d06b42fe2b014e7974d4aeffce25a0902c9b44265e5d6d26809b5f24875e80cc13f1f8872b04a237
+CT: f366e7b66683f52586e1c363c15b7fb1
+TAG: e0e1bb733471f150ddce1b83f3fc2d88589d286ca052574b7f0735bb598362d2
+
+KEY: eb78ea626b219e12937057155884547cb7578718f569dc8f2b370c0fea80e7f0d0f5cb590f0b7341d20c775bcd6a3c818e23b6cea949cf99eb94a23a81cd2249
+NONCE: 75a10f16d429b809cf12b9ef
+IN: 6b0203316e8108ff01b12df91ba6644382
+AD: 
+CT: 7ee07054f76471115be159259340c24391
+TAG: ab970669d1603767d588a93cf215673ad307244f9179f46fca56e97f64a5fbac
+
+KEY: 3221167926be262b7bd0591f56be6bf030365d45ab84a93a94ea41a5e07735b17245ad43787e8791e7ceaa0472b562ed17e3b609c66c868c9b08304c8bb328b1
+NONCE: a94d8417d2bb0323bcfd354d
+IN: cec81bac7b85c441b6261163d67921eb49
+AD: dd
+CT: ddd8860fa9e2e8087db30c9da1ec9f9487
+TAG: 26a3b9bc4d4cd802cc22e7647a19fc2a5092293c9f5b1c84bdab7245a6d8f4ab
+
+KEY: 4b16e2d62294f76cd2a6c8e0928279d9de40f0b169ef9465738cbfa064c520128ee89cf657da27e4e532d8c4709d992970bfc9daab2f31b3a67e53200d3d6710
+NONCE: e746d498b9031007332447f7
+IN: 16841e3fc1f53990d33f7ba525dab121a0
+AD: a785917bc9f3aaadfd170abe83bb30c0c5d595fc8b491d983131aeab1a7b8d8771f1a963c251976152dd63
+CT: 6bcf5eac15ef74cb8a706856f62eb5e8c7
+TAG: 9dc84b06e8ec8921be4bc7762e8cebb61a95ac5660022520f9438e8f77b45796
+
+KEY: ff2f5944111226df1d9a300533d3e871694fe15a418b2090265cd8c0111b249dfb7ee86bd9228f7ea5d89d8afcf10bf69942ee4c29bfa8409b63c00c2213629e
+NONCE: 477060f0c61555873bbeb225
+IN: f091891c43e2374c2755a88a11b04beb4a
+AD: f1323fd1ac4de9719dc5966dae45dd7b8ddbee3f8da4f4f4d5f25d06bdb8ebf57328dde76d0bdb9bdc5f6b12
+CT: e0d96f6f3ed0493a289d4c3b79238b9ed6
+TAG: 71276c05b52bab0063108dbf4e8ff57cf3e15079055a309d725f14bb86671ce1
+
+KEY: 1ce841bcf2ad8accc458a2d94774c3aa53a99e7dbec587376212101303ca2b42272a23fe28514be190b82e503e7772a3713800f4360fdb767e85ea5e1f7b8eca
+NONCE: a2f8afc5ceb5382882907630
+IN: 620fece1e843d1d0b5c5a541a6f615a81d
+AD: ded910647464d0fbb0a5d93ffb9839de3360c675179c5991ad3470285d79071436025111153628c563ad1b595e
+CT: 34431c3422e009373c50f3ee6c5b3fcc2d
+TAG: 6e4e8a3967307f47e233a36ce05a4826a698fada2ac19543bab7c9ac4f79451b
+
+KEY: 6bafd28a32690851fda667eb2d3c5993f13df52b2e97630527f26c498fd5019f26177a78f27c0c41616d2a4a73757fcaf9cd92a7da8498f90315d41e7479d90a
+NONCE: 75166c506c8e1d10da4da8b9
+IN: 697bea4d6eed5e6ed243cf01cc79bfd3a5
+AD: c0fa663961c3f7e09a8c7bc73e252a232977dd6c9483f02067b34fe695f341d05338ea2002952439ce08295ee5c12f38dafffeb5716908d3f1d4bfbf9eb0e4077bf8e534f19568ed04fca3bbff95da9088cb939f7a20cc97cc0994f9308e184219bf12c8af0d66df436c296ad39832d661b88c98cbb168c751719ac1383c9124
+CT: 8f37885b9602725385fd9a244ab2a156ea
+TAG: 7fa5cedd330887900f4a44d098e04d5eca16cf94e21f897fa54b0fc116b711b6
+
+KEY: 815786c7744d15afe1d6ab452cb6696fead8b88269ba3eb35c458f6248bad77b404acc744ebb74612c4f97deaccb99a7bcc6ad41917d61057c05b30c581dc4a0
+NONCE: 12342e4704f02336ebfc91df
+IN: 7f15e696b49ae5104ced5bebbf58a9d8ddcfaf46ddce9df88fe0d58a2f8546feeb83b975c66e4dafddb7fd9d17e80127e70af06b3b8b13c3390f1f50a227e7
+AD: 
+CT: 22e7c5d54a7b622c47a9edb77cfe7c094e500b0ef9595bc346de736e0088e5934dc07160aea34f24d3ab21440878213d28059551cbfdaa418af40d344674f7
+TAG: 8c271ea5c15aa771c900388267efb2f435f001c2e83f4ec297e77c608de2d579
+
+KEY: 66d87d2b18e46257476456a1f87123424477decf196b88b09acfd3ca74bdebef4c98f1b93803098a141e0acc3ce8eede065417a0c1eda9b4614558d2383762b6
+NONCE: 1ec0ca1d3b09ef186ac4bb1a
+IN: cbb59e14098c2a8ab7e84ace913515c74e056e0fb272c7b88d0dddfb62e395afb695647d97d1071eb09cc1e1776b609fceaf4e30e92640379bb8f0e762ca9c
+AD: ec
+CT: 832804b8003b0ca1b4eff1dc4da6f6a9649e5a582854bb72cd74357476bf38d81ea3bc8ac0463f21fe37683bcbe07360d0ec2d7ab90b588adf669099303ac1
+TAG: 9fecafc768fca71ffe7d640dbb7a052d97d6c8e2fc86001d71feaf284ab609f0
+
+KEY: fbff97085351f4500e73190ac139dd3ac91e268042b5926b57e0394c750b10348b47641d195d5fb5b0846256ab229f102538b81e209db5d93b4d55f30c453d9c
+NONCE: d4868c918de2af7d3e3f57d3
+IN: 4f14aa5a680d66ae15ce0ce4739888f64d827def862572f9a6cd620badbe4ee9d75f4f9bc1f73d409f519a657f53a50d50e68e22f33a8ef5aa08b1212889e5
+AD: c41253e96696a948ce500030af27086842aacb79c04cc02a42b858a65c630065a5292bb9b2e69ea5fe5a7a
+CT: 08596ac0550574e352edc13d7e390d8fd0a57406dd61e1543066b4aa0ea06670f356e26ada0d6c61c1e41de1b4fd7a251c961fae44b23523ce227eec99a338
+TAG: 72f58de3e6697c8419ef518748fe0bb3cb930907c71b6d682c5e61068206d991
+
+KEY: c78c550aba82b571d39ce21d6ecf5e5f7c2a7bf921c6162c64ec1fdff4d0b8c41bfcea0e2486cc86b9ed9e9ceb73c4ec228a2ecbcfa0379174e76475cc21ae31
+NONCE: b5adf4de19980a71cb8ae8e6
+IN: 3d5e43ce95ff9d7f797f27b904c07291a35678fe76a9c57f0c0cba724f38acbb22c6c185db864a2a17b7ef2d67a04810ee5a45fd5a4e28a15a1ae16971451d
+AD: b5eeb9a18d436ada7bd5601944784f50fb0a989397b5c781a2cdf29337315dc7664f3c1cbf17f37fd0cc8b30
+CT: f91f1f20d06ad4480ff233480228994cfa052f9bf3038d06d997d31eb68bffa4960341b93eb5ed2260341e6816519c47bf231db2a41ad8a9719f4de6a33de5
+TAG: 6e5eabda421961e26dc17a7e1f750425235df4eaf9a97934c1e1b4439fc22791
+
+KEY: 17b90dec44546d9dbc489e55a01f2cc64452a9b0e50506a8ad7c81bc6fb21328285cafed901a7204048866ff3bd543003fdcbeb3e9e2f3d580f9062362879633
+NONCE: f0c0cb247d210031f9b233bc
+IN: 75b9b524cbfd1287259da116f536aff56112a406f069aa08f545b5372d45b66d7a5d05e02728c4bc2c779609dfe251386f78c5f48b9dad90b363d324826cd6
+AD: 8a604a9b06ad595ce0b9ad1644a596c7d3cde81490abc80840c764c40d6df08fc71d1e8196eae0802f8c8dfc24
+CT: 23ad62a668f942e613c3b5a7828142048f1f6a67f7f0e0cc8bf3fffb2d1dd967da472d080353dc9c23b900a566f20afb850e4a47688ee507faa6178fef2afd
+TAG: e9e82d3221f964d9e6c09d761afa3f05d1316d39c82618a82dafa23607bb40a3
+
+KEY: d5c09fe24201fcc3ad4c9a9c4b759345f643e930301c3714f62c8dd4974bb15a026b217ac637b4f0e8d6ef40f36be967c50aaea83b2e72df18eeb9576865f1d8
+NONCE: 9cfa0df1fe0910b33ee9849d
+IN: bfeb3d86ce3f4c5ccd0c3945e1da0e75dd057aa5b4e1f070593394f4a0227abedac0b77478e04d498506245b162e909cb711d8b875d33f9c4578e80a0e2113
+AD: b874a8523799554436a1174ab124677dc2ae2042a436c85065c50d5b5e7519623379ffed9a9c2b84b9626214b13c1806b65a432ba79066ff28ed94d17628f5ff84618593954389181e997ebd245d31f520539e250b31c86b99992983820f79e74aeaacb3a95e690e2841aba5a384d0333ebaa5d1fde06b4b8e3e1cabc6639459
+CT: afa649ea47db94936f89612ece681bb175664a97aa6faae5745f49ac9fcbfd4287b73cb58e8d8aa12eccf309182f075098f339db697fc60540481dad0cd82e
+TAG: 9909335130df0326650823de5a4f5b6f45e6941a6a72ceaf80ef32fe67363944
+
+KEY: a13c4654606f532a8df47c367dab1b214166e4f7188c20560831ac30ba5e58d316d29764e4c716ec0126657c926ba2e4541da062447228ae61340a951101b4a0
+NONCE: a2df3417ebb86bbb2f954939
+IN: f1954e59a319547d32e81f846e0c79db41c681166b43eb9c10458948606ced50a44df26fad5654a7c25d3fb52539cf25fcc1c11707c4b5aca7910a76e2374740
+AD: 
+CT: 374726a4691f178a4c0a6f96108ba30c4ca8a30242c14e84380969473879d4a5de580fab4cf6ef6e465560a15028ba78a1a88f9e62322cb698b15ccce6ba83a8
+TAG: 683e5a3e61d9d9c8b170f1d4eaa4f74dcbecb1a4cb1551dc364bbb336d4e4109
+
+KEY: 0c1751677a9b7373e0c2ceab2c8e4dab50af22e2230be3187c21ed46069168d173c28a7474d8f7c3cab39401663405aebdcc474ce136e1fff9cfc520bfe17ca6
+NONCE: 38bc2efcd97998de1528b064
+IN: 8a3c6212240bdcb86da98f0e3ab3e9e78f7f61f0627ea088ab283e739a0bed5c360eeed26cea43ec09b4f3556049a1d7f8ef86abfd1118f9c0e34cc6eea4544a
+AD: 20
+CT: a1a9f7f4750be3d89fc4f25917f8ffa7dd462ce712ddf61792a01b1840bc8e428000372252f1b41055416a961db3be8fbe774f0a0a71a82e79e74927522703a0
+TAG: ae24708df0d5893a902765f6c6c2eebae0c11312936cd415bf4a74bb8498a367
+
+KEY: 154c21eb43d8d556e5f782ddd64d577ac8066fa172c2936fc2b2e875aa437f941819d9ecfaefa2e388fdeea81a0ece8dcb7647f2c68da48884aeb1315b577c09
+NONCE: e14d1bd8681373d41702a762
+IN: a2c880fcda87d9d4681a735a6790d93a1c9c68e55b87d5f7b3146665a6b2051398eb9895e1f5d522841668b9915633aa8cb40048c619baf6d63ca2da486cdeb8
+AD: b0b725cf634349ce1d3ac49d48313a09697efd9996cc5afd06b1d0817181d0374db05825dc2f08207bfb3b
+CT: 1cc0db5980863df7a40c78e323a78be6c6d556d4e3b5f930d8d0f2c6a10c6477e31c000d3f0563b46e1a4aa566a4ef4b433e17e94c43338b51a7a3f862739b6e
+TAG: fe005424112de2a5ca6e68ada40984df1ae5ac666cf5fee19e9a0f203dd69f52
+
+KEY: c34482341724ee431b5272ee2964b245d7657778f7927cad4b5a1bc30a176b1eb88a83ac9faf58215a72855edf94f8e86fade58c5b5907994bb8381c9f21b753
+NONCE: 4934d9afc32fc7e2d8851594
+IN: aa3d32adc47b0b84d1b038ddcaeb007a7d5c96cc06a943eba5da6d0d367625330556e67da099c84086b3f46bb4b72986e076eb426913e415cd20bee34e434bd0
+AD: 076a7bc587b306f3da3ba88e66a55cb8125bbf8aa000dda266e950f381e35ac938ac86f8a15a83022a25f28b
+CT: cf017d87da8927e42c1f10fd3d73cf483bae43f4e110363159a9fbb7cba363930a0364cd42a5de2c70171edc4caf15bfc7238f7087bf1402b32c7bdb1f493393
+TAG: 3961efea656aab1b83082522b801fafdae346f7d4be70db1981283f323e5b5dd
+
+KEY: 363e10d8b3fe349014d6222761bba7af86545dcd1812fe2e5ada564c5008f8ea1850f374208e87362afa135f20f9e79dd0ad32f86448263416086d3afc5d37c0
+NONCE: cc545928edd3b21c0e8bc0f1
+IN: b68e3a54d17dab6eb41b03de2df14e792201d78a9c1cbf341da421da82b026ff471d4305ede5c6baae162a098c73da5cab93f30d6d540b4eaa0ee772448dade8
+AD: e21498edf4e25ada2dd6a382eceaf737623e501db34f5c5bd5c963f45818b146a6e45aa92db2a2069e55d46a4c
+CT: e4920c1fddb5dfed2268781fbb17e9ad2ea88bf2a0f116fbb7b309b25a5b9f989e1abc334999ab175b65f87e874d8ba80792044b458dc27d2b24c989d24385e1
+TAG: f0dcfa064cdf042e0b9a0443d634c38695dd09b99dadc647195fc2ad53dde547
+
+KEY: ae93f58aefa94e4e0622f2e962529fd2efdab840fd0bce62e163ca0fb004ec3b22e246073614203d9b63fe2842ef5903ed08b3e52abf7ea18acbe16fa8f66368
+NONCE: c9ac237c87270f2d88b91b64
+IN: a75f49778a6c03b0f8915f5d09efe99c5f4e9cd928713882e6b9b78bab3541812db41792b893c7e2259debc6c660ce708851912a5b9eaf91416d86b5de114ce1
+AD: a4b198a329e9c5bb6d9f31a6415811eb33c79422b0db130b78d788c38c0b9a5122688cbc50fea811afa20789465f9ee4362336cc3701ece701179af96eb7c86d5a00ed8582f24364393287d5dbc3e83a82b7a585cee5b152b5da40aa45ccd46dc841004778998c7efe9eb43c9762d1c8581eee64e18c5a961bda5aafdd5cfec8
+CT: 453fad9395106a703ccbfe811bf775f1827ea960c71d79242d2ea0e3e31b14baa76eb6d107dfc6e484f4e5146f8cad5b389e4c0fa18260c96a193edbc8091a36
+TAG: b67082c21557b31392a9821fbce4b93706f96856d2581c92e7fb65dd2166624f
+
+KEY: a145adafac46280e1cee8696903c5f3866540f27f17a519637373d95dca4ac5ac0bfd85ca6e1f8df8ae3fcfc9158421581669db52c20a3e19c5d251952f63218
+NONCE: 90bd43611f235ff225b23208
+IN: cbe5f3a5b7a94b8665cac1a4d173a225679e1a3926d8596b5adc0ef4fd00f7d93a432ff141cc04f877be60b6a17fff40ac845a91bcee3b483862f67d9a76ef498ce5e49c361bfc018e401aff47b397e96b2982d4fdcd043ca09905be9634e83dc22a667c955bc992ec96ca1b76f73631767f64fc7151284d5aa81c1aa42eb3aa
+AD: 
+CT: 604f718dbce17dfca1fc5e0f400151cb65bea9d7d8f26d56687a76a23f89201aab01ef928006d15493f5b1501bb99c517cf123acd956ab575e687298488a88d5739c266e67ca6a20a5dbe5f5f27ac778816f04e7b1764cb716477f3aa01482cb6b25fe034ab5d942013164aa124608cacf13d6cc9487446cfba54315fc6bfc42
+TAG: 8e3e1a01945bfd9e1aa4eff1cdd0a6da6d8fdd5446e6d732a673effe8e44d76a
+
+KEY: 63ac8e2561341587bc066c87cd23f7f33e6023bdc1521a91d6ce63d3ab213825d95d674928b56da1741aad8e85a8b703239ad74e0304ad555eeadebf4ae30aa6
+NONCE: 4f3073c3b780ebb146e136c7
+IN: 7f9a05b1aead29b4d5361c2606e5db8a48122858842679cd46f8386ef9359f998cd2c6c266791429624ff634a160d08faf1523b650c30b2fcd71517da5f377000251ef23cfd2510a0630215ad45fa6d2313f9add040a07df8259b82d3f29cf1ab8477cd114c9ee579d3e2ce60c5da2f3375b68b4d6e0913d39dac9399c00bd32
+AD: 22
+CT: d4ed811c8db932348e0c311e9278ef22f22cec8af88b3ac0cef77f13bbd9b8cca037c1ea87590a0ce3f3e7b3ffe1dcc4c7cd9e721baa5f126a3e0afb26dcfa02bf44428846c0f1e07ba0e026c23a39877de1e69e16a2766ff4fa3d4e8d3a97ba28f407f459ae3520dd840e8f9e149ea582048dc6e3d0227bd86a9c26ddd59895
+TAG: 0abc9111229bcb725953d139a2dcb1aa0cb9d3d6c01ef4733482dc5edcc88958
+
+KEY: 355454fbe12f125edbc13550a7494f37efbe12b843058d29f892e1524289c2868ef0050a75a232d3083c381289e4950e352d68d64bf05f0608d694763c36641c
+NONCE: 0a344bb3da1c4260f2daf256
+IN: 362e97f8ef09f30e5db2f21d40568d347d9bc42d4c94a563484b12eb109886ccfd2c61c40dfe93eb836bb6aa4f828e77c137485da2df494cbeb6a9a0192c3777b4d7a927fba11a8eaf604b85a81ac4719ce8b595a74656286fd0b80d1ad3f3393e6038b258af97af9a77f6760d486d9caf5a451ba26dee51bda0f76d75bfc26e
+AD: c7c2e8196f37185b44515480d5d9451d79d07df4c1256bff6382f942727ce9b3a4f81ae964d8af2cd9f638
+CT: 32a67922947fd6b1c1bfaf3e1d41397173b97095e55307cae1c574daca275778d4aa4313fb1fe5b3997ff18800903ce044c7d0976abbb03b6cc1f7498d8b56d00672bd74f7cb152b677c632ef7a6f6fc13e95e82b6e35d663eb47f27c229c81174fd7c62c94c414e47216af2580fe822643e54907af77ae18e903fe856a02173
+TAG: 72d0fe5baee8090c5f8e79890b77f6d72a4213a7d1a81e0d1f1c9e6731e44d54
+
+KEY: 664478c9d30d2cbc39351ec3b3494f3edb81e32e48bd4ef05969da07e770e4181a9ada3b2f83b46f40fc2d9ad35fd8ee6864ff3d70436d6cca3f8e0563cc3b06
+NONCE: 7313df9679181ffad2972a6b
+IN: 142f073f2ce443c68822f120b5009e39bea3453017dc04c1b091adfddcb2a7e361c2b79eab1bf0818bc86e9d7964834d3775698b56a11ee07a0c9c03cb7bb895bf1a1dde3975c3662d233052824f1539f58cd6ad5cadb58fecaf2b34935ff711c45a639d642fb8fc3a52929b1296683bb13e67f2cc8ed9090126cdf28a4395c6
+AD: d0d78b94505793af546912f3780699dd72e288c775bfc75da6e306defcd868f6d40c6d6ce34fab9c11574ef5
+CT: cb913e40ea5dfe76beae612e9732d23ce352789987134822b2324db585179bf90d0ee20bee102e93a49a55fc978d19e99ba316cf8d9a10d2f2bcb75da4b135d1fcb8057edc33a180586015d8829a128f8fdc87b72497016c280f54f4d974c2c7e9d32ae137eaa1bcb670be237269fa73c3a0f273da9e70d89600ae7c231fc9d4
+TAG: dcc158c254ff7e131ad854a2158d51c643c281dfd7df342d5481384ab236a685
+
+KEY: 409d1b4e1c187c8b1c053e999f2af648583e1045d56d553cce9270d08c5643ef365eb35e3bdeaedcd164b0122ad185e71c75146a9807104d9b65b56d9bc1dc55
+NONCE: 1cce3f08a5aa5824d063a6f2
+IN: a255239e4065f3effe6aa5e88814d516236d016c51cd8eb35af7cee86418966559802f8ff7ac39c6a45acc1f1b18cc28d7cc32ae66dff43289fe44c3a2a72fbadf3a7249d76c1ba9671dfc420ddf513539f2da5f31030f2b6775c57432c2c3486621d841e80dd4894229debc12ef47d74716838f2d807e208f0fdaf733bce76e
+AD: 8f34f8b676e71844841c6a7b63fef1ad3061f2449c1044e1a281595da2d9e9fd141aea7350bd8cf9774d375e67
+CT: 969fc2c64261db415e51eee8cc5e0cf5185b8e3325dea516a70e32115a5b72233a44458c40f2daff3594d71e42ca2e3fc1c444ce171d22ef40009d798456613fa4b76beaa6d469e235997a302ac468c8bcfb8ef5de5cda58d7e554a9eab6cb568945dc37f28b0dbd674c083dfbd2e42fda1b42d0c1966e9652a21b32af71e2d5
+TAG: fa0789a83c255412501944a67bdceaff3f01d9a23b0c749be38abc956e2acae6
+
+KEY: e6fd8144cdb305bf9e62a2c901764c62902f354409d8c5b9c8cbfc0ba8ac7d0859ff8994e573e46784395d89c355a91a313f601b56e86ed3fd10ba428a5481ce
+NONCE: bae080718d3e5c5998542f15
+IN: 2258ffcd6fcf91b1723f8db0047525d61cc8ffc440acf3290690685d16384292493807312b7dfc23ac9d9c3ee1405baab21a3770a05875cfe325268b65fc877463e3208c842ea4a32cf144cc46d57afd91f6b6b5d85fb2dedb0702f0c4e7f742cf4c9b4aec02f07267ec1f7b96a5a3ef25f6c1b4c27bd829e86583e239cd854b
+AD: 51ae57749b7757718aef9b9c47da5794659516e7f98bc80e6c18c89253f8617963331f54d4f009f087d1d2bd69a083f3a4b98f2a51ce24ffc6079774f7c7b01638b6131bfccebe21fea67bc839c259a50fcc0a16a69ada3c5adee4097d9e053a03266cb9b4b39ee2a465ec1aa058e61a0b9888b93bfcfd103f91ca3a7b274a10
+CT: 5b2fe8eea3313cc04d5ec75d75d05b3242b6e3b65c6fa1761716780c9529ff8ca523096dd037c5bda27984aa93c702ce9c01c63569a90657cc6373ad5d4473028b7eef69dd79c44c38d0063e8a8b7f1aa2bf6b646711ecd4eea3fa27408e089d9c4c4aceedff29a25baa6a9069eb7eac83a53212c0b387d700547c46cdc525e3
+TAG: 60319de093aec5c0bb8d5f17e950b0f4df0dfd20ad96490f6f12db461b2a4a84
+
diff --git a/crypto/err/cipher.errordata b/crypto/err/cipher.errordata
index bc7666e..ce8459b 100644
--- a/crypto/err/cipher.errordata
+++ b/crypto/err/cipher.errordata
@@ -8,6 +8,9 @@
 CIPHER,function,106,EVP_CipherInit_ex
 CIPHER,function,107,EVP_DecryptFinal_ex
 CIPHER,function,108,EVP_EncryptFinal_ex
+CIPHER,function,132,aead_aes_ctr_hmac_sha256_init
+CIPHER,function,133,aead_aes_ctr_hmac_sha256_open
+CIPHER,function,134,aead_aes_ctr_hmac_sha256_seal
 CIPHER,function,109,aead_aes_gcm_init
 CIPHER,function,110,aead_aes_gcm_open
 CIPHER,function,111,aead_aes_gcm_seal
diff --git a/include/openssl/aead.h b/include/openssl/aead.h
index 4b8f6cd..b39939d 100644
--- a/include/openssl/aead.h
+++ b/include/openssl/aead.h
@@ -115,6 +115,15 @@
  * See |EVP_aead_aes_128_key_wrap| for details. */
 OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_key_wrap(void);
 
+/* EVP_aead_aes_128_ctr_hmac_sha256 is AES-128 in CTR mode with HMAC-SHA256 for
+ * authentication. The nonce is 12 bytes; the bottom 32-bits are used as the
+ * block counter, thus the maximum plaintext size is 64GB. */
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ctr_hmac_sha256(void);
+
+/* EVP_aead_aes_128_ctr_hmac_sha256 is AES-256 in CTR mode with HMAC-SHA256 for
+ * authentication. See |EVP_aead_aes_128_ctr_hmac_sha256| for details. */
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_ctr_hmac_sha256(void);
+
 /* EVP_has_aes_hardware returns one if we enable hardware support for fast and
  * constant-time AES-GCM. */
 OPENSSL_EXPORT int EVP_has_aes_hardware(void);
diff --git a/include/openssl/cipher.h b/include/openssl/cipher.h
index 43b6cd5..1df4699 100644
--- a/include/openssl/cipher.h
+++ b/include/openssl/cipher.h
@@ -531,6 +531,9 @@
 #define CIPHER_F_aes_init_key 129
 #define CIPHER_F_aesni_init_key 130
 #define CIPHER_F_EVP_AEAD_CTX_init_with_direction 131
+#define CIPHER_F_aead_aes_ctr_hmac_sha256_init 132
+#define CIPHER_F_aead_aes_ctr_hmac_sha256_open 133
+#define CIPHER_F_aead_aes_ctr_hmac_sha256_seal 134
 #define CIPHER_R_AES_KEY_SETUP_FAILED 100
 #define CIPHER_R_BAD_DECRYPT 101
 #define CIPHER_R_BAD_KEY_LENGTH 102
diff --git a/util/all_tests.go b/util/all_tests.go
index 907dc48..ded798e 100644
--- a/util/all_tests.go
+++ b/util/all_tests.go
@@ -62,6 +62,8 @@
 	{"crypto/cipher/aead_test", "aes-128-cbc-sha1-ssl3", "crypto/cipher/test/aes_128_cbc_sha1_ssl3_tests.txt"},
 	{"crypto/cipher/aead_test", "aes-256-cbc-sha1-ssl3", "crypto/cipher/test/aes_256_cbc_sha1_ssl3_tests.txt"},
 	{"crypto/cipher/aead_test", "des-ede3-cbc-sha1-ssl3", "crypto/cipher/test/des_ede3_cbc_sha1_ssl3_tests.txt"},
+	{"crypto/cipher/aead_test", "aes-128-ctr-hmac-sha256", "crypto/cipher/test/aes_128_ctr_hmac_sha256.txt"},
+	{"crypto/cipher/aead_test", "aes-256-ctr-hmac-sha256", "crypto/cipher/test/aes_256_ctr_hmac_sha256.txt"},
 	{"crypto/cipher/cipher_test", "crypto/cipher/test/cipher_test.txt"},
 	{"crypto/constant_time_test"},
 	{"crypto/dh/dh_test"},