Home | History | Annotate | Download | only in aes
      1 /* Copyright (c) 2015, Google Inc.
      2  *
      3  * Permission to use, copy, modify, and/or distribute this software for any
      4  * purpose with or without fee is hereby granted, provided that the above
      5  * copyright notice and this permission notice appear in all copies.
      6  *
      7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
     10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
     12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
     13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
     14 
     15 #include <stdio.h>
     16 #include <string.h>
     17 
     18 #include <memory>
     19 #include <vector>
     20 
     21 #include <gtest/gtest.h>
     22 
     23 #include <openssl/aes.h>
     24 
     25 #include "../../internal.h"
     26 #include "../../test/file_test.h"
     27 #include "../../test/test_util.h"
     28 
     29 
     30 static void TestRaw(FileTest *t) {
     31   std::vector<uint8_t> key, plaintext, ciphertext;
     32   ASSERT_TRUE(t->GetBytes(&key, "Key"));
     33   ASSERT_TRUE(t->GetBytes(&plaintext, "Plaintext"));
     34   ASSERT_TRUE(t->GetBytes(&ciphertext, "Ciphertext"));
     35 
     36   ASSERT_EQ(static_cast<unsigned>(AES_BLOCK_SIZE), plaintext.size());
     37   ASSERT_EQ(static_cast<unsigned>(AES_BLOCK_SIZE), ciphertext.size());
     38 
     39   AES_KEY aes_key;
     40   ASSERT_EQ(0, AES_set_encrypt_key(key.data(), 8 * key.size(), &aes_key));
     41 
     42   // Test encryption.
     43   uint8_t block[AES_BLOCK_SIZE];
     44   AES_encrypt(plaintext.data(), block, &aes_key);
     45   EXPECT_EQ(Bytes(ciphertext), Bytes(block));
     46 
     47   // Test in-place encryption.
     48   OPENSSL_memcpy(block, plaintext.data(), AES_BLOCK_SIZE);
     49   AES_encrypt(block, block, &aes_key);
     50   EXPECT_EQ(Bytes(ciphertext), Bytes(block));
     51 
     52   ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes_key));
     53 
     54   // Test decryption.
     55   AES_decrypt(ciphertext.data(), block, &aes_key);
     56   EXPECT_EQ(Bytes(plaintext), Bytes(block));
     57 
     58   // Test in-place decryption.
     59   OPENSSL_memcpy(block, ciphertext.data(), AES_BLOCK_SIZE);
     60   AES_decrypt(block, block, &aes_key);
     61   EXPECT_EQ(Bytes(plaintext), Bytes(block));
     62 }
     63 
     64 static void TestKeyWrap(FileTest *t) {
     65   // All test vectors use the default IV, so test both with implicit and
     66   // explicit IV.
     67   //
     68   // TODO(davidben): Find test vectors that use a different IV.
     69   static const uint8_t kDefaultIV[] = {
     70       0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
     71   };
     72 
     73   std::vector<uint8_t> key, plaintext, ciphertext;
     74   ASSERT_TRUE(t->GetBytes(&key, "Key"));
     75   ASSERT_TRUE(t->GetBytes(&plaintext, "Plaintext"));
     76   ASSERT_TRUE(t->GetBytes(&ciphertext, "Ciphertext"));
     77 
     78   ASSERT_EQ(plaintext.size() + 8, ciphertext.size())
     79       << "Invalid Plaintext and Ciphertext lengths.";
     80 
     81   // Test encryption.
     82   AES_KEY aes_key;
     83   ASSERT_EQ(0, AES_set_encrypt_key(key.data(), 8 * key.size(), &aes_key));
     84 
     85   // Test with implicit IV.
     86   std::unique_ptr<uint8_t[]> buf(new uint8_t[ciphertext.size()]);
     87   int len = AES_wrap_key(&aes_key, nullptr /* iv */, buf.get(),
     88                          plaintext.data(), plaintext.size());
     89   ASSERT_GE(len, 0);
     90   EXPECT_EQ(Bytes(ciphertext), Bytes(buf.get(), static_cast<size_t>(len)));
     91 
     92   // Test with explicit IV.
     93   OPENSSL_memset(buf.get(), 0, ciphertext.size());
     94   len = AES_wrap_key(&aes_key, kDefaultIV, buf.get(), plaintext.data(),
     95                      plaintext.size());
     96   ASSERT_GE(len, 0);
     97   EXPECT_EQ(Bytes(ciphertext), Bytes(buf.get(), static_cast<size_t>(len)));
     98 
     99   // Test decryption.
    100   ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes_key));
    101 
    102   // Test with implicit IV.
    103   buf.reset(new uint8_t[plaintext.size()]);
    104   len = AES_unwrap_key(&aes_key, nullptr /* iv */, buf.get(), ciphertext.data(),
    105                        ciphertext.size());
    106   ASSERT_GE(len, 0);
    107   EXPECT_EQ(Bytes(plaintext), Bytes(buf.get(), static_cast<size_t>(len)));
    108 
    109   // Test with explicit IV.
    110   OPENSSL_memset(buf.get(), 0, plaintext.size());
    111   len = AES_unwrap_key(&aes_key, kDefaultIV, buf.get(), ciphertext.data(),
    112                        ciphertext.size());
    113   ASSERT_GE(len, 0);
    114 
    115   // Test corrupted ciphertext.
    116   ciphertext[0] ^= 1;
    117   EXPECT_EQ(-1, AES_unwrap_key(&aes_key, nullptr /* iv */, buf.get(),
    118                                ciphertext.data(), ciphertext.size()));
    119 }
    120 
    121 TEST(AESTest, TestVectors) {
    122   FileTestGTest("crypto/fipsmodule/aes/aes_tests.txt", [](FileTest *t) {
    123     if (t->GetParameter() == "Raw") {
    124       TestRaw(t);
    125     } else if (t->GetParameter() == "KeyWrap") {
    126       TestKeyWrap(t);
    127     } else {
    128       ADD_FAILURE() << "Unknown mode " << t->GetParameter();
    129     }
    130   });
    131 }
    132