blob: fdc52e6787defc48103a91967169123775e59556 [file] [log] [blame]
Shawn Willden4db3fbd2014-08-08 22:13:44 -06001/*
2 * Copyright (C) 2014 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 <algorithm>
18
19#include <gtest/gtest.h>
20
21#include <openssl/engine.h>
22
23#define KEYMASTER_NAME_TAGS
24#include "authorization_set.h"
25#include "google_keymaster_utils.h"
26#include "keymaster_tags.h"
27#include "key_blob.h"
28
29int main(int argc, char** argv) {
30 ::testing::InitGoogleTest(&argc, argv);
31 int result = RUN_ALL_TESTS();
32 // Clean up stuff OpenSSL leaves around, so Valgrind doesn't complain.
33 CRYPTO_cleanup_all_ex_data();
34 ERR_free_strings();
35 return result;
36}
37
38namespace keymaster {
39
Shawn Willden834e8072014-08-09 16:38:53 -060040bool operator==(const AuthorizationSet& a, const AuthorizationSet& b);
Shawn Willden4db3fbd2014-08-08 22:13:44 -060041bool operator==(const AuthorizationSet& a, const AuthorizationSet& b) {
42 if (a.size() != b.size())
43 return false;
44
45 for (size_t i = 0; i < a.size(); ++i) {
46 if (a[i].tag != b[i].tag)
47 return false;
48 // TODO(check value)
49 }
50
51 return true;
52}
53
54namespace test {
55
56class KeyBlobTest : public testing::Test {
57 protected:
58 KeyBlobTest()
59 : key_data_({21, 22, 23, 24, 25}),
60 master_key_data_({0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}),
61 nonce_({12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}) {
62 key_.key_material = const_cast<uint8_t*>(key_data_);
63 key_.key_material_size = array_size(key_data_);
64 master_key_.key_material = const_cast<uint8_t*>(master_key_data_);
65 master_key_.key_material_size = array_size(master_key_data_);
66
67 enforced_.push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
68 enforced_.push_back(TAG_KEY_SIZE, 256);
69 enforced_.push_back(TAG_BLOB_USAGE_REQUIREMENTS, KM_BLOB_STANDALONE);
70 enforced_.push_back(TAG_MIN_SECONDS_BETWEEN_OPS, 10);
71 enforced_.push_back(TAG_ALL_USERS);
72 enforced_.push_back(TAG_NO_AUTH_REQUIRED);
73 enforced_.push_back(TAG_ORIGIN, KM_ORIGIN_HARDWARE);
Shawn Willden4db3fbd2014-08-08 22:13:44 -060074
75 unenforced_.push_back(TAG_ACTIVE_DATETIME, 10);
76 unenforced_.push_back(TAG_ORIGINATION_EXPIRE_DATETIME, 100);
77 unenforced_.push_back(TAG_CREATION_DATETIME, 10);
78 unenforced_.push_back(TAG_CHUNK_LENGTH, 10);
Shawn Willden39b970b2014-08-11 09:11:21 -060079
80 hidden_.push_back(TAG_ROOT_OF_TRUST, "foo", 3);
81 hidden_.push_back(TAG_APPLICATION_ID, "my_app", 6);
82
83 blob_.reset(new KeyBlob(enforced_, unenforced_, hidden_, key_, master_key_, nonce_));
Shawn Willden4db3fbd2014-08-08 22:13:44 -060084 }
85
86 AuthorizationSet enforced_;
87 AuthorizationSet unenforced_;
Shawn Willden39b970b2014-08-11 09:11:21 -060088 AuthorizationSet hidden_;
89
90 UniquePtr<KeyBlob> blob_;
Shawn Willden4db3fbd2014-08-08 22:13:44 -060091
92 keymaster_key_blob_t key_;
93 const uint8_t key_data_[5];
94 keymaster_key_blob_t master_key_;
95 const uint8_t master_key_data_[16];
96 uint8_t nonce_[KeyBlob::NONCE_LENGTH];
97};
98
99TEST_F(KeyBlobTest, EncryptDecrypt) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600100 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600101 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600102 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600103
104 // key_data shouldn't be anywhere in the blob.
105 uint8_t* begin = serialized_blob.get();
106 uint8_t* end = begin + size;
107 EXPECT_EQ(end, std::search(begin, end, key_data_, key_data_ + array_size(key_data_)));
108
109 // Recover the key material.
110 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600111 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600112 EXPECT_EQ(KM_ERROR_OK, deserialized.error());
113 EXPECT_EQ(0, memcmp(deserialized.key_material(), key_data_, array_size(key_data_)));
114}
115
116TEST_F(KeyBlobTest, WrongKeyLength) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600117 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600118 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600119 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600120
Shawn Willden8d336ae2014-08-09 15:47:05 -0600121 // Modify the key length
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600122 serialized_blob[KeyBlob::NONCE_LENGTH]++;
123
124 // Decrypting with wrong nonce should fail.
125 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600126 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600127 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
128}
129
130TEST_F(KeyBlobTest, WrongNonce) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600131 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600132 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600133 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600134
135 // Find the nonce, then modify it.
136 uint8_t* begin = serialized_blob.get();
137 uint8_t* end = begin + size;
138 auto nonce_ptr = std::search(begin, end, nonce_, nonce_ + array_size(nonce_));
139 ASSERT_NE(nonce_ptr, end);
140 EXPECT_EQ(end, std::search(nonce_ptr + 1, end, nonce_, nonce_ + array_size(nonce_)));
141 (*nonce_ptr)++;
142
143 // Decrypting with wrong nonce should fail.
144 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600145 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600146 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
147 EXPECT_NE(0, memcmp(deserialized.key_material(), key_data_, array_size(key_data_)));
148}
149
150TEST_F(KeyBlobTest, WrongTag) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600151 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600152 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600153 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600154
155 // Find the tag, them modify it.
156 uint8_t* begin = serialized_blob.get();
157 uint8_t* end = begin + size;
Shawn Willden39b970b2014-08-11 09:11:21 -0600158 auto tag_ptr = std::search(begin, end, blob_->tag(), blob_->tag() + KeyBlob::TAG_LENGTH);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600159 ASSERT_NE(tag_ptr, end);
Shawn Willden39b970b2014-08-11 09:11:21 -0600160 EXPECT_EQ(end, std::search(tag_ptr + 1, end, blob_->tag(), blob_->tag() + KeyBlob::TAG_LENGTH));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600161 (*tag_ptr)++;
162
163 // Decrypting with wrong tag should fail.
164 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600165 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600166 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
167 EXPECT_NE(0, memcmp(deserialized.key_material(), key_data_, array_size(key_data_)));
168}
169
170TEST_F(KeyBlobTest, WrongCiphertext) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600171 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600172 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600173 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600174
175 // Find the ciphertext, them modify it.
176 uint8_t* begin = serialized_blob.get();
177 uint8_t* end = begin + size;
Shawn Willden39b970b2014-08-11 09:11:21 -0600178 auto ciphertext_ptr =
179 std::search(begin, end, blob_->encrypted_key_material(),
180 blob_->encrypted_key_material() + blob_->key_material_length());
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600181 ASSERT_NE(ciphertext_ptr, end);
Shawn Willden39b970b2014-08-11 09:11:21 -0600182 EXPECT_EQ(end, std::search(ciphertext_ptr + 1, end, blob_->encrypted_key_material(),
183 blob_->encrypted_key_material() + blob_->key_material_length()));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600184 (*ciphertext_ptr)++;
185
186 // Decrypting with wrong tag should fail.
187 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600188 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600189 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
190 EXPECT_NE(0, memcmp(deserialized.key_material(), key_data_, array_size(key_data_)));
191}
192
193TEST_F(KeyBlobTest, WrongMasterKey) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600194 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600195 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600196 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600197
198 uint8_t wrong_master_data[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
199 keymaster_key_blob_t wrong_master;
200 wrong_master.key_material = wrong_master_data;
201 wrong_master.key_material_size = array_size(wrong_master_data);
202
203 // Decrypting with wrong master key should fail.
204 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600205 KeyBlob deserialized(encrypted_blob, hidden_, wrong_master);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600206 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
207 EXPECT_NE(0, memcmp(deserialized.key_material(), key_data_, array_size(key_data_)));
208}
209
210TEST_F(KeyBlobTest, WrongEnforced) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600211 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600212 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600213 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600214 uint8_t* begin = serialized_blob.get();
215 uint8_t* end = begin + size;
216
Shawn Willden8d336ae2014-08-09 15:47:05 -0600217 // Find enforced serialization data and modify it.
218 size_t enforced_size = enforced_.SerializedSize();
219 UniquePtr<uint8_t[]> enforced_data(new uint8_t[enforced_size]);
220 enforced_.Serialize(enforced_data.get(), enforced_data.get() + enforced_size);
221
222 auto enforced_ptr =
223 std::search(begin, end, enforced_data.get(), enforced_data.get() + enforced_size);
224 ASSERT_NE(end, enforced_ptr);
225 EXPECT_EQ(end, std::search(enforced_ptr + 1, end, enforced_data.get(),
226 enforced_data.get() + enforced_size));
227 (*(enforced_ptr + enforced_size - 1))++;
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600228
229 // Decrypting with wrong unenforced data should fail.
230 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600231 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600232 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600233}
234
235TEST_F(KeyBlobTest, WrongUnenforced) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600236 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600237 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600238 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600239 uint8_t* begin = serialized_blob.get();
240 uint8_t* end = begin + size;
241
Shawn Willden8d336ae2014-08-09 15:47:05 -0600242 // Find unenforced serialization data and modify it.
243 size_t unenforced_size = unenforced_.SerializedSize();
244 UniquePtr<uint8_t[]> unenforced_data(new uint8_t[unenforced_size]);
245 unenforced_.Serialize(unenforced_data.get(), unenforced_data.get() + unenforced_size);
246
247 auto unenforced_ptr =
248 std::search(begin, end, unenforced_data.get(), unenforced_data.get() + unenforced_size);
249 ASSERT_NE(end, unenforced_ptr);
250 EXPECT_EQ(end, std::search(unenforced_ptr + 1, end, unenforced_data.get(),
251 unenforced_data.get() + unenforced_size));
252 (*(unenforced_ptr + unenforced_size - 1))++;
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600253
254 // Decrypting with wrong unenforced data should fail.
255 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600256 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
257 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
258}
259
260TEST_F(KeyBlobTest, EmptyHidden) {
261 size_t size = blob_->SerializedSize();
262 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
263 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
264 uint8_t* begin = serialized_blob.get();
265 uint8_t* end = begin + size;
266
267 AuthorizationSet wrong_hidden;
268
269 // Decrypting with wrong hidden data should fail.
270 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
271 KeyBlob deserialized(encrypted_blob, wrong_hidden, master_key_);
272 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
273}
274
275TEST_F(KeyBlobTest, WrongRootOfTrust) {
276 size_t size = blob_->SerializedSize();
277 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
278 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
279 uint8_t* begin = serialized_blob.get();
280 uint8_t* end = begin + size;
281
282 AuthorizationSet wrong_hidden;
283 wrong_hidden.push_back(TAG_ROOT_OF_TRUST, "bar", 3);
284 wrong_hidden.push_back(TAG_APPLICATION_ID, "my_app", 6);
285
286 // Decrypting with wrong hidden data should fail.
287 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
288 KeyBlob deserialized(encrypted_blob, wrong_hidden, master_key_);
289 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
290}
291
292TEST_F(KeyBlobTest, WrongAppId) {
293 size_t size = blob_->SerializedSize();
294 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
295 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
296 uint8_t* begin = serialized_blob.get();
297 uint8_t* end = begin + size;
298
299 AuthorizationSet wrong_hidden;
300 wrong_hidden.push_back(TAG_ROOT_OF_TRUST, "foo", 3);
301 wrong_hidden.push_back(TAG_APPLICATION_ID, "your_app", 7);
302
303 // Decrypting with wrong hidden data should fail.
304 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
305 KeyBlob deserialized(encrypted_blob, wrong_hidden, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600306 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600307}
308
309} // namespace test
310} // namespace keymaster