1 // Copyright 2017 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ////////////////////////////////////////////////////////////////////////////////
16
17 #include "tink/subtle/aes_ctr_boringssl.h"
18
19 #include <string>
20 #include <utility>
21 #include <vector>
22
23 #include "gtest/gtest.h"
24 #include "absl/status/status.h"
25 #include "tink/internal/fips_utils.h"
26 #include "tink/subtle/random.h"
27 #include "tink/util/secret_data.h"
28 #include "tink/util/status.h"
29 #include "tink/util/statusor.h"
30 #include "tink/util/test_matchers.h"
31 #include "tink/util/test_util.h"
32
33 namespace crypto {
34 namespace tink {
35 namespace subtle {
36 namespace {
37
38 using ::crypto::tink::test::IsOk;
39 using ::crypto::tink::test::StatusIs;
40
TEST(AesCtrBoringSslTest,TestEncryptDecrypt)41 TEST(AesCtrBoringSslTest, TestEncryptDecrypt) {
42 if (internal::IsFipsModeEnabled() && !internal::IsFipsEnabledInSsl()) {
43 GTEST_SKIP()
44 << "Test should not run in FIPS mode when BoringCrypto is unavailable.";
45 }
46
47 util::SecretData key = util::SecretDataFromStringView(
48 test::HexDecodeOrDie("000102030405060708090a0b0c0d0e0f"));
49 int iv_size = 12;
50 auto res = AesCtrBoringSsl::New(key, iv_size);
51 EXPECT_TRUE(res.ok()) << res.status();
52 auto cipher = std::move(res.value());
53 std::string message = "Some data to encrypt.";
54 auto ct = cipher->Encrypt(message);
55 EXPECT_TRUE(ct.ok()) << ct.status();
56 EXPECT_EQ(ct.value().size(), message.size() + iv_size);
57 auto pt = cipher->Decrypt(ct.value());
58 EXPECT_TRUE(pt.ok()) << pt.status();
59 EXPECT_EQ(pt.value(), message);
60 }
61
TEST(AesCtrBoringSslTest,TestEncryptDecrypt_randomMessage)62 TEST(AesCtrBoringSslTest, TestEncryptDecrypt_randomMessage) {
63 if (internal::IsFipsModeEnabled() && !internal::IsFipsEnabledInSsl()) {
64 GTEST_SKIP()
65 << "Test should not run in FIPS mode when BoringCrypto is unavailable.";
66 }
67
68 util::SecretData key = util::SecretDataFromStringView(
69 test::HexDecodeOrDie("000102030405060708090a0b0c0d0e0f"));
70 int iv_size = 12;
71 auto res = AesCtrBoringSsl::New(key, iv_size);
72 EXPECT_TRUE(res.ok()) << res.status();
73 auto cipher = std::move(res.value());
74 for (int i = 0; i < 256; i++) {
75 std::string message = Random::GetRandomBytes(i);
76 auto ct = cipher->Encrypt(message);
77 EXPECT_TRUE(ct.ok()) << ct.status();
78 EXPECT_EQ(ct.value().size(), message.size() + iv_size);
79 auto pt = cipher->Decrypt(ct.value());
80 EXPECT_TRUE(pt.ok()) << pt.status();
81 EXPECT_EQ(pt.value(), message);
82 }
83 }
84
TEST(AesCtrBoringSslTest,TestEncryptDecrypt_randomKey_randomMessage)85 TEST(AesCtrBoringSslTest, TestEncryptDecrypt_randomKey_randomMessage) {
86 if (internal::IsFipsModeEnabled() && !internal::IsFipsEnabledInSsl()) {
87 GTEST_SKIP()
88 << "Test should not run in FIPS mode when BoringCrypto is unavailable.";
89 }
90
91 for (int i = 0; i < 256; i++) {
92 util::SecretData key = Random::GetRandomKeyBytes(16);
93 int iv_size = 12;
94 auto res = AesCtrBoringSsl::New(key, iv_size);
95 EXPECT_TRUE(res.ok()) << res.status();
96 auto cipher = std::move(res.value());
97 std::string message = Random::GetRandomBytes(i);
98 auto ct = cipher->Encrypt(message);
99 EXPECT_TRUE(ct.ok()) << ct.status();
100 EXPECT_EQ(ct.value().size(), message.size() + iv_size);
101 auto pt = cipher->Decrypt(ct.value());
102 EXPECT_TRUE(pt.ok()) << pt.status();
103 EXPECT_EQ(pt.value(), message);
104 }
105 }
106
TEST(AesCtrBoringSslTest,TestEncryptDecrypt_invalidIvSize)107 TEST(AesCtrBoringSslTest, TestEncryptDecrypt_invalidIvSize) {
108 if (internal::IsFipsModeEnabled() && !internal::IsFipsEnabledInSsl()) {
109 GTEST_SKIP()
110 << "Test should not run in FIPS mode when BoringCrypto is unavailable.";
111 }
112
113 util::SecretData key = util::SecretDataFromStringView(
114 test::HexDecodeOrDie("000102030405060708090a0b0c0d0e0f"));
115 int iv_size = 11;
116 auto res1 = AesCtrBoringSsl::New(key, iv_size);
117 EXPECT_FALSE(res1.ok()) << res1.status();
118
119 iv_size = 17;
120 auto res2 = AesCtrBoringSsl::New(key, iv_size);
121 EXPECT_FALSE(res2.ok()) << res2.status();
122 }
123
TEST(AesCtrBoringSslTest,TestNistTestVector)124 TEST(AesCtrBoringSslTest, TestNistTestVector) {
125 if (internal::IsFipsModeEnabled() && !internal::IsFipsEnabledInSsl()) {
126 GTEST_SKIP()
127 << "Test should not run in FIPS mode when BoringCrypto is unavailable.";
128 }
129
130 // NIST SP 800-38A pp 55.
131 util::SecretData key = util::SecretDataFromStringView(
132 test::HexDecodeOrDie("2b7e151628aed2a6abf7158809cf4f3c"));
133 std::string ciphertext(test::HexDecodeOrDie(
134 "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff874d6191b620e3261bef6864990db6ce"));
135 std::string message(test::HexDecodeOrDie("6bc1bee22e409f96e93d7e117393172a"));
136 int iv_size = 16;
137 auto res = AesCtrBoringSsl::New(key, iv_size);
138 EXPECT_TRUE(res.ok()) << res.status();
139 auto cipher = std::move(res.value());
140 auto pt = cipher->Decrypt(ciphertext);
141 EXPECT_TRUE(pt.ok()) << pt.status();
142 EXPECT_EQ(pt.value(), message);
143 }
144
TEST(AesCtrBoringSslTest,TestMultipleEncrypt)145 TEST(AesCtrBoringSslTest, TestMultipleEncrypt) {
146 if (internal::IsFipsModeEnabled() && !internal::IsFipsEnabledInSsl()) {
147 GTEST_SKIP()
148 << "Test should not run in FIPS mode when BoringCrypto is unavailable.";
149 }
150
151 util::SecretData key = Random::GetRandomKeyBytes(16);
152 int iv_size = 12;
153 auto res = AesCtrBoringSsl::New(key, iv_size);
154 EXPECT_TRUE(res.ok()) << res.status();
155 auto cipher = std::move(res.value());
156 std::string message = "Some data to encrypt.";
157 auto ct1 = cipher->Encrypt(message);
158 auto ct2 = cipher->Encrypt(message);
159 EXPECT_NE(ct1.value(), ct2.value());
160 }
161
TEST(AesCtrBoringSslTest,TestFipsOnly)162 TEST(AesCtrBoringSslTest, TestFipsOnly) {
163 if (internal::IsFipsModeEnabled() && !internal::IsFipsEnabledInSsl()) {
164 GTEST_SKIP()
165 << "Test should not run in FIPS mode when BoringCrypto is unavailable.";
166 }
167
168 util::SecretData key128 = util::SecretDataFromStringView(
169 test::HexDecodeOrDie("000102030405060708090a0b0c0d0e0f"));
170 util::SecretData key256 = util::SecretDataFromStringView(test::HexDecodeOrDie(
171 "000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f"));
172
173 EXPECT_THAT(subtle::AesCtrBoringSsl::New(key128, 16), IsOk());
174 EXPECT_THAT(subtle::AesCtrBoringSsl::New(key256, 16), IsOk());
175 }
176
TEST(AesCtrBoringSslTest,TestFipsFailWithoutBoringCrypto)177 TEST(AesCtrBoringSslTest, TestFipsFailWithoutBoringCrypto) {
178 if (!internal::IsFipsModeEnabled() || internal::IsFipsEnabledInSsl()) {
179 GTEST_SKIP()
180 << "Test assumes kOnlyUseFips but BoringCrypto is unavailable.";
181 }
182
183 util::SecretData key128 = util::SecretDataFromStringView(
184 test::HexDecodeOrDie("000102030405060708090a0b0c0d0e0f"));
185 util::SecretData key256 = util::SecretDataFromStringView(test::HexDecodeOrDie(
186 "000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f"));
187
188 EXPECT_THAT(subtle::AesCtrBoringSsl::New(key128, 16).status(),
189 StatusIs(absl::StatusCode::kInternal));
190 EXPECT_THAT(subtle::AesCtrBoringSsl::New(key256, 16).status(),
191 StatusIs(absl::StatusCode::kInternal));
192 }
193
194 } // namespace
195 } // namespace subtle
196 } // namespace tink
197 } // namespace crypto
198