blob: f29fcb69aafe46288ae6839a0a87d852a063905d [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
Shawn Willden4db3fbd2014-08-08 22:13:44 -060023#include "authorization_set.h"
24#include "google_keymaster_utils.h"
25#include "keymaster_tags.h"
26#include "key_blob.h"
27
28int main(int argc, char** argv) {
29 ::testing::InitGoogleTest(&argc, argv);
30 int result = RUN_ALL_TESTS();
31 // Clean up stuff OpenSSL leaves around, so Valgrind doesn't complain.
32 CRYPTO_cleanup_all_ex_data();
33 ERR_free_strings();
34 return result;
35}
36
37namespace keymaster {
38
Shawn Willden4db3fbd2014-08-08 22:13:44 -060039namespace test {
40
Shawn Willdenebf627f2014-08-12 11:15:29 -060041const uint8_t master_key_data[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
42const uint8_t key_data[5] = {21, 22, 23, 24, 25};
43const uint8_t nonce[KeyBlob::NONCE_LENGTH]{12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
44
Shawn Willden4db3fbd2014-08-08 22:13:44 -060045class KeyBlobTest : public testing::Test {
46 protected:
Shawn Willdenebf627f2014-08-12 11:15:29 -060047 KeyBlobTest() {
48 key_.key_material = const_cast<uint8_t*>(key_data);
49 key_.key_material_size = array_size(key_data);
50 master_key_.key_material = const_cast<uint8_t*>(master_key_data);
51 master_key_.key_material_size = array_size(master_key_data);
Shawn Willden4db3fbd2014-08-08 22:13:44 -060052
53 enforced_.push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
54 enforced_.push_back(TAG_KEY_SIZE, 256);
55 enforced_.push_back(TAG_BLOB_USAGE_REQUIREMENTS, KM_BLOB_STANDALONE);
56 enforced_.push_back(TAG_MIN_SECONDS_BETWEEN_OPS, 10);
57 enforced_.push_back(TAG_ALL_USERS);
58 enforced_.push_back(TAG_NO_AUTH_REQUIRED);
59 enforced_.push_back(TAG_ORIGIN, KM_ORIGIN_HARDWARE);
Shawn Willden4db3fbd2014-08-08 22:13:44 -060060
61 unenforced_.push_back(TAG_ACTIVE_DATETIME, 10);
62 unenforced_.push_back(TAG_ORIGINATION_EXPIRE_DATETIME, 100);
63 unenforced_.push_back(TAG_CREATION_DATETIME, 10);
64 unenforced_.push_back(TAG_CHUNK_LENGTH, 10);
Shawn Willden39b970b2014-08-11 09:11:21 -060065
66 hidden_.push_back(TAG_ROOT_OF_TRUST, "foo", 3);
67 hidden_.push_back(TAG_APPLICATION_ID, "my_app", 6);
68
Shawn Willdenebf627f2014-08-12 11:15:29 -060069 blob_.reset(new KeyBlob(enforced_, unenforced_, hidden_, key_, master_key_, nonce));
Shawn Willden4db3fbd2014-08-08 22:13:44 -060070 }
71
72 AuthorizationSet enforced_;
73 AuthorizationSet unenforced_;
Shawn Willden39b970b2014-08-11 09:11:21 -060074 AuthorizationSet hidden_;
75
76 UniquePtr<KeyBlob> blob_;
Shawn Willden4db3fbd2014-08-08 22:13:44 -060077
78 keymaster_key_blob_t key_;
Shawn Willden4db3fbd2014-08-08 22:13:44 -060079 keymaster_key_blob_t master_key_;
Shawn Willden4db3fbd2014-08-08 22:13:44 -060080};
81
82TEST_F(KeyBlobTest, EncryptDecrypt) {
Shawn Willden39b970b2014-08-11 09:11:21 -060083 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -060084 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -060085 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -060086
87 // key_data shouldn't be anywhere in the blob.
88 uint8_t* begin = serialized_blob.get();
89 uint8_t* end = begin + size;
Shawn Willdenebf627f2014-08-12 11:15:29 -060090 EXPECT_EQ(end, std::search(begin, end, key_data, key_data + array_size(key_data)));
Shawn Willden4db3fbd2014-08-08 22:13:44 -060091
92 // Recover the key material.
93 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -060094 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -060095 EXPECT_EQ(KM_ERROR_OK, deserialized.error());
Shawn Willdenebf627f2014-08-12 11:15:29 -060096 EXPECT_EQ(0, memcmp(deserialized.key_material(), key_data, array_size(key_data)));
Shawn Willden4db3fbd2014-08-08 22:13:44 -060097}
98
99TEST_F(KeyBlobTest, WrongKeyLength) {
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
Shawn Willden8d336ae2014-08-09 15:47:05 -0600104 // Modify the key length
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600105 serialized_blob[KeyBlob::NONCE_LENGTH]++;
106
107 // Decrypting with wrong nonce should fail.
108 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600109 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600110 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
111}
112
113TEST_F(KeyBlobTest, WrongNonce) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600114 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600115 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600116 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600117
118 // Find the nonce, then modify it.
119 uint8_t* begin = serialized_blob.get();
120 uint8_t* end = begin + size;
Shawn Willdenebf627f2014-08-12 11:15:29 -0600121 auto nonce_ptr = std::search(begin, end, nonce, nonce + array_size(nonce));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600122 ASSERT_NE(nonce_ptr, end);
Shawn Willdenebf627f2014-08-12 11:15:29 -0600123 EXPECT_EQ(end, std::search(nonce_ptr + 1, end, nonce, nonce + array_size(nonce)));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600124 (*nonce_ptr)++;
125
126 // Decrypting with wrong nonce should fail.
127 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600128 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600129 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
Shawn Willdenebf627f2014-08-12 11:15:29 -0600130 EXPECT_NE(0, memcmp(deserialized.key_material(), key_data, array_size(key_data)));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600131}
132
133TEST_F(KeyBlobTest, WrongTag) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600134 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600135 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600136 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600137
138 // Find the tag, them modify it.
139 uint8_t* begin = serialized_blob.get();
140 uint8_t* end = begin + size;
Shawn Willden39b970b2014-08-11 09:11:21 -0600141 auto tag_ptr = std::search(begin, end, blob_->tag(), blob_->tag() + KeyBlob::TAG_LENGTH);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600142 ASSERT_NE(tag_ptr, end);
Shawn Willden39b970b2014-08-11 09:11:21 -0600143 EXPECT_EQ(end, std::search(tag_ptr + 1, end, blob_->tag(), blob_->tag() + KeyBlob::TAG_LENGTH));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600144 (*tag_ptr)++;
145
146 // Decrypting with wrong tag should fail.
147 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600148 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600149 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
Shawn Willdenebf627f2014-08-12 11:15:29 -0600150 EXPECT_NE(0, memcmp(deserialized.key_material(), key_data, array_size(key_data)));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600151}
152
153TEST_F(KeyBlobTest, WrongCiphertext) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600154 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600155 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600156 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600157
158 // Find the ciphertext, them modify it.
159 uint8_t* begin = serialized_blob.get();
160 uint8_t* end = begin + size;
Shawn Willden39b970b2014-08-11 09:11:21 -0600161 auto ciphertext_ptr =
162 std::search(begin, end, blob_->encrypted_key_material(),
163 blob_->encrypted_key_material() + blob_->key_material_length());
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600164 ASSERT_NE(ciphertext_ptr, end);
Shawn Willden39b970b2014-08-11 09:11:21 -0600165 EXPECT_EQ(end, std::search(ciphertext_ptr + 1, end, blob_->encrypted_key_material(),
166 blob_->encrypted_key_material() + blob_->key_material_length()));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600167 (*ciphertext_ptr)++;
168
169 // Decrypting with wrong tag should fail.
170 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600171 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600172 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
Shawn Willdenebf627f2014-08-12 11:15:29 -0600173 EXPECT_NE(0, memcmp(deserialized.key_material(), key_data, array_size(key_data)));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600174}
175
176TEST_F(KeyBlobTest, WrongMasterKey) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600177 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600178 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600179 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600180
181 uint8_t wrong_master_data[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
182 keymaster_key_blob_t wrong_master;
183 wrong_master.key_material = wrong_master_data;
184 wrong_master.key_material_size = array_size(wrong_master_data);
185
186 // Decrypting with wrong master key 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_, wrong_master);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600189 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
Shawn Willdenebf627f2014-08-12 11:15:29 -0600190 EXPECT_NE(0, memcmp(deserialized.key_material(), key_data, array_size(key_data)));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600191}
192
193TEST_F(KeyBlobTest, WrongEnforced) {
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 uint8_t* begin = serialized_blob.get();
198 uint8_t* end = begin + size;
199
Shawn Willden8d336ae2014-08-09 15:47:05 -0600200 // Find enforced serialization data and modify it.
201 size_t enforced_size = enforced_.SerializedSize();
202 UniquePtr<uint8_t[]> enforced_data(new uint8_t[enforced_size]);
203 enforced_.Serialize(enforced_data.get(), enforced_data.get() + enforced_size);
204
205 auto enforced_ptr =
206 std::search(begin, end, enforced_data.get(), enforced_data.get() + enforced_size);
207 ASSERT_NE(end, enforced_ptr);
208 EXPECT_EQ(end, std::search(enforced_ptr + 1, end, enforced_data.get(),
209 enforced_data.get() + enforced_size));
210 (*(enforced_ptr + enforced_size - 1))++;
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600211
212 // Decrypting with wrong unenforced data should fail.
213 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600214 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600215 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600216}
217
218TEST_F(KeyBlobTest, WrongUnenforced) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600219 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600220 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600221 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600222 uint8_t* begin = serialized_blob.get();
223 uint8_t* end = begin + size;
224
Shawn Willden8d336ae2014-08-09 15:47:05 -0600225 // Find unenforced serialization data and modify it.
226 size_t unenforced_size = unenforced_.SerializedSize();
227 UniquePtr<uint8_t[]> unenforced_data(new uint8_t[unenforced_size]);
228 unenforced_.Serialize(unenforced_data.get(), unenforced_data.get() + unenforced_size);
229
230 auto unenforced_ptr =
231 std::search(begin, end, unenforced_data.get(), unenforced_data.get() + unenforced_size);
232 ASSERT_NE(end, unenforced_ptr);
233 EXPECT_EQ(end, std::search(unenforced_ptr + 1, end, unenforced_data.get(),
234 unenforced_data.get() + unenforced_size));
235 (*(unenforced_ptr + unenforced_size - 1))++;
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600236
237 // Decrypting with wrong unenforced data should fail.
238 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600239 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
240 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
241}
242
243TEST_F(KeyBlobTest, EmptyHidden) {
244 size_t size = blob_->SerializedSize();
245 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
246 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
247 uint8_t* begin = serialized_blob.get();
248 uint8_t* end = begin + size;
249
250 AuthorizationSet wrong_hidden;
251
252 // Decrypting with wrong hidden data should fail.
253 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
254 KeyBlob deserialized(encrypted_blob, wrong_hidden, master_key_);
255 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
256}
257
258TEST_F(KeyBlobTest, WrongRootOfTrust) {
259 size_t size = blob_->SerializedSize();
260 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
261 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
262 uint8_t* begin = serialized_blob.get();
263 uint8_t* end = begin + size;
264
265 AuthorizationSet wrong_hidden;
266 wrong_hidden.push_back(TAG_ROOT_OF_TRUST, "bar", 3);
267 wrong_hidden.push_back(TAG_APPLICATION_ID, "my_app", 6);
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, WrongAppId) {
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, "foo", 3);
284 wrong_hidden.push_back(TAG_APPLICATION_ID, "your_app", 7);
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_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600289 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600290}
291
292} // namespace test
293} // namespace keymaster