blob: aae2584ade49676524370529f86576710c76857d [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 Willden98d9b922014-08-26 08:14:10 -060023#include <keymaster/authorization_set.h>
24#include <keymaster/google_keymaster_utils.h>
25#include <keymaster/keymaster_tags.h>
26
Shawn Willden72014ad2014-09-17 13:04:10 -060027#include "unencrypted_key_blob.h"
Shawn Willden4db3fbd2014-08-08 22:13:44 -060028
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
Shawn Willdenebf627f2014-08-12 11:15:29 -060042const uint8_t master_key_data[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
43const uint8_t key_data[5] = {21, 22, 23, 24, 25};
44const uint8_t nonce[KeyBlob::NONCE_LENGTH]{12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
45
Shawn Willden4db3fbd2014-08-08 22:13:44 -060046class KeyBlobTest : public testing::Test {
47 protected:
Shawn Willdenebf627f2014-08-12 11:15:29 -060048 KeyBlobTest() {
Shawn Willden4db3fbd2014-08-08 22:13:44 -060049 enforced_.push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
50 enforced_.push_back(TAG_KEY_SIZE, 256);
51 enforced_.push_back(TAG_BLOB_USAGE_REQUIREMENTS, KM_BLOB_STANDALONE);
52 enforced_.push_back(TAG_MIN_SECONDS_BETWEEN_OPS, 10);
53 enforced_.push_back(TAG_ALL_USERS);
54 enforced_.push_back(TAG_NO_AUTH_REQUIRED);
55 enforced_.push_back(TAG_ORIGIN, KM_ORIGIN_HARDWARE);
Shawn Willden4db3fbd2014-08-08 22:13:44 -060056
57 unenforced_.push_back(TAG_ACTIVE_DATETIME, 10);
58 unenforced_.push_back(TAG_ORIGINATION_EXPIRE_DATETIME, 100);
59 unenforced_.push_back(TAG_CREATION_DATETIME, 10);
60 unenforced_.push_back(TAG_CHUNK_LENGTH, 10);
Shawn Willden39b970b2014-08-11 09:11:21 -060061
62 hidden_.push_back(TAG_ROOT_OF_TRUST, "foo", 3);
63 hidden_.push_back(TAG_APPLICATION_ID, "my_app", 6);
64
Shawn Willden72014ad2014-09-17 13:04:10 -060065 blob_.reset(new UnencryptedKeyBlob(enforced_, unenforced_, hidden_, key_data,
66 array_size(key_data), master_key_data,
67 array_size(master_key_data), nonce));
Shawn Willden4db3fbd2014-08-08 22:13:44 -060068 }
69
70 AuthorizationSet enforced_;
71 AuthorizationSet unenforced_;
Shawn Willden39b970b2014-08-11 09:11:21 -060072 AuthorizationSet hidden_;
73
Shawn Willden72014ad2014-09-17 13:04:10 -060074 UniquePtr<UnencryptedKeyBlob> blob_;
Shawn Willden4db3fbd2014-08-08 22:13:44 -060075};
76
77TEST_F(KeyBlobTest, EncryptDecrypt) {
Shawn Willden39b970b2014-08-11 09:11:21 -060078 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -060079 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -060080 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -060081
82 // key_data shouldn't be anywhere in the blob.
83 uint8_t* begin = serialized_blob.get();
84 uint8_t* end = begin + size;
Shawn Willdenebf627f2014-08-12 11:15:29 -060085 EXPECT_EQ(end, std::search(begin, end, key_data, key_data + array_size(key_data)));
Shawn Willden4db3fbd2014-08-08 22:13:44 -060086
87 // Recover the key material.
88 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden72014ad2014-09-17 13:04:10 -060089 UnencryptedKeyBlob deserialized(encrypted_blob, hidden_, master_key_data,
90 array_size(master_key_data));
Shawn Willden4db3fbd2014-08-08 22:13:44 -060091 EXPECT_EQ(KM_ERROR_OK, deserialized.error());
Shawn Willden72014ad2014-09-17 13:04:10 -060092 EXPECT_EQ(0, memcmp(deserialized.unencrypted_key_material(), key_data, array_size(key_data)));
Shawn Willden4db3fbd2014-08-08 22:13:44 -060093}
94
95TEST_F(KeyBlobTest, WrongKeyLength) {
Shawn Willden39b970b2014-08-11 09:11:21 -060096 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -060097 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -060098 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -060099
Shawn Willden8d336ae2014-08-09 15:47:05 -0600100 // Modify the key length
Shawn Willden72014ad2014-09-17 13:04:10 -0600101 serialized_blob[UnencryptedKeyBlob::NONCE_LENGTH]++;
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600102
103 // Decrypting with wrong nonce should fail.
104 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden72014ad2014-09-17 13:04:10 -0600105 UnencryptedKeyBlob deserialized(encrypted_blob, hidden_, master_key_data,
106 array_size(master_key_data));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600107 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
108}
109
110TEST_F(KeyBlobTest, WrongNonce) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600111 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600112 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600113 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600114
115 // Find the nonce, then modify it.
116 uint8_t* begin = serialized_blob.get();
117 uint8_t* end = begin + size;
Shawn Willdenebf627f2014-08-12 11:15:29 -0600118 auto nonce_ptr = std::search(begin, end, nonce, nonce + array_size(nonce));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600119 ASSERT_NE(nonce_ptr, end);
Shawn Willdenebf627f2014-08-12 11:15:29 -0600120 EXPECT_EQ(end, std::search(nonce_ptr + 1, end, nonce, nonce + array_size(nonce)));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600121 (*nonce_ptr)++;
122
123 // Decrypting with wrong nonce should fail.
124 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden72014ad2014-09-17 13:04:10 -0600125 UnencryptedKeyBlob deserialized(encrypted_blob, hidden_, master_key_data,
126 array_size(master_key_data));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600127 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
Shawn Willden72014ad2014-09-17 13:04:10 -0600128 EXPECT_NE(0, memcmp(deserialized.unencrypted_key_material(), key_data, array_size(key_data)));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600129}
130
131TEST_F(KeyBlobTest, WrongTag) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600132 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600133 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600134 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600135
136 // Find the tag, them modify it.
137 uint8_t* begin = serialized_blob.get();
138 uint8_t* end = begin + size;
Shawn Willden72014ad2014-09-17 13:04:10 -0600139 auto tag_ptr =
140 std::search(begin, end, blob_->tag(), blob_->tag() + UnencryptedKeyBlob::TAG_LENGTH);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600141 ASSERT_NE(tag_ptr, end);
Shawn Willden72014ad2014-09-17 13:04:10 -0600142 EXPECT_EQ(end, std::search(tag_ptr + 1, end, blob_->tag(),
143 blob_->tag() + UnencryptedKeyBlob::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 Willden72014ad2014-09-17 13:04:10 -0600148 UnencryptedKeyBlob deserialized(encrypted_blob, hidden_, master_key_data,
149 array_size(master_key_data));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600150 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
Shawn Willden72014ad2014-09-17 13:04:10 -0600151 EXPECT_NE(0, memcmp(deserialized.unencrypted_key_material(), key_data, array_size(key_data)));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600152}
153
154TEST_F(KeyBlobTest, WrongCiphertext) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600155 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600156 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600157 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600158
159 // Find the ciphertext, them modify it.
160 uint8_t* begin = serialized_blob.get();
161 uint8_t* end = begin + size;
Shawn Willden39b970b2014-08-11 09:11:21 -0600162 auto ciphertext_ptr =
163 std::search(begin, end, blob_->encrypted_key_material(),
164 blob_->encrypted_key_material() + blob_->key_material_length());
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600165 ASSERT_NE(ciphertext_ptr, end);
Shawn Willden39b970b2014-08-11 09:11:21 -0600166 EXPECT_EQ(end, std::search(ciphertext_ptr + 1, end, blob_->encrypted_key_material(),
167 blob_->encrypted_key_material() + blob_->key_material_length()));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600168 (*ciphertext_ptr)++;
169
170 // Decrypting with wrong tag should fail.
171 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden72014ad2014-09-17 13:04:10 -0600172 UnencryptedKeyBlob deserialized(encrypted_blob, hidden_, master_key_data,
173 array_size(master_key_data));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600174 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
Shawn Willden72014ad2014-09-17 13:04:10 -0600175 EXPECT_NE(0, memcmp(deserialized.unencrypted_key_material(), key_data, array_size(key_data)));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600176}
177
178TEST_F(KeyBlobTest, WrongMasterKey) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600179 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600180 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600181 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600182
183 uint8_t wrong_master_data[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600184
185 // Decrypting with wrong master key should fail.
186 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden72014ad2014-09-17 13:04:10 -0600187 UnencryptedKeyBlob deserialized(encrypted_blob, hidden_, wrong_master_data,
188 array_size(wrong_master_data));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600189 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
Shawn Willden72014ad2014-09-17 13:04:10 -0600190 EXPECT_NE(0, memcmp(deserialized.unencrypted_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 Willden72014ad2014-09-17 13:04:10 -0600214 UnencryptedKeyBlob deserialized(encrypted_blob, hidden_, master_key_data,
215 array_size(master_key_data));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600216 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600217}
218
219TEST_F(KeyBlobTest, WrongUnenforced) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600220 size_t size = blob_->SerializedSize();
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600221 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
Shawn Willden39b970b2014-08-11 09:11:21 -0600222 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600223 uint8_t* begin = serialized_blob.get();
224 uint8_t* end = begin + size;
225
Shawn Willden8d336ae2014-08-09 15:47:05 -0600226 // Find unenforced serialization data and modify it.
227 size_t unenforced_size = unenforced_.SerializedSize();
228 UniquePtr<uint8_t[]> unenforced_data(new uint8_t[unenforced_size]);
229 unenforced_.Serialize(unenforced_data.get(), unenforced_data.get() + unenforced_size);
230
231 auto unenforced_ptr =
232 std::search(begin, end, unenforced_data.get(), unenforced_data.get() + unenforced_size);
233 ASSERT_NE(end, unenforced_ptr);
234 EXPECT_EQ(end, std::search(unenforced_ptr + 1, end, unenforced_data.get(),
235 unenforced_data.get() + unenforced_size));
236 (*(unenforced_ptr + unenforced_size - 1))++;
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600237
238 // Decrypting with wrong unenforced data should fail.
239 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden72014ad2014-09-17 13:04:10 -0600240 UnencryptedKeyBlob deserialized(encrypted_blob, hidden_, master_key_data,
241 array_size(master_key_data));
Shawn Willden39b970b2014-08-11 09:11:21 -0600242 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
243}
244
245TEST_F(KeyBlobTest, EmptyHidden) {
246 size_t size = blob_->SerializedSize();
247 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
248 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
249 uint8_t* begin = serialized_blob.get();
250 uint8_t* end = begin + size;
251
252 AuthorizationSet wrong_hidden;
253
254 // Decrypting with wrong hidden data should fail.
255 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden72014ad2014-09-17 13:04:10 -0600256 UnencryptedKeyBlob deserialized(encrypted_blob, wrong_hidden, master_key_data,
257 array_size(master_key_data));
Shawn Willden39b970b2014-08-11 09:11:21 -0600258 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};
Shawn Willden72014ad2014-09-17 13:04:10 -0600274 UnencryptedKeyBlob deserialized(encrypted_blob, wrong_hidden, master_key_data,
275 array_size(master_key_data));
Shawn Willden39b970b2014-08-11 09:11:21 -0600276 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
277}
278
279TEST_F(KeyBlobTest, WrongAppId) {
280 size_t size = blob_->SerializedSize();
281 UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
282 blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
283 uint8_t* begin = serialized_blob.get();
284 uint8_t* end = begin + size;
285
286 AuthorizationSet wrong_hidden;
287 wrong_hidden.push_back(TAG_ROOT_OF_TRUST, "foo", 3);
288 wrong_hidden.push_back(TAG_APPLICATION_ID, "your_app", 7);
289
290 // Decrypting with wrong hidden data should fail.
291 keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
Shawn Willden72014ad2014-09-17 13:04:10 -0600292 UnencryptedKeyBlob deserialized(encrypted_blob, wrong_hidden, master_key_data,
293 array_size(master_key_data));
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600294 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
Shawn Willden4db3fbd2014-08-08 22:13:44 -0600295}
296
297} // namespace test
298} // namespace keymaster