all repos — TinyCrypT @ 7d1a1493a6ed478d3d2ac234ad7ed9b22a0ce1e5

Short and sweet classical cryptographic primitives

tests/src/chacha20-poly1305/all.cpp (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
extern "C"
{
#include "tinycrypt/chacha20_poly1305.h"
}
#include "gtest/gtest.h"
#include <cstdint>
#include <cstring>
#include <vector>

TEST (ChaCha20_Poly1305, cc20_p1305_full)
{
  const uint8_t KEY[]
      = { 0x42, 0x90, 0xbc, 0xb1, 0x54, 0x17, 0x35, 0x31, 0xf3, 0x14, 0xaf,
          0x57, 0xf3, 0xbe, 0x3b, 0x50, 0x06, 0xda, 0x37, 0x1e, 0xce, 0x27,
          0x2a, 0xfa, 0x1b, 0x5d, 0xbd, 0xd1, 0x10, 0x0a, 0x10, 0x07 };
  const uint8_t INPUT[]
      = { 0x86, 0xd0, 0x99, 0x74, 0x84, 0x0b, 0xde, 0xd2, 0xa5, 0xca };
  const uint8_t NONCE[] = { 0xcd, 0x7c, 0xf6, 0x7b, 0xe3, 0x9c, 0x79, 0x4a };
  const uint8_t AAD[]
      = { 0x87, 0xe2, 0x29, 0xd4, 0x50, 0x08, 0x45, 0xa0, 0x79, 0xc0 };
  const uint8_t EXPECTED_OUTPUT[]
      = { 0xe3, 0xe4, 0x46, 0xf7, 0xed, 0xe9, 0xa1, 0x9b, 0x62,
          0xa4, 0x67, 0x7d, 0xab, 0xf4, 0xe3, 0xd2, 0x4b, 0x87,
          0x6b, 0xb2, 0x84, 0x75, 0x38, 0x96, 0xe1, 0xd6 };
  uint8_t actual_output[sizeof (EXPECTED_OUTPUT)];
  tct_aead_chacha20_poly1305_encrypt (AAD, sizeof (AAD), KEY, NONCE, INPUT,
                                      sizeof (INPUT), actual_output,
                                      actual_output + sizeof (INPUT));
  EXPECT_EQ (memcmp (actual_output, EXPECTED_OUTPUT, sizeof (EXPECTED_OUTPUT)),
             0);
}

TEST (ChaCha20_Poly1305, round_trip_lengths)
{
  const uint8_t KEY[32]
      = { 0x42, 0x90, 0xbc, 0xb1, 0x54, 0x17, 0x35, 0x31, 0xf3, 0x14, 0xaf,
          0x57, 0xf3, 0xbe, 0x3b, 0x50, 0x06, 0xda, 0x37, 0x1e, 0xce, 0x27,
          0x2a, 0xfa, 0x1b, 0x5d, 0xbd, 0xd1, 0x10, 0x0a, 0x10, 0x07 };
  const uint8_t NONCE[8] = { 0xcd, 0x7c, 0xf6, 0x7b, 0xe3, 0x9c, 0x79, 0x4a };
  const uint8_t AAD[10]
      = { 0x87, 0xe2, 0x29, 0xd4, 0x50, 0x08, 0x45, 0xa0, 0x79, 0xc0 };

  // Lengths straddling block (64) and vector-width (256, 512) boundaries.
  const size_t lengths[] = { 0,   1,   63,  64,  65,  127, 128,  255,  256,
                             257, 320, 511, 512, 513, 576, 1024, 2048, 4096 };

  for (size_t aad_len = 0; aad_len <= sizeof (AAD); aad_len += sizeof (AAD))
    {
      for (size_t len : lengths)
        {
          std::vector<uint8_t> plaintext (len), cipher (len), recovered (len);
          for (size_t i = 0; i < len; ++i)
            plaintext[i] = static_cast<uint8_t> (i * 31 + 7);

          uint8_t mac[16];
          tct_aead_chacha20_poly1305_encrypt (AAD, aad_len, KEY, NONCE,
                                              plaintext.data (), len,
                                              cipher.data (), mac);

          // ciphertext must differ from plaintext where there is data
          if (len > 0)
            {
              EXPECT_NE (memcmp (cipher.data (), plaintext.data (), len), 0)
                  << "len=" << len;
            }

          // frame = ciphertext || 16-byte tag
          std::vector<uint8_t> frame (len + 16);
          if (len != 0)
            {
              memcpy (frame.data (), cipher.data (), len);
            }
          memcpy (frame.data () + len, mac, 16);

          bool ok = tct_aead_chacha20_poly1305_decrypt_and_verify (
              AAD, aad_len, KEY, NONCE, frame.data (), len, recovered.data ());
          EXPECT_TRUE (ok) << "verify failed: aad_len=" << aad_len
                           << " len=" << len;
          if (len != 0)
            {
              EXPECT_EQ (memcmp (recovered.data (), plaintext.data (), len), 0)
                  << "aad_len=" << aad_len << " len=" << len;
            }

          // a single flipped ciphertext bit must fail verification
          if (len > 0)
            {
              frame[0] ^= 0x01;
              EXPECT_FALSE (tct_aead_chacha20_poly1305_decrypt_and_verify (
                  AAD, aad_len, KEY, NONCE, frame.data (), len,
                  recovered.data ()))
                  << "tamper not detected: len=" << len;
            }
        }
    }
}