blob: ccec597e4859ba33eb74b42128aad28c19933070 [file] [log] [blame]
Kenny Rootb8494592015-09-25 02:29:14 +00001/* 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>
Adam Vartanianbfcf3a72018-08-10 14:55:24 +010016#include <stdlib.h>
Kenny Rootb8494592015-09-25 02:29:14 +000017#include <string.h>
18
Steven Valdezbb1ceac2016-10-07 10:34:51 -040019#include <memory>
20#include <vector>
21
Robert Sloan8ff03552017-06-14 12:40:58 -070022#include <gtest/gtest.h>
23
Kenny Rootb8494592015-09-25 02:29:14 +000024#include <openssl/aes.h>
Kenny Rootb8494592015-09-25 02:29:14 +000025
Robert Sloan572a4e22017-04-17 10:52:19 -070026#include "../../internal.h"
27#include "../../test/file_test.h"
Robert Sloan8ff03552017-06-14 12:40:58 -070028#include "../../test/test_util.h"
Adam Vartanianbfcf3a72018-08-10 14:55:24 +010029#include "../../test/wycheproof_util.h"
Kenny Rootb8494592015-09-25 02:29:14 +000030
Steven Valdezbb1ceac2016-10-07 10:34:51 -040031
Robert Sloan8ff03552017-06-14 12:40:58 -070032static void TestRaw(FileTest *t) {
Steven Valdezbb1ceac2016-10-07 10:34:51 -040033 std::vector<uint8_t> key, plaintext, ciphertext;
Robert Sloan8ff03552017-06-14 12:40:58 -070034 ASSERT_TRUE(t->GetBytes(&key, "Key"));
35 ASSERT_TRUE(t->GetBytes(&plaintext, "Plaintext"));
36 ASSERT_TRUE(t->GetBytes(&ciphertext, "Ciphertext"));
Steven Valdezbb1ceac2016-10-07 10:34:51 -040037
Robert Sloan8ff03552017-06-14 12:40:58 -070038 ASSERT_EQ(static_cast<unsigned>(AES_BLOCK_SIZE), plaintext.size());
39 ASSERT_EQ(static_cast<unsigned>(AES_BLOCK_SIZE), ciphertext.size());
Steven Valdezbb1ceac2016-10-07 10:34:51 -040040
Kenny Rootb8494592015-09-25 02:29:14 +000041 AES_KEY aes_key;
Robert Sloan8ff03552017-06-14 12:40:58 -070042 ASSERT_EQ(0, AES_set_encrypt_key(key.data(), 8 * key.size(), &aes_key));
Kenny Rootb8494592015-09-25 02:29:14 +000043
44 // Test encryption.
45 uint8_t block[AES_BLOCK_SIZE];
Steven Valdezbb1ceac2016-10-07 10:34:51 -040046 AES_encrypt(plaintext.data(), block, &aes_key);
Robert Sloan8ff03552017-06-14 12:40:58 -070047 EXPECT_EQ(Bytes(ciphertext), Bytes(block));
Kenny Rootb8494592015-09-25 02:29:14 +000048
49 // Test in-place encryption.
Robert Sloan69939df2017-01-09 10:53:07 -080050 OPENSSL_memcpy(block, plaintext.data(), AES_BLOCK_SIZE);
Kenny Rootb8494592015-09-25 02:29:14 +000051 AES_encrypt(block, block, &aes_key);
Robert Sloan8ff03552017-06-14 12:40:58 -070052 EXPECT_EQ(Bytes(ciphertext), Bytes(block));
Kenny Rootb8494592015-09-25 02:29:14 +000053
Robert Sloan8ff03552017-06-14 12:40:58 -070054 ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes_key));
Kenny Rootb8494592015-09-25 02:29:14 +000055
56 // Test decryption.
Steven Valdezbb1ceac2016-10-07 10:34:51 -040057 AES_decrypt(ciphertext.data(), block, &aes_key);
Robert Sloan8ff03552017-06-14 12:40:58 -070058 EXPECT_EQ(Bytes(plaintext), Bytes(block));
Kenny Rootb8494592015-09-25 02:29:14 +000059
60 // Test in-place decryption.
Robert Sloan69939df2017-01-09 10:53:07 -080061 OPENSSL_memcpy(block, ciphertext.data(), AES_BLOCK_SIZE);
Kenny Rootb8494592015-09-25 02:29:14 +000062 AES_decrypt(block, block, &aes_key);
Robert Sloan8ff03552017-06-14 12:40:58 -070063 EXPECT_EQ(Bytes(plaintext), Bytes(block));
Kenny Rootb8494592015-09-25 02:29:14 +000064}
65
Robert Sloan8ff03552017-06-14 12:40:58 -070066static void TestKeyWrap(FileTest *t) {
Steven Valdezbb1ceac2016-10-07 10:34:51 -040067 // All test vectors use the default IV, so test both with implicit and
68 // explicit IV.
69 //
70 // TODO(davidben): Find test vectors that use a different IV.
71 static const uint8_t kDefaultIV[] = {
72 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
73 };
Kenny Rootb8494592015-09-25 02:29:14 +000074
Steven Valdezbb1ceac2016-10-07 10:34:51 -040075 std::vector<uint8_t> key, plaintext, ciphertext;
Robert Sloan8ff03552017-06-14 12:40:58 -070076 ASSERT_TRUE(t->GetBytes(&key, "Key"));
77 ASSERT_TRUE(t->GetBytes(&plaintext, "Plaintext"));
78 ASSERT_TRUE(t->GetBytes(&ciphertext, "Ciphertext"));
Kenny Rootb8494592015-09-25 02:29:14 +000079
Robert Sloan8ff03552017-06-14 12:40:58 -070080 ASSERT_EQ(plaintext.size() + 8, ciphertext.size())
81 << "Invalid Plaintext and Ciphertext lengths.";
Steven Valdezbb1ceac2016-10-07 10:34:51 -040082
Robert Sloan8ff03552017-06-14 12:40:58 -070083 // Test encryption.
Steven Valdezbb1ceac2016-10-07 10:34:51 -040084 AES_KEY aes_key;
Robert Sloan8ff03552017-06-14 12:40:58 -070085 ASSERT_EQ(0, AES_set_encrypt_key(key.data(), 8 * key.size(), &aes_key));
Steven Valdezbb1ceac2016-10-07 10:34:51 -040086
Robert Sloan8ff03552017-06-14 12:40:58 -070087 // Test with implicit IV.
Steven Valdezbb1ceac2016-10-07 10:34:51 -040088 std::unique_ptr<uint8_t[]> buf(new uint8_t[ciphertext.size()]);
Robert Sloan8ff03552017-06-14 12:40:58 -070089 int len = AES_wrap_key(&aes_key, nullptr /* iv */, buf.get(),
90 plaintext.data(), plaintext.size());
91 ASSERT_GE(len, 0);
92 EXPECT_EQ(Bytes(ciphertext), Bytes(buf.get(), static_cast<size_t>(len)));
Steven Valdezbb1ceac2016-10-07 10:34:51 -040093
Robert Sloan8ff03552017-06-14 12:40:58 -070094 // Test with explicit IV.
Robert Sloan69939df2017-01-09 10:53:07 -080095 OPENSSL_memset(buf.get(), 0, ciphertext.size());
Robert Sloan8ff03552017-06-14 12:40:58 -070096 len = AES_wrap_key(&aes_key, kDefaultIV, buf.get(), plaintext.data(),
97 plaintext.size());
98 ASSERT_GE(len, 0);
99 EXPECT_EQ(Bytes(ciphertext), Bytes(buf.get(), static_cast<size_t>(len)));
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400100
Robert Sloan8ff03552017-06-14 12:40:58 -0700101 // Test decryption.
102 ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes_key));
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400103
Robert Sloan8ff03552017-06-14 12:40:58 -0700104 // Test with implicit IV.
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400105 buf.reset(new uint8_t[plaintext.size()]);
Robert Sloan8ff03552017-06-14 12:40:58 -0700106 len = AES_unwrap_key(&aes_key, nullptr /* iv */, buf.get(), ciphertext.data(),
107 ciphertext.size());
108 ASSERT_GE(len, 0);
109 EXPECT_EQ(Bytes(plaintext), Bytes(buf.get(), static_cast<size_t>(len)));
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400110
Robert Sloan8ff03552017-06-14 12:40:58 -0700111 // Test with explicit IV.
Robert Sloan69939df2017-01-09 10:53:07 -0800112 OPENSSL_memset(buf.get(), 0, plaintext.size());
Robert Sloan8ff03552017-06-14 12:40:58 -0700113 len = AES_unwrap_key(&aes_key, kDefaultIV, buf.get(), ciphertext.data(),
114 ciphertext.size());
115 ASSERT_GE(len, 0);
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400116
Robert Sloan8ff03552017-06-14 12:40:58 -0700117 // Test corrupted ciphertext.
Robert Sloan69939df2017-01-09 10:53:07 -0800118 ciphertext[0] ^= 1;
Robert Sloan8ff03552017-06-14 12:40:58 -0700119 EXPECT_EQ(-1, AES_unwrap_key(&aes_key, nullptr /* iv */, buf.get(),
120 ciphertext.data(), ciphertext.size()));
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400121}
122
Robert Sloan8ff03552017-06-14 12:40:58 -0700123TEST(AESTest, TestVectors) {
124 FileTestGTest("crypto/fipsmodule/aes/aes_tests.txt", [](FileTest *t) {
125 if (t->GetParameter() == "Raw") {
126 TestRaw(t);
127 } else if (t->GetParameter() == "KeyWrap") {
128 TestKeyWrap(t);
129 } else {
130 ADD_FAILURE() << "Unknown mode " << t->GetParameter();
131 }
132 });
Kenny Rootb8494592015-09-25 02:29:14 +0000133}
Adam Vartanianbfcf3a72018-08-10 14:55:24 +0100134
135TEST(AESTest, WycheproofKeyWrap) {
136 FileTestGTest("third_party/wycheproof_testvectors/kw_test.txt",
137 [](FileTest *t) {
138 std::string key_size;
139 ASSERT_TRUE(t->GetInstruction(&key_size, "keySize"));
140 std::vector<uint8_t> ct, key, msg;
141 ASSERT_TRUE(t->GetBytes(&ct, "ct"));
142 ASSERT_TRUE(t->GetBytes(&key, "key"));
143 ASSERT_TRUE(t->GetBytes(&msg, "msg"));
144 ASSERT_EQ(static_cast<unsigned>(atoi(key_size.c_str())), key.size() * 8);
145 WycheproofResult result;
146 ASSERT_TRUE(GetWycheproofResult(t, &result));
147
148 if (result != WycheproofResult::kInvalid) {
149 ASSERT_GE(ct.size(), 8u);
150
151 AES_KEY aes;
152 ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes));
153 std::vector<uint8_t> out(ct.size() - 8);
154 int len = AES_unwrap_key(&aes, nullptr, out.data(), ct.data(), ct.size());
155 ASSERT_EQ(static_cast<int>(out.size()), len);
156 EXPECT_EQ(Bytes(msg), Bytes(out));
157
158 out.resize(msg.size() + 8);
159 ASSERT_EQ(0, AES_set_encrypt_key(key.data(), 8 * key.size(), &aes));
160 len = AES_wrap_key(&aes, nullptr, out.data(), msg.data(), msg.size());
161 ASSERT_EQ(static_cast<int>(out.size()), len);
162 EXPECT_EQ(Bytes(ct), Bytes(out));
163 } else {
164 AES_KEY aes;
165 ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes));
166 std::vector<uint8_t> out(ct.size() < 8 ? 0 : ct.size() - 8);
167 int len = AES_unwrap_key(&aes, nullptr, out.data(), ct.data(), ct.size());
168 EXPECT_EQ(-1, len);
169 }
170 });
171}
172
173TEST(AESTest, WrapBadLengths) {
174 uint8_t key[128/8] = {0};
175 AES_KEY aes;
176 ASSERT_EQ(0, AES_set_encrypt_key(key, 128, &aes));
177
178 // Input lengths to |AES_wrap_key| must be a multiple of 8 and at least 16.
179 static const size_t kLengths[] = {0, 1, 2, 3, 4, 5, 6, 7, 8,
180 9, 10, 11, 12, 13, 14, 15, 20};
181 for (size_t len : kLengths) {
182 SCOPED_TRACE(len);
183 std::vector<uint8_t> in(len);
184 std::vector<uint8_t> out(len + 8);
185 EXPECT_EQ(-1,
186 AES_wrap_key(&aes, nullptr, out.data(), in.data(), in.size()));
187 }
188}