blob: 9ec27a2f71a9ee382cf73ca089b009ea7f57fe1a [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 Willden4db3fbd2014-08-08 22:13:44 -060040namespace test {
41
42class KeyBlobTest : public testing::Test {
43 protected:
44 KeyBlobTest()
45 : key_data_({21, 22, 23, 24, 25}),
46 master_key_data_({0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}),
47 nonce_({12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}) {
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_);
52
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
69 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_;
79 const uint8_t key_data_[5];
80 keymaster_key_blob_t master_key_;
81 const uint8_t master_key_data_[16];
82 uint8_t nonce_[KeyBlob::NONCE_LENGTH];
83};
84
85TEST_F(KeyBlobTest, EncryptDecrypt) {
Shawn Willden39b970b2014-08-11 09:11:21 -060086 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -060087 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -060088 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -060089
90 // key_data shouldn't be anywhere in the blob.
91 uint8_t* begin = serialized_blob.get();
92 uint8_t* end = begin + size;
93 EXPECT_EQ(end, std::search(begin, end, key_data_, key_data_ + array_size(key_data_)));
94
95 // Recover the key material.
96 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -060097 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -060098 EXPECT_EQ(KM_ERROR_OK, deserialized.error());
99 EXPECT_EQ(0, memcmp(deserialized.key_material(), key_data_, array_size(key_data_)));
100}
101
102TEST_F(KeyBlobTest, WrongKeyLength) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600103 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600104 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600105 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600106
Shawn Willden8d336ae2014-08-09 15:47:05 -0600107 // Modify the key length
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600108 serialized_blob[KeyBlob::NONCE_LENGTH]++;
109
110 // Decrypting with wrong nonce should fail.
111 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600112 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600113 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
114}
115
116TEST_F(KeyBlobTest, WrongNonce) {
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
121 // Find the nonce, then modify it.
122 uint8_t* begin = serialized_blob.get();
123 uint8_t* end = begin + size;
124 auto nonce_ptr = std::search(begin, end, nonce_, nonce_ + array_size(nonce_));
125 ASSERT_NE(nonce_ptr, end);
126 EXPECT_EQ(end, std::search(nonce_ptr + 1, end, nonce_, nonce_ + array_size(nonce_)));
127 (*nonce_ptr)++;
128
129 // Decrypting with wrong nonce should fail.
130 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600131 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600132 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
133 EXPECT_NE(0, memcmp(deserialized.key_material(), key_data_, array_size(key_data_)));
134}
135
136TEST_F(KeyBlobTest, WrongTag) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600137 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600138 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600139 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600140
141 // Find the tag, them modify it.
142 uint8_t* begin = serialized_blob.get();
143 uint8_t* end = begin + size;
Shawn Willden39b970b2014-08-11 09:11:21 -0600144 auto tag_ptr = std::search(begin, end, blob_->tag(), blob_->tag() + KeyBlob::TAG_LENGTH);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600145 ASSERT_NE(tag_ptr, end);
Shawn Willden39b970b2014-08-11 09:11:21 -0600146 EXPECT_EQ(end, std::search(tag_ptr + 1, end, blob_->tag(), blob_->tag() + KeyBlob::TAG_LENGTH));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600147 (*tag_ptr)++;
148
149 // Decrypting with wrong tag should fail.
150 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600151 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600152 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
153 EXPECT_NE(0, memcmp(deserialized.key_material(), key_data_, array_size(key_data_)));
154}
155
156TEST_F(KeyBlobTest, WrongCiphertext) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600157 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600158 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600159 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600160
161 // Find the ciphertext, them modify it.
162 uint8_t* begin = serialized_blob.get();
163 uint8_t* end = begin + size;
Shawn Willden39b970b2014-08-11 09:11:21 -0600164 auto ciphertext_ptr =
165 std::search(begin, end, blob_->encrypted_key_material(),
166 blob_->encrypted_key_material() + blob_->key_material_length());
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600167 ASSERT_NE(ciphertext_ptr, end);
Shawn Willden39b970b2014-08-11 09:11:21 -0600168 EXPECT_EQ(end, std::search(ciphertext_ptr + 1, end, blob_->encrypted_key_material(),
169 blob_->encrypted_key_material() + blob_->key_material_length()));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600170 (*ciphertext_ptr)++;
171
172 // Decrypting with wrong tag should fail.
173 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600174 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600175 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
176 EXPECT_NE(0, memcmp(deserialized.key_material(), key_data_, array_size(key_data_)));
177}
178
179TEST_F(KeyBlobTest, WrongMasterKey) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600180 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600181 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600182 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600183
184 uint8_t wrong_master_data[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
185 keymaster_key_blob_t wrong_master;
186 wrong_master.key_material = wrong_master_data;
187 wrong_master.key_material_size = array_size(wrong_master_data);
188
189 // Decrypting with wrong master key should fail.
190 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600191 KeyBlob deserialized(encrypted_blob, hidden_, wrong_master);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600192 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
193 EXPECT_NE(0, memcmp(deserialized.key_material(), key_data_, array_size(key_data_)));
194}
195
196TEST_F(KeyBlobTest, WrongEnforced) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600197 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600198 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600199 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600200 uint8_t* begin = serialized_blob.get();
201 uint8_t* end = begin + size;
202
Shawn Willden8d336ae2014-08-09 15:47:05 -0600203 // Find enforced serialization data and modify it.
204 size_t enforced_size = enforced_.SerializedSize();
205 UniquePtr<uint8_t[]> enforced_data(new uint8_t[enforced_size]);
206 enforced_.Serialize(enforced_data.get(), enforced_data.get() + enforced_size);
207
208 auto enforced_ptr =
209 std::search(begin, end, enforced_data.get(), enforced_data.get() + enforced_size);
210 ASSERT_NE(end, enforced_ptr);
211 EXPECT_EQ(end, std::search(enforced_ptr + 1, end, enforced_data.get(),
212 enforced_data.get() + enforced_size));
213 (*(enforced_ptr + enforced_size - 1))++;
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600214
215 // Decrypting with wrong unenforced data should fail.
216 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600217 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600218 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600219}
220
221TEST_F(KeyBlobTest, WrongUnenforced) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600222 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600223 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600224 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600225 uint8_t* begin = serialized_blob.get();
226 uint8_t* end = begin + size;
227
Shawn Willden8d336ae2014-08-09 15:47:05 -0600228 // Find unenforced serialization data and modify it.
229 size_t unenforced_size = unenforced_.SerializedSize();
230 UniquePtr<uint8_t[]> unenforced_data(new uint8_t[unenforced_size]);
231 unenforced_.Serialize(unenforced_data.get(), unenforced_data.get() + unenforced_size);
232
233 auto unenforced_ptr =
234 std::search(begin, end, unenforced_data.get(), unenforced_data.get() + unenforced_size);
235 ASSERT_NE(end, unenforced_ptr);
236 EXPECT_EQ(end, std::search(unenforced_ptr + 1, end, unenforced_data.get(),
237 unenforced_data.get() + unenforced_size));
238 (*(unenforced_ptr + unenforced_size - 1))++;
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600239
240 // Decrypting with wrong unenforced data should fail.
241 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden39b970b2014-08-11 09:11:21 -0600242 KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
243 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
244}
245
246TEST_F(KeyBlobTest, EmptyHidden) {
247 size_t size = blob_->SerializedSize();
248 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
249 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
250 uint8_t* begin = serialized_blob.get();
251 uint8_t* end = begin + size;
252
253 AuthorizationSet wrong_hidden;
254
255 // Decrypting with wrong hidden data should fail.
256 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
257 KeyBlob deserialized(encrypted_blob, wrong_hidden, master_key_);
258 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
259}
260
261TEST_F(KeyBlobTest, WrongRootOfTrust) {
262 size_t size = blob_->SerializedSize();
263 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
264 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
265 uint8_t* begin = serialized_blob.get();
266 uint8_t* end = begin + size;
267
268 AuthorizationSet wrong_hidden;
269 wrong_hidden.push_back(TAG_ROOT_OF_TRUST, "bar", 3);
270 wrong_hidden.push_back(TAG_APPLICATION_ID, "my_app", 6);
271
272 // Decrypting with wrong hidden data should fail.
273 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
274 KeyBlob deserialized(encrypted_blob, wrong_hidden, master_key_);
275 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
276}
277
278TEST_F(KeyBlobTest, WrongAppId) {
279 size_t size = blob_->SerializedSize();
280 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
281 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
282 uint8_t* begin = serialized_blob.get();
283 uint8_t* end = begin + size;
284
285 AuthorizationSet wrong_hidden;
286 wrong_hidden.push_back(TAG_ROOT_OF_TRUST, "foo", 3);
287 wrong_hidden.push_back(TAG_APPLICATION_ID, "your_app", 7);
288
289 // Decrypting with wrong hidden data should fail.
290 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
291 KeyBlob deserialized(encrypted_blob, wrong_hidden, master_key_);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600292 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600293}
294
295} // namespace test
296} // namespace keymaster