1//
2// Copyright (C) 2015 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#include <memory>
18#include <string>
19#include <vector>
20
21#include <base/logging.h>
22#include <base/strings/string_number_conversions.h>
23#include <gmock/gmock.h>
24#include <gtest/gtest.h>
25
26#include "attestation/common/crypto_utility_impl.h"
27#include "attestation/common/mock_tpm_utility.h"
28
29using testing::_;
30using testing::NiceMock;
31using testing::Return;
32
33namespace {
34
35const char kValidPublicKeyHex[] =
36    "3082010A0282010100"
37    "961037BC12D2A298BEBF06B2D5F8C9B64B832A2237F8CF27D5F96407A6041A4D"
38    "AD383CB5F88E625F412E8ACD5E9D69DF0F4FA81FCE7955829A38366CBBA5A2B1"
39    "CE3B48C14B59E9F094B51F0A39155874C8DE18A0C299EBF7A88114F806BE4F25"
40    "3C29A509B10E4B19E31675AFE3B2DA77077D94F43D8CE61C205781ED04D183B4"
41    "C349F61B1956C64B5398A3A98FAFF17D1B3D9120C832763EDFC8F4137F6EFBEF"
42    "46D8F6DE03BD00E49DEF987C10BDD5B6F8758B6A855C23C982DDA14D8F0F2B74"
43    "E6DEFA7EEE5A6FC717EB0FF103CB8049F693A2C8A5039EF1F5C025DC44BD8435"
44    "E8D8375DADE00E0C0F5C196E04B8483CC98B1D5B03DCD7E0048B2AB343FFC11F"
45    "0203"
46    "010001";
47
48std::string HexDecode(const std::string hex) {
49  std::vector<uint8_t> output;
50  CHECK(base::HexStringToBytes(hex, &output));
51  return std::string(reinterpret_cast<char*>(output.data()), output.size());
52}
53
54}  // namespace
55
56namespace attestation {
57
58class CryptoUtilityImplTest : public testing::Test {
59 public:
60  ~CryptoUtilityImplTest() override = default;
61  void SetUp() override {
62    crypto_utility_.reset(new CryptoUtilityImpl(&mock_tpm_utility_));
63  }
64
65 protected:
66  NiceMock<MockTpmUtility> mock_tpm_utility_;
67  std::unique_ptr<CryptoUtilityImpl> crypto_utility_;
68};
69
70TEST_F(CryptoUtilityImplTest, GetRandomSuccess) {
71  std::string random1;
72  EXPECT_TRUE(crypto_utility_->GetRandom(20, &random1));
73  std::string random2;
74  EXPECT_TRUE(crypto_utility_->GetRandom(20, &random2));
75  EXPECT_NE(random1, random2);
76}
77
78TEST_F(CryptoUtilityImplTest, GetRandomIntOverflow) {
79  size_t num_bytes = -1;
80  std::string buffer;
81  EXPECT_FALSE(crypto_utility_->GetRandom(num_bytes, &buffer));
82}
83
84TEST_F(CryptoUtilityImplTest, PairwiseSealedEncryption) {
85  std::string key;
86  std::string sealed_key;
87  EXPECT_TRUE(crypto_utility_->CreateSealedKey(&key, &sealed_key));
88  std::string data("test");
89  std::string encrypted_data;
90  EXPECT_TRUE(crypto_utility_->EncryptData(data, key, sealed_key,
91                                           &encrypted_data));
92  key.clear();
93  sealed_key.clear();
94  data.clear();
95  EXPECT_TRUE(crypto_utility_->UnsealKey(encrypted_data, &key, &sealed_key));
96  EXPECT_TRUE(crypto_utility_->DecryptData(encrypted_data, key, &data));
97  EXPECT_EQ("test", data);
98}
99
100TEST_F(CryptoUtilityImplTest, SealFailure) {
101  EXPECT_CALL(mock_tpm_utility_, SealToPCR0(_, _))
102      .WillRepeatedly(Return(false));
103  std::string key;
104  std::string sealed_key;
105  EXPECT_FALSE(crypto_utility_->CreateSealedKey(&key, &sealed_key));
106}
107
108TEST_F(CryptoUtilityImplTest, EncryptNoData) {
109  std::string key(32, 0);
110  std::string output;
111  EXPECT_TRUE(crypto_utility_->EncryptData(std::string(), key, key, &output));
112}
113
114TEST_F(CryptoUtilityImplTest, EncryptInvalidKey) {
115  std::string key(12, 0);
116  std::string output;
117  EXPECT_FALSE(crypto_utility_->EncryptData(std::string(), key, key, &output));
118}
119
120TEST_F(CryptoUtilityImplTest, UnsealInvalidData) {
121  std::string output;
122  EXPECT_FALSE(crypto_utility_->UnsealKey("invalid", &output, &output));
123}
124
125TEST_F(CryptoUtilityImplTest, UnsealError) {
126  EXPECT_CALL(mock_tpm_utility_, Unseal(_, _))
127      .WillRepeatedly(Return(false));
128  std::string key(32, 0);
129  std::string data;
130  EXPECT_TRUE(crypto_utility_->EncryptData("data", key, key, &data));
131  std::string output;
132  EXPECT_FALSE(crypto_utility_->UnsealKey(data, &output, &output));
133}
134
135TEST_F(CryptoUtilityImplTest, DecryptInvalidKey) {
136  std::string key(12, 0);
137  std::string output;
138  EXPECT_FALSE(crypto_utility_->DecryptData(std::string(), key, &output));
139}
140
141TEST_F(CryptoUtilityImplTest, DecryptInvalidData) {
142  std::string key(32, 0);
143  std::string output;
144  EXPECT_FALSE(crypto_utility_->DecryptData("invalid", key, &output));
145}
146
147TEST_F(CryptoUtilityImplTest, DecryptInvalidData2) {
148  std::string key(32, 0);
149  std::string output;
150  EncryptedData proto;
151  std::string input;
152  proto.SerializeToString(&input);
153  EXPECT_FALSE(crypto_utility_->DecryptData(input, key, &output));
154}
155
156TEST_F(CryptoUtilityImplTest, GetRSASubjectPublicKeyInfo) {
157  std::string public_key = HexDecode(kValidPublicKeyHex);
158  std::string output;
159  EXPECT_TRUE(crypto_utility_->GetRSASubjectPublicKeyInfo(public_key, &output));
160}
161
162TEST_F(CryptoUtilityImplTest, GetRSASubjectPublicKeyInfoBadInput) {
163  std::string public_key = "bad_public_key";
164  std::string output;
165  EXPECT_FALSE(crypto_utility_->GetRSASubjectPublicKeyInfo(public_key,
166                                                           &output));
167}
168
169TEST_F(CryptoUtilityImplTest, GetRSASubjectPublicKeyInfoPairWise) {
170  std::string public_key = HexDecode(kValidPublicKeyHex);
171  std::string output;
172  EXPECT_TRUE(crypto_utility_->GetRSASubjectPublicKeyInfo(public_key, &output));
173  std::string public_key2;
174  EXPECT_TRUE(crypto_utility_->GetRSAPublicKey(output, &public_key2));
175  EXPECT_EQ(public_key, public_key2);
176}
177
178TEST_F(CryptoUtilityImplTest, EncryptIdentityCredential) {
179  std::string public_key = HexDecode(kValidPublicKeyHex);
180  std::string public_key_info;
181  EXPECT_TRUE(crypto_utility_->GetRSASubjectPublicKeyInfo(public_key,
182                                                          &public_key_info));
183  EncryptedIdentityCredential output;
184  EXPECT_TRUE(crypto_utility_->EncryptIdentityCredential("credential",
185                                                         public_key_info,
186                                                         "aik",
187                                                         &output));
188  EXPECT_TRUE(output.has_asym_ca_contents());
189  EXPECT_TRUE(output.has_sym_ca_attestation());
190}
191
192TEST_F(CryptoUtilityImplTest, EncryptIdentityCredentialBadEK) {
193  EncryptedIdentityCredential output;
194  EXPECT_FALSE(crypto_utility_->EncryptIdentityCredential("credential",
195                                                          "bad_ek",
196                                                          "aik",
197                                                          &output));
198}
199
200TEST_F(CryptoUtilityImplTest, EncryptForUnbind) {
201  std::string public_key = HexDecode(kValidPublicKeyHex);
202  std::string public_key_info;
203  EXPECT_TRUE(crypto_utility_->GetRSASubjectPublicKeyInfo(public_key,
204                                                          &public_key_info));
205  std::string output;
206  EXPECT_TRUE(crypto_utility_->EncryptForUnbind(public_key_info, "input",
207                                                &output));
208  EXPECT_FALSE(output.empty());
209}
210
211TEST_F(CryptoUtilityImplTest, EncryptForUnbindBadKey) {
212  std::string output;
213  EXPECT_FALSE(crypto_utility_->EncryptForUnbind("bad_key", "input", &output));
214}
215
216TEST_F(CryptoUtilityImplTest, EncryptForUnbindLargeInput) {
217  std::string public_key = HexDecode(kValidPublicKeyHex);
218  std::string public_key_info;
219  EXPECT_TRUE(crypto_utility_->GetRSASubjectPublicKeyInfo(public_key,
220                                                          &public_key_info));
221  std::string input(1000, 'A');
222  std::string output;
223  EXPECT_FALSE(crypto_utility_->EncryptForUnbind(public_key_info, input,
224                                                 &output));
225}
226
227TEST_F(CryptoUtilityImplTest, VerifySignatureBadSignature) {
228  std::string public_key = HexDecode(kValidPublicKeyHex);
229  std::string public_key_info;
230  EXPECT_TRUE(crypto_utility_->GetRSASubjectPublicKeyInfo(public_key,
231                                                          &public_key_info));
232  std::string output;
233  EXPECT_FALSE(crypto_utility_->VerifySignature(public_key_info, "input",
234                                                "signature"));
235}
236
237TEST_F(CryptoUtilityImplTest, VerifySignatureBadKey) {
238  EXPECT_FALSE(crypto_utility_->VerifySignature("bad_key", "input", ""));
239}
240
241}  // namespace attestation
242