• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 #include <keymaster/authorization_set.h>
24 #include <keymaster/google_keymaster_utils.h>
25 #include <keymaster/keymaster_tags.h>
26 
27 #include <keymaster/key_blob.h>
28 
main(int argc,char ** argv)29 int 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 
38 namespace keymaster {
39 
40 namespace test {
41 
42 const uint8_t master_key_data[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
43 const uint8_t key_data[5] = {21, 22, 23, 24, 25};
44 const uint8_t nonce[KeyBlob::NONCE_LENGTH]{12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
45 
46 class KeyBlobTest : public testing::Test {
47   protected:
KeyBlobTest()48     KeyBlobTest() {
49         key_.key_material = const_cast<uint8_t*>(key_data);
50         key_.key_material_size = array_size(key_data);
51         master_key_.key_material = const_cast<uint8_t*>(master_key_data);
52         master_key_.key_material_size = array_size(master_key_data);
53 
54         enforced_.push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
55         enforced_.push_back(TAG_KEY_SIZE, 256);
56         enforced_.push_back(TAG_BLOB_USAGE_REQUIREMENTS, KM_BLOB_STANDALONE);
57         enforced_.push_back(TAG_MIN_SECONDS_BETWEEN_OPS, 10);
58         enforced_.push_back(TAG_ALL_USERS);
59         enforced_.push_back(TAG_NO_AUTH_REQUIRED);
60         enforced_.push_back(TAG_ORIGIN, KM_ORIGIN_HARDWARE);
61 
62         unenforced_.push_back(TAG_ACTIVE_DATETIME, 10);
63         unenforced_.push_back(TAG_ORIGINATION_EXPIRE_DATETIME, 100);
64         unenforced_.push_back(TAG_CREATION_DATETIME, 10);
65         unenforced_.push_back(TAG_CHUNK_LENGTH, 10);
66 
67         hidden_.push_back(TAG_ROOT_OF_TRUST, "foo", 3);
68         hidden_.push_back(TAG_APPLICATION_ID, "my_app", 6);
69 
70         blob_.reset(new KeyBlob(enforced_, unenforced_, hidden_, key_, master_key_, nonce));
71     }
72 
73     AuthorizationSet enforced_;
74     AuthorizationSet unenforced_;
75     AuthorizationSet hidden_;
76 
77     UniquePtr<KeyBlob> blob_;
78 
79     keymaster_key_blob_t key_;
80     keymaster_key_blob_t master_key_;
81 };
82 
TEST_F(KeyBlobTest,EncryptDecrypt)83 TEST_F(KeyBlobTest, EncryptDecrypt) {
84     size_t size = blob_->SerializedSize();
85     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
86     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
87 
88     // key_data shouldn't be anywhere in the blob.
89     uint8_t* begin = serialized_blob.get();
90     uint8_t* end = begin + size;
91     EXPECT_EQ(end, std::search(begin, end, key_data, key_data + array_size(key_data)));
92 
93     // Recover the key material.
94     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
95     KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
96     EXPECT_EQ(KM_ERROR_OK, deserialized.error());
97     EXPECT_EQ(0, memcmp(deserialized.key_material(), key_data, array_size(key_data)));
98 }
99 
TEST_F(KeyBlobTest,WrongKeyLength)100 TEST_F(KeyBlobTest, WrongKeyLength) {
101     size_t size = blob_->SerializedSize();
102     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
103     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
104 
105     // Modify the key length
106     serialized_blob[KeyBlob::NONCE_LENGTH]++;
107 
108     // Decrypting with wrong nonce should fail.
109     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
110     KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
111     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
112 }
113 
TEST_F(KeyBlobTest,WrongNonce)114 TEST_F(KeyBlobTest, WrongNonce) {
115     size_t size = blob_->SerializedSize();
116     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
117     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
118 
119     // Find the nonce, then modify it.
120     uint8_t* begin = serialized_blob.get();
121     uint8_t* end = begin + size;
122     auto nonce_ptr = std::search(begin, end, nonce, nonce + array_size(nonce));
123     ASSERT_NE(nonce_ptr, end);
124     EXPECT_EQ(end, std::search(nonce_ptr + 1, end, nonce, nonce + array_size(nonce)));
125     (*nonce_ptr)++;
126 
127     // Decrypting with wrong nonce should fail.
128     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
129     KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
130     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
131     EXPECT_NE(0, memcmp(deserialized.key_material(), key_data, array_size(key_data)));
132 }
133 
TEST_F(KeyBlobTest,WrongTag)134 TEST_F(KeyBlobTest, WrongTag) {
135     size_t size = blob_->SerializedSize();
136     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
137     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
138 
139     // Find the tag, them modify it.
140     uint8_t* begin = serialized_blob.get();
141     uint8_t* end = begin + size;
142     auto tag_ptr = std::search(begin, end, blob_->tag(), blob_->tag() + KeyBlob::TAG_LENGTH);
143     ASSERT_NE(tag_ptr, end);
144     EXPECT_EQ(end, std::search(tag_ptr + 1, end, blob_->tag(), blob_->tag() + KeyBlob::TAG_LENGTH));
145     (*tag_ptr)++;
146 
147     // Decrypting with wrong tag should fail.
148     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
149     KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
150     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
151     EXPECT_NE(0, memcmp(deserialized.key_material(), key_data, array_size(key_data)));
152 }
153 
TEST_F(KeyBlobTest,WrongCiphertext)154 TEST_F(KeyBlobTest, WrongCiphertext) {
155     size_t size = blob_->SerializedSize();
156     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
157     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
158 
159     // Find the ciphertext, them modify it.
160     uint8_t* begin = serialized_blob.get();
161     uint8_t* end = begin + size;
162     auto ciphertext_ptr =
163         std::search(begin, end, blob_->encrypted_key_material(),
164                     blob_->encrypted_key_material() + blob_->key_material_length());
165     ASSERT_NE(ciphertext_ptr, end);
166     EXPECT_EQ(end, std::search(ciphertext_ptr + 1, end, blob_->encrypted_key_material(),
167                                blob_->encrypted_key_material() + blob_->key_material_length()));
168     (*ciphertext_ptr)++;
169 
170     // Decrypting with wrong tag should fail.
171     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
172     KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
173     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
174     EXPECT_NE(0, memcmp(deserialized.key_material(), key_data, array_size(key_data)));
175 }
176 
TEST_F(KeyBlobTest,WrongMasterKey)177 TEST_F(KeyBlobTest, WrongMasterKey) {
178     size_t size = blob_->SerializedSize();
179     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
180     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
181 
182     uint8_t wrong_master_data[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
183     keymaster_key_blob_t wrong_master;
184     wrong_master.key_material = wrong_master_data;
185     wrong_master.key_material_size = array_size(wrong_master_data);
186 
187     // Decrypting with wrong master key should fail.
188     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
189     KeyBlob deserialized(encrypted_blob, hidden_, wrong_master);
190     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
191     EXPECT_NE(0, memcmp(deserialized.key_material(), key_data, array_size(key_data)));
192 }
193 
TEST_F(KeyBlobTest,WrongEnforced)194 TEST_F(KeyBlobTest, WrongEnforced) {
195     size_t size = blob_->SerializedSize();
196     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
197     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
198     uint8_t* begin = serialized_blob.get();
199     uint8_t* end = begin + size;
200 
201     // Find enforced serialization data and modify it.
202     size_t enforced_size = enforced_.SerializedSize();
203     UniquePtr<uint8_t[]> enforced_data(new uint8_t[enforced_size]);
204     enforced_.Serialize(enforced_data.get(), enforced_data.get() + enforced_size);
205 
206     auto enforced_ptr =
207         std::search(begin, end, enforced_data.get(), enforced_data.get() + enforced_size);
208     ASSERT_NE(end, enforced_ptr);
209     EXPECT_EQ(end, std::search(enforced_ptr + 1, end, enforced_data.get(),
210                                enforced_data.get() + enforced_size));
211     (*(enforced_ptr + enforced_size - 1))++;
212 
213     // Decrypting with wrong unenforced data should fail.
214     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
215     KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
216     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
217 }
218 
TEST_F(KeyBlobTest,WrongUnenforced)219 TEST_F(KeyBlobTest, WrongUnenforced) {
220     size_t size = blob_->SerializedSize();
221     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
222     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
223     uint8_t* begin = serialized_blob.get();
224     uint8_t* end = begin + size;
225 
226     // 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))++;
237 
238     // Decrypting with wrong unenforced data should fail.
239     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
240     KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
241     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
242 }
243 
TEST_F(KeyBlobTest,EmptyHidden)244 TEST_F(KeyBlobTest, EmptyHidden) {
245     size_t size = blob_->SerializedSize();
246     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
247     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
248     uint8_t* begin = serialized_blob.get();
249     uint8_t* end = begin + size;
250 
251     AuthorizationSet wrong_hidden;
252 
253     // Decrypting with wrong hidden data should fail.
254     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
255     KeyBlob deserialized(encrypted_blob, wrong_hidden, master_key_);
256     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
257 }
258 
TEST_F(KeyBlobTest,WrongRootOfTrust)259 TEST_F(KeyBlobTest, WrongRootOfTrust) {
260     size_t size = blob_->SerializedSize();
261     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
262     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
263     uint8_t* begin = serialized_blob.get();
264     uint8_t* end = begin + size;
265 
266     AuthorizationSet wrong_hidden;
267     wrong_hidden.push_back(TAG_ROOT_OF_TRUST, "bar", 3);
268     wrong_hidden.push_back(TAG_APPLICATION_ID, "my_app", 6);
269 
270     // Decrypting with wrong hidden data should fail.
271     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
272     KeyBlob deserialized(encrypted_blob, wrong_hidden, master_key_);
273     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
274 }
275 
TEST_F(KeyBlobTest,WrongAppId)276 TEST_F(KeyBlobTest, WrongAppId) {
277     size_t size = blob_->SerializedSize();
278     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
279     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
280     uint8_t* begin = serialized_blob.get();
281     uint8_t* end = begin + size;
282 
283     AuthorizationSet wrong_hidden;
284     wrong_hidden.push_back(TAG_ROOT_OF_TRUST, "foo", 3);
285     wrong_hidden.push_back(TAG_APPLICATION_ID, "your_app", 7);
286 
287     // Decrypting with wrong hidden data should fail.
288     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
289     KeyBlob deserialized(encrypted_blob, wrong_hidden, master_key_);
290     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
291 }
292 
293 }  // namespace test
294 }  // namespace keymaster
295