1*789431f2SAndroid Build Coastguard Worker /*
2*789431f2SAndroid Build Coastguard Worker * Copyright (C) 2014 The Android Open Source Project
3*789431f2SAndroid Build Coastguard Worker *
4*789431f2SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*789431f2SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*789431f2SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*789431f2SAndroid Build Coastguard Worker *
8*789431f2SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*789431f2SAndroid Build Coastguard Worker *
10*789431f2SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*789431f2SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*789431f2SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*789431f2SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*789431f2SAndroid Build Coastguard Worker * limitations under the License.
15*789431f2SAndroid Build Coastguard Worker */
16*789431f2SAndroid Build Coastguard Worker
17*789431f2SAndroid Build Coastguard Worker #include <algorithm>
18*789431f2SAndroid Build Coastguard Worker #include <utility>
19*789431f2SAndroid Build Coastguard Worker
20*789431f2SAndroid Build Coastguard Worker #include <gtest/gtest.h>
21*789431f2SAndroid Build Coastguard Worker
22*789431f2SAndroid Build Coastguard Worker #include <openssl/engine.h>
23*789431f2SAndroid Build Coastguard Worker #include <openssl/rand.h>
24*789431f2SAndroid Build Coastguard Worker
25*789431f2SAndroid Build Coastguard Worker #include <android-base/logging.h>
26*789431f2SAndroid Build Coastguard Worker
27*789431f2SAndroid Build Coastguard Worker #include <keymaster/android_keymaster_utils.h>
28*789431f2SAndroid Build Coastguard Worker #include <keymaster/authorization_set.h>
29*789431f2SAndroid Build Coastguard Worker #include <keymaster/key_blob_utils/auth_encrypted_key_blob.h>
30*789431f2SAndroid Build Coastguard Worker #include <keymaster/key_blob_utils/integrity_assured_key_blob.h>
31*789431f2SAndroid Build Coastguard Worker #include <keymaster/keymaster_tags.h>
32*789431f2SAndroid Build Coastguard Worker #include <keymaster/km_openssl/software_random_source.h>
33*789431f2SAndroid Build Coastguard Worker
34*789431f2SAndroid Build Coastguard Worker #include "android_keymaster_test_utils.h"
35*789431f2SAndroid Build Coastguard Worker
36*789431f2SAndroid Build Coastguard Worker namespace keymaster::test {
37*789431f2SAndroid Build Coastguard Worker
38*789431f2SAndroid Build Coastguard Worker namespace {
39*789431f2SAndroid Build Coastguard Worker
40*789431f2SAndroid Build Coastguard Worker const uint8_t master_key_data[16] = {};
41*789431f2SAndroid Build Coastguard Worker const uint8_t key_data[5] = {21, 22, 23, 24, 25};
42*789431f2SAndroid Build Coastguard Worker
43*789431f2SAndroid Build Coastguard Worker } // namespace
44*789431f2SAndroid Build Coastguard Worker
45*789431f2SAndroid Build Coastguard Worker class KeyBlobTest : public ::testing::TestWithParam<AuthEncryptedBlobFormat>,
46*789431f2SAndroid Build Coastguard Worker public SoftwareRandomSource {
47*789431f2SAndroid Build Coastguard Worker protected:
KeyBlobTest()48*789431f2SAndroid Build Coastguard Worker KeyBlobTest()
49*789431f2SAndroid Build Coastguard Worker : key_material_(key_data, array_length(key_data)),
50*789431f2SAndroid Build Coastguard Worker master_key_(master_key_data, array_length(master_key_data)),
51*789431f2SAndroid Build Coastguard Worker secure_deletion_data_(SecureDeletionData()) {
52*789431f2SAndroid Build Coastguard Worker hw_enforced_.push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
53*789431f2SAndroid Build Coastguard Worker hw_enforced_.push_back(TAG_KEY_SIZE, 256);
54*789431f2SAndroid Build Coastguard Worker hw_enforced_.push_back(TAG_BLOB_USAGE_REQUIREMENTS, KM_BLOB_STANDALONE);
55*789431f2SAndroid Build Coastguard Worker hw_enforced_.push_back(TAG_MIN_SECONDS_BETWEEN_OPS, 10);
56*789431f2SAndroid Build Coastguard Worker hw_enforced_.push_back(TAG_ALL_USERS);
57*789431f2SAndroid Build Coastguard Worker hw_enforced_.push_back(TAG_NO_AUTH_REQUIRED);
58*789431f2SAndroid Build Coastguard Worker hw_enforced_.push_back(TAG_ORIGIN, KM_ORIGIN_GENERATED);
59*789431f2SAndroid Build Coastguard Worker
60*789431f2SAndroid Build Coastguard Worker sw_enforced_.push_back(TAG_ACTIVE_DATETIME, 10);
61*789431f2SAndroid Build Coastguard Worker sw_enforced_.push_back(TAG_ORIGINATION_EXPIRE_DATETIME, 100);
62*789431f2SAndroid Build Coastguard Worker sw_enforced_.push_back(TAG_CREATION_DATETIME, 10);
63*789431f2SAndroid Build Coastguard Worker
64*789431f2SAndroid Build Coastguard Worker secure_deletion_data_.factory_reset_secret.Reinitialize("Factory reset secret",
65*789431f2SAndroid Build Coastguard Worker sizeof("Factory reset secret"));
66*789431f2SAndroid Build Coastguard Worker secure_deletion_data_.secure_deletion_secret.Reinitialize("Secure deletion secret",
67*789431f2SAndroid Build Coastguard Worker sizeof("Secure deletion secret"));
68*789431f2SAndroid Build Coastguard Worker
69*789431f2SAndroid Build Coastguard Worker hidden_.push_back(TAG_ROOT_OF_TRUST, "foo", 3);
70*789431f2SAndroid Build Coastguard Worker hidden_.push_back(TAG_APPLICATION_ID, "my_app", 6);
71*789431f2SAndroid Build Coastguard Worker }
72*789431f2SAndroid Build Coastguard Worker
Encrypt(AuthEncryptedBlobFormat format)73*789431f2SAndroid Build Coastguard Worker keymaster_error_t Encrypt(AuthEncryptedBlobFormat format) {
74*789431f2SAndroid Build Coastguard Worker auto result = EncryptKey(key_material_, format, hw_enforced_, sw_enforced_, hidden_,
75*789431f2SAndroid Build Coastguard Worker secure_deletion_data_, master_key_, *this);
76*789431f2SAndroid Build Coastguard Worker if (!result) return result.error();
77*789431f2SAndroid Build Coastguard Worker encrypted_key_ = std::move(*result);
78*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
79*789431f2SAndroid Build Coastguard Worker }
80*789431f2SAndroid Build Coastguard Worker
Decrypt()81*789431f2SAndroid Build Coastguard Worker keymaster_error_t Decrypt() {
82*789431f2SAndroid Build Coastguard Worker auto result =
83*789431f2SAndroid Build Coastguard Worker DecryptKey(std::move(deserialized_key_), hidden_, secure_deletion_data_, master_key_);
84*789431f2SAndroid Build Coastguard Worker if (!result) return result.error();
85*789431f2SAndroid Build Coastguard Worker decrypted_plaintext_ = std::move(*result);
86*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
87*789431f2SAndroid Build Coastguard Worker }
88*789431f2SAndroid Build Coastguard Worker
Serialize(uint32_t secure_deletion_key_slot=0)89*789431f2SAndroid Build Coastguard Worker keymaster_error_t Serialize(uint32_t secure_deletion_key_slot = 0) {
90*789431f2SAndroid Build Coastguard Worker auto result = SerializeAuthEncryptedBlob(encrypted_key_, hw_enforced_, sw_enforced_,
91*789431f2SAndroid Build Coastguard Worker secure_deletion_key_slot);
92*789431f2SAndroid Build Coastguard Worker if (!result) return result.error();
93*789431f2SAndroid Build Coastguard Worker serialized_blob_ = std::move(*result);
94*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
95*789431f2SAndroid Build Coastguard Worker }
96*789431f2SAndroid Build Coastguard Worker
Deserialize()97*789431f2SAndroid Build Coastguard Worker keymaster_error_t Deserialize() {
98*789431f2SAndroid Build Coastguard Worker auto result = DeserializeAuthEncryptedBlob(serialized_blob_);
99*789431f2SAndroid Build Coastguard Worker if (!result) return result.error();
100*789431f2SAndroid Build Coastguard Worker deserialized_key_ = std::move(*result);
101*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
102*789431f2SAndroid Build Coastguard Worker }
103*789431f2SAndroid Build Coastguard Worker
104*789431f2SAndroid Build Coastguard Worker // Encryption inputs
105*789431f2SAndroid Build Coastguard Worker AuthorizationSet hw_enforced_;
106*789431f2SAndroid Build Coastguard Worker AuthorizationSet sw_enforced_;
107*789431f2SAndroid Build Coastguard Worker AuthorizationSet hidden_;
108*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob key_material_;
109*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob master_key_;
110*789431f2SAndroid Build Coastguard Worker SecureDeletionData secure_deletion_data_;
111*789431f2SAndroid Build Coastguard Worker
112*789431f2SAndroid Build Coastguard Worker // Encryption output
113*789431f2SAndroid Build Coastguard Worker EncryptedKey encrypted_key_;
114*789431f2SAndroid Build Coastguard Worker
115*789431f2SAndroid Build Coastguard Worker // Serialization output
116*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob serialized_blob_;
117*789431f2SAndroid Build Coastguard Worker
118*789431f2SAndroid Build Coastguard Worker // Deserialization output
119*789431f2SAndroid Build Coastguard Worker DeserializedKey deserialized_key_;
120*789431f2SAndroid Build Coastguard Worker
121*789431f2SAndroid Build Coastguard Worker // Decryption output.
122*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob decrypted_plaintext_;
123*789431f2SAndroid Build Coastguard Worker };
124*789431f2SAndroid Build Coastguard Worker
TEST_P(KeyBlobTest,EncryptDecrypt)125*789431f2SAndroid Build Coastguard Worker TEST_P(KeyBlobTest, EncryptDecrypt) {
126*789431f2SAndroid Build Coastguard Worker uint32_t key_slot = static_cast<uint32_t>(rand());
127*789431f2SAndroid Build Coastguard Worker
128*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Encrypt(GetParam()));
129*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Serialize(key_slot));
130*789431f2SAndroid Build Coastguard Worker
131*789431f2SAndroid Build Coastguard Worker // key_data shouldn't be anywhere in the blob, ciphertext should.
132*789431f2SAndroid Build Coastguard Worker EXPECT_EQ(serialized_blob_.end(), std::search(serialized_blob_.begin(), serialized_blob_.end(),
133*789431f2SAndroid Build Coastguard Worker key_material_.begin(), key_material_.end()));
134*789431f2SAndroid Build Coastguard Worker EXPECT_NE(serialized_blob_.end(),
135*789431f2SAndroid Build Coastguard Worker std::search(serialized_blob_.begin(), serialized_blob_.end(),
136*789431f2SAndroid Build Coastguard Worker encrypted_key_.ciphertext.begin(), encrypted_key_.ciphertext.end()));
137*789431f2SAndroid Build Coastguard Worker
138*789431f2SAndroid Build Coastguard Worker KmErrorOr<DeserializedKey> deserialized = DeserializeAuthEncryptedBlob(serialized_blob_);
139*789431f2SAndroid Build Coastguard Worker ASSERT_TRUE(deserialized.isOk());
140*789431f2SAndroid Build Coastguard Worker EXPECT_EQ(hw_enforced_, deserialized->hw_enforced);
141*789431f2SAndroid Build Coastguard Worker EXPECT_EQ(sw_enforced_, deserialized->sw_enforced);
142*789431f2SAndroid Build Coastguard Worker if (GetParam() == AES_GCM_WITH_SECURE_DELETION ||
143*789431f2SAndroid Build Coastguard Worker GetParam() == AES_GCM_WITH_SECURE_DELETION_VERSIONED) {
144*789431f2SAndroid Build Coastguard Worker EXPECT_EQ(key_slot, deserialized->key_slot);
145*789431f2SAndroid Build Coastguard Worker } else {
146*789431f2SAndroid Build Coastguard Worker EXPECT_EQ(0U, deserialized->key_slot);
147*789431f2SAndroid Build Coastguard Worker }
148*789431f2SAndroid Build Coastguard Worker
149*789431f2SAndroid Build Coastguard Worker KmErrorOr<KeymasterKeyBlob> plaintext =
150*789431f2SAndroid Build Coastguard Worker DecryptKey(*deserialized, hidden_, secure_deletion_data_, master_key_);
151*789431f2SAndroid Build Coastguard Worker ASSERT_TRUE(plaintext.isOk());
152*789431f2SAndroid Build Coastguard Worker EXPECT_TRUE(std::equal(key_material_.begin(), key_material_.end(), //
153*789431f2SAndroid Build Coastguard Worker plaintext->begin(), plaintext->end()));
154*789431f2SAndroid Build Coastguard Worker }
155*789431f2SAndroid Build Coastguard Worker
TEST_P(KeyBlobTest,WrongKeyLength)156*789431f2SAndroid Build Coastguard Worker TEST_P(KeyBlobTest, WrongKeyLength) {
157*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Encrypt(GetParam()));
158*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Serialize());
159*789431f2SAndroid Build Coastguard Worker
160*789431f2SAndroid Build Coastguard Worker // Modify the key length, shouldn't be able to parse.
161*789431f2SAndroid Build Coastguard Worker serialized_blob_.writable_data()[1 /* version */ + 4 /* nonce len */ + 12 /* nonce */ + 3]++;
162*789431f2SAndroid Build Coastguard Worker
163*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, Deserialize());
164*789431f2SAndroid Build Coastguard Worker }
165*789431f2SAndroid Build Coastguard Worker
TEST_P(KeyBlobTest,WrongNonce)166*789431f2SAndroid Build Coastguard Worker TEST_P(KeyBlobTest, WrongNonce) {
167*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Encrypt(GetParam()));
168*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Serialize());
169*789431f2SAndroid Build Coastguard Worker
170*789431f2SAndroid Build Coastguard Worker // Find the nonce, then modify it.
171*789431f2SAndroid Build Coastguard Worker auto nonce_ptr = std::search(serialized_blob_.begin(), serialized_blob_.end(),
172*789431f2SAndroid Build Coastguard Worker encrypted_key_.nonce.begin(), encrypted_key_.nonce.end());
173*789431f2SAndroid Build Coastguard Worker ASSERT_NE(nonce_ptr, serialized_blob_.end());
174*789431f2SAndroid Build Coastguard Worker (*const_cast<uint8_t*>(nonce_ptr))++;
175*789431f2SAndroid Build Coastguard Worker
176*789431f2SAndroid Build Coastguard Worker // Deserialization shouldn't be affected, but decryption should fail.
177*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Deserialize());
178*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, Decrypt());
179*789431f2SAndroid Build Coastguard Worker }
180*789431f2SAndroid Build Coastguard Worker
TEST_P(KeyBlobTest,WrongTag)181*789431f2SAndroid Build Coastguard Worker TEST_P(KeyBlobTest, WrongTag) {
182*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Encrypt(GetParam()));
183*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Serialize());
184*789431f2SAndroid Build Coastguard Worker
185*789431f2SAndroid Build Coastguard Worker // Find the tag, then modify it.
186*789431f2SAndroid Build Coastguard Worker auto tag_ptr = std::search(serialized_blob_.begin(), serialized_blob_.end(),
187*789431f2SAndroid Build Coastguard Worker encrypted_key_.tag.begin(), encrypted_key_.tag.end());
188*789431f2SAndroid Build Coastguard Worker ASSERT_NE(tag_ptr, serialized_blob_.end());
189*789431f2SAndroid Build Coastguard Worker (*const_cast<uint8_t*>(tag_ptr))++;
190*789431f2SAndroid Build Coastguard Worker
191*789431f2SAndroid Build Coastguard Worker // Deserialization shouldn't be affected, but decryption should fail.
192*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Deserialize());
193*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, Decrypt());
194*789431f2SAndroid Build Coastguard Worker }
195*789431f2SAndroid Build Coastguard Worker
TEST_P(KeyBlobTest,WrongCiphertext)196*789431f2SAndroid Build Coastguard Worker TEST_P(KeyBlobTest, WrongCiphertext) {
197*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Encrypt(GetParam()));
198*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Serialize());
199*789431f2SAndroid Build Coastguard Worker
200*789431f2SAndroid Build Coastguard Worker // Find the ciphertext, then modify it.
201*789431f2SAndroid Build Coastguard Worker auto ciphertext_ptr =
202*789431f2SAndroid Build Coastguard Worker std::search(serialized_blob_.begin(), serialized_blob_.end(),
203*789431f2SAndroid Build Coastguard Worker encrypted_key_.ciphertext.begin(), encrypted_key_.ciphertext.end());
204*789431f2SAndroid Build Coastguard Worker ASSERT_NE(ciphertext_ptr, serialized_blob_.end());
205*789431f2SAndroid Build Coastguard Worker (*const_cast<uint8_t*>(ciphertext_ptr))++;
206*789431f2SAndroid Build Coastguard Worker
207*789431f2SAndroid Build Coastguard Worker // Deserialization shouldn't be affected, but decryption should fail.
208*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Deserialize());
209*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, Decrypt());
210*789431f2SAndroid Build Coastguard Worker }
211*789431f2SAndroid Build Coastguard Worker
TEST_P(KeyBlobTest,WrongMasterKey)212*789431f2SAndroid Build Coastguard Worker TEST_P(KeyBlobTest, WrongMasterKey) {
213*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Encrypt(GetParam()));
214*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Serialize());
215*789431f2SAndroid Build Coastguard Worker
216*789431f2SAndroid Build Coastguard Worker uint8_t wrong_master_data[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
217*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob wrong_master(wrong_master_data, array_length(wrong_master_data));
218*789431f2SAndroid Build Coastguard Worker
219*789431f2SAndroid Build Coastguard Worker // Decrypting with wrong master key should fail.
220*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Deserialize());
221*789431f2SAndroid Build Coastguard Worker auto result = DecryptKey(deserialized_key_, hidden_, secure_deletion_data_, wrong_master);
222*789431f2SAndroid Build Coastguard Worker ASSERT_FALSE(result.isOk());
223*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, result.error());
224*789431f2SAndroid Build Coastguard Worker }
225*789431f2SAndroid Build Coastguard Worker
TEST_P(KeyBlobTest,WrongHwEnforced)226*789431f2SAndroid Build Coastguard Worker TEST_P(KeyBlobTest, WrongHwEnforced) {
227*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Encrypt(GetParam()));
228*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Serialize());
229*789431f2SAndroid Build Coastguard Worker
230*789431f2SAndroid Build Coastguard Worker // Find enforced serialization data and modify it.
231*789431f2SAndroid Build Coastguard Worker size_t hw_enforced_size = hw_enforced_.SerializedSize();
232*789431f2SAndroid Build Coastguard Worker UniquePtr<uint8_t[]> hw_enforced_data(new (std::nothrow) uint8_t[hw_enforced_size]);
233*789431f2SAndroid Build Coastguard Worker hw_enforced_.Serialize(hw_enforced_data.get(), hw_enforced_data.get() + hw_enforced_size);
234*789431f2SAndroid Build Coastguard Worker
235*789431f2SAndroid Build Coastguard Worker auto hw_enforced_ptr =
236*789431f2SAndroid Build Coastguard Worker std::search(serialized_blob_.begin(), serialized_blob_.end(), hw_enforced_data.get(),
237*789431f2SAndroid Build Coastguard Worker hw_enforced_data.get() + hw_enforced_size);
238*789431f2SAndroid Build Coastguard Worker ASSERT_NE(serialized_blob_.end(), hw_enforced_ptr);
239*789431f2SAndroid Build Coastguard Worker (*(const_cast<uint8_t*>(hw_enforced_ptr) + hw_enforced_size - 1))++;
240*789431f2SAndroid Build Coastguard Worker
241*789431f2SAndroid Build Coastguard Worker // Deserialization shouldn't be affected, but decryption should fail.
242*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Deserialize());
243*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, Decrypt());
244*789431f2SAndroid Build Coastguard Worker }
245*789431f2SAndroid Build Coastguard Worker
TEST_P(KeyBlobTest,WrongSwEnforced)246*789431f2SAndroid Build Coastguard Worker TEST_P(KeyBlobTest, WrongSwEnforced) {
247*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Encrypt(GetParam()));
248*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Serialize());
249*789431f2SAndroid Build Coastguard Worker
250*789431f2SAndroid Build Coastguard Worker // Find enforced serialization data and modify it.
251*789431f2SAndroid Build Coastguard Worker size_t sw_enforced_size = sw_enforced_.SerializedSize();
252*789431f2SAndroid Build Coastguard Worker UniquePtr<uint8_t[]> sw_enforced_data(new uint8_t[sw_enforced_size]);
253*789431f2SAndroid Build Coastguard Worker sw_enforced_.Serialize(sw_enforced_data.get(), sw_enforced_data.get() + sw_enforced_size);
254*789431f2SAndroid Build Coastguard Worker
255*789431f2SAndroid Build Coastguard Worker auto sw_enforced_ptr =
256*789431f2SAndroid Build Coastguard Worker std::search(serialized_blob_.begin(), serialized_blob_.end(), sw_enforced_data.get(),
257*789431f2SAndroid Build Coastguard Worker sw_enforced_data.get() + sw_enforced_size);
258*789431f2SAndroid Build Coastguard Worker ASSERT_NE(serialized_blob_.end(), sw_enforced_ptr);
259*789431f2SAndroid Build Coastguard Worker (*(const_cast<uint8_t*>(sw_enforced_ptr) + sw_enforced_size - 1))++;
260*789431f2SAndroid Build Coastguard Worker
261*789431f2SAndroid Build Coastguard Worker // Deserialization shouldn't be affected, but decryption should fail.
262*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Deserialize());
263*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, Decrypt());
264*789431f2SAndroid Build Coastguard Worker }
265*789431f2SAndroid Build Coastguard Worker
TEST_P(KeyBlobTest,EmptyHidden)266*789431f2SAndroid Build Coastguard Worker TEST_P(KeyBlobTest, EmptyHidden) {
267*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Encrypt(GetParam()));
268*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Serialize());
269*789431f2SAndroid Build Coastguard Worker
270*789431f2SAndroid Build Coastguard Worker AuthorizationSet wrong_hidden;
271*789431f2SAndroid Build Coastguard Worker
272*789431f2SAndroid Build Coastguard Worker // Deserialization shouldn't be affected, but decryption should fail.
273*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Deserialize());
274*789431f2SAndroid Build Coastguard Worker auto result = DecryptKey(deserialized_key_, wrong_hidden, secure_deletion_data_, master_key_);
275*789431f2SAndroid Build Coastguard Worker EXPECT_FALSE(result.isOk());
276*789431f2SAndroid Build Coastguard Worker EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, result.error());
277*789431f2SAndroid Build Coastguard Worker }
278*789431f2SAndroid Build Coastguard Worker
TEST_P(KeyBlobTest,WrongRootOfTrust)279*789431f2SAndroid Build Coastguard Worker TEST_P(KeyBlobTest, WrongRootOfTrust) {
280*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Encrypt(GetParam()));
281*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Serialize());
282*789431f2SAndroid Build Coastguard Worker
283*789431f2SAndroid Build Coastguard Worker AuthorizationSet wrong_hidden;
284*789431f2SAndroid Build Coastguard Worker wrong_hidden.push_back(TAG_ROOT_OF_TRUST, "bar", 2);
285*789431f2SAndroid Build Coastguard Worker wrong_hidden.push_back(TAG_APPLICATION_ID, "my_app", 6);
286*789431f2SAndroid Build Coastguard Worker
287*789431f2SAndroid Build Coastguard Worker // Deserialization shouldn't be affected, but decryption should fail.
288*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Deserialize());
289*789431f2SAndroid Build Coastguard Worker auto result = DecryptKey(deserialized_key_, wrong_hidden, secure_deletion_data_, master_key_);
290*789431f2SAndroid Build Coastguard Worker EXPECT_FALSE(result.isOk());
291*789431f2SAndroid Build Coastguard Worker EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, result.error());
292*789431f2SAndroid Build Coastguard Worker }
293*789431f2SAndroid Build Coastguard Worker
TEST_P(KeyBlobTest,WrongAppId)294*789431f2SAndroid Build Coastguard Worker TEST_P(KeyBlobTest, WrongAppId) {
295*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Encrypt(GetParam()));
296*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Serialize());
297*789431f2SAndroid Build Coastguard Worker
298*789431f2SAndroid Build Coastguard Worker AuthorizationSet wrong_hidden;
299*789431f2SAndroid Build Coastguard Worker wrong_hidden.push_back(TAG_ROOT_OF_TRUST, "foo", 3);
300*789431f2SAndroid Build Coastguard Worker wrong_hidden.push_back(TAG_APPLICATION_ID, "your_app", 7);
301*789431f2SAndroid Build Coastguard Worker
302*789431f2SAndroid Build Coastguard Worker // Deserialization shouldn't be affected, but decryption should fail.
303*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Deserialize());
304*789431f2SAndroid Build Coastguard Worker auto result = DecryptKey(deserialized_key_, wrong_hidden, secure_deletion_data_, master_key_);
305*789431f2SAndroid Build Coastguard Worker EXPECT_FALSE(result.isOk());
306*789431f2SAndroid Build Coastguard Worker EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, result.error());
307*789431f2SAndroid Build Coastguard Worker }
308*789431f2SAndroid Build Coastguard Worker
309*789431f2SAndroid Build Coastguard Worker // This test is especially useful when compiled for 32-bit mode and run under valgrind.
TEST_P(KeyBlobTest,FuzzTest)310*789431f2SAndroid Build Coastguard Worker TEST_P(KeyBlobTest, FuzzTest) {
311*789431f2SAndroid Build Coastguard Worker time_t now = time(NULL);
312*789431f2SAndroid Build Coastguard Worker std::cout << "Seeding rand() with " << now << " for fuzz test." << std::endl;
313*789431f2SAndroid Build Coastguard Worker srand(now);
314*789431f2SAndroid Build Coastguard Worker
315*789431f2SAndroid Build Coastguard Worker // Fill large buffer with random bytes.
316*789431f2SAndroid Build Coastguard Worker const int kBufSize = 10000;
317*789431f2SAndroid Build Coastguard Worker UniquePtr<uint8_t[]> buf(new uint8_t[kBufSize]);
318*789431f2SAndroid Build Coastguard Worker for (size_t i = 0; i < kBufSize; ++i)
319*789431f2SAndroid Build Coastguard Worker buf[i] = static_cast<uint8_t>(rand());
320*789431f2SAndroid Build Coastguard Worker
321*789431f2SAndroid Build Coastguard Worker // Try to deserialize every offset with multiple methods.
322*789431f2SAndroid Build Coastguard Worker size_t deserialize_auth_encrypted_success = 0;
323*789431f2SAndroid Build Coastguard Worker for (size_t i = 0; i < kBufSize; ++i) {
324*789431f2SAndroid Build Coastguard Worker keymaster_key_blob_t blob = {buf.get() + i, kBufSize - i};
325*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob key_blob(blob);
326*789431f2SAndroid Build Coastguard Worker
327*789431f2SAndroid Build Coastguard Worker // Integrity-assured blob.
328*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB,
329*789431f2SAndroid Build Coastguard Worker DeserializeIntegrityAssuredBlob(key_blob, hidden_, &key_material_, &hw_enforced_,
330*789431f2SAndroid Build Coastguard Worker &sw_enforced_));
331*789431f2SAndroid Build Coastguard Worker
332*789431f2SAndroid Build Coastguard Worker // Auth-encrypted blob.
333*789431f2SAndroid Build Coastguard Worker auto deserialized = DeserializeAuthEncryptedBlob(key_blob);
334*789431f2SAndroid Build Coastguard Worker if (deserialized.isOk()) {
335*789431f2SAndroid Build Coastguard Worker // It's possible (though unlikely) to deserialize successfully. Decryption should
336*789431f2SAndroid Build Coastguard Worker // always fail, though.
337*789431f2SAndroid Build Coastguard Worker ++deserialize_auth_encrypted_success;
338*789431f2SAndroid Build Coastguard Worker auto decrypted = DecryptKey(*deserialized, hidden_, secure_deletion_data_, master_key_);
339*789431f2SAndroid Build Coastguard Worker ASSERT_FALSE(decrypted.isOk());
340*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, decrypted.error())
341*789431f2SAndroid Build Coastguard Worker << "Somehow successfully parsed and decrypted a blob with seed " << now
342*789431f2SAndroid Build Coastguard Worker << " at offset " << i;
343*789431f2SAndroid Build Coastguard Worker } else {
344*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
345*789431f2SAndroid Build Coastguard Worker }
346*789431f2SAndroid Build Coastguard Worker }
347*789431f2SAndroid Build Coastguard Worker }
348*789431f2SAndroid Build Coastguard Worker
TEST_P(KeyBlobTest,UnderflowTest)349*789431f2SAndroid Build Coastguard Worker TEST_P(KeyBlobTest, UnderflowTest) {
350*789431f2SAndroid Build Coastguard Worker uint8_t buf[0];
351*789431f2SAndroid Build Coastguard Worker keymaster_key_blob_t blob = {buf, 0};
352*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob key_blob(blob);
353*789431f2SAndroid Build Coastguard Worker EXPECT_NE(nullptr, key_blob.key_material);
354*789431f2SAndroid Build Coastguard Worker EXPECT_EQ(0U, key_blob.key_material_size);
355*789431f2SAndroid Build Coastguard Worker
356*789431f2SAndroid Build Coastguard Worker EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB,
357*789431f2SAndroid Build Coastguard Worker DeserializeIntegrityAssuredBlob(key_blob, hidden_, &key_material_, &hw_enforced_,
358*789431f2SAndroid Build Coastguard Worker &sw_enforced_));
359*789431f2SAndroid Build Coastguard Worker
360*789431f2SAndroid Build Coastguard Worker auto deserialized = DeserializeAuthEncryptedBlob(key_blob);
361*789431f2SAndroid Build Coastguard Worker EXPECT_FALSE(deserialized.isOk());
362*789431f2SAndroid Build Coastguard Worker EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
363*789431f2SAndroid Build Coastguard Worker }
364*789431f2SAndroid Build Coastguard Worker
TEST_P(KeyBlobTest,DupBufferToolarge)365*789431f2SAndroid Build Coastguard Worker TEST_P(KeyBlobTest, DupBufferToolarge) {
366*789431f2SAndroid Build Coastguard Worker uint8_t buf[0];
367*789431f2SAndroid Build Coastguard Worker keymaster_key_blob_t blob = {buf, 0};
368*789431f2SAndroid Build Coastguard Worker blob.key_material_size = 16 * 1024 * 1024 + 1;
369*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob key_blob(blob);
370*789431f2SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, key_blob.key_material);
371*789431f2SAndroid Build Coastguard Worker EXPECT_EQ(0U, key_blob.key_material_size);
372*789431f2SAndroid Build Coastguard Worker
373*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB,
374*789431f2SAndroid Build Coastguard Worker DeserializeIntegrityAssuredBlob(key_blob, hidden_, &key_material_, &hw_enforced_,
375*789431f2SAndroid Build Coastguard Worker &sw_enforced_));
376*789431f2SAndroid Build Coastguard Worker
377*789431f2SAndroid Build Coastguard Worker auto deserialized = DeserializeAuthEncryptedBlob(key_blob);
378*789431f2SAndroid Build Coastguard Worker EXPECT_FALSE(deserialized.isOk());
379*789431f2SAndroid Build Coastguard Worker EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
380*789431f2SAndroid Build Coastguard Worker }
381*789431f2SAndroid Build Coastguard Worker
382*789431f2SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(AllFormats, KeyBlobTest,
383*789431f2SAndroid Build Coastguard Worker ::testing::Values(AES_OCB, AES_GCM_WITH_SW_ENFORCED,
384*789431f2SAndroid Build Coastguard Worker AES_GCM_WITH_SECURE_DELETION,
385*789431f2SAndroid Build Coastguard Worker AES_GCM_WITH_SW_ENFORCED_VERSIONED,
386*789431f2SAndroid Build Coastguard Worker AES_GCM_WITH_SECURE_DELETION_VERSIONED),
__anona3395e460202(const ::testing::TestParamInfo<KeyBlobTest::ParamType>& info) 387*789431f2SAndroid Build Coastguard Worker [](const ::testing::TestParamInfo<KeyBlobTest::ParamType>& info) {
388*789431f2SAndroid Build Coastguard Worker switch (info.param) {
389*789431f2SAndroid Build Coastguard Worker case AES_OCB:
390*789431f2SAndroid Build Coastguard Worker return "AES_OCB";
391*789431f2SAndroid Build Coastguard Worker case AES_GCM_WITH_SW_ENFORCED:
392*789431f2SAndroid Build Coastguard Worker return "AES_GCM_WITH_SW_ENFORCED";
393*789431f2SAndroid Build Coastguard Worker case AES_GCM_WITH_SECURE_DELETION:
394*789431f2SAndroid Build Coastguard Worker return "AES_GCM_WITH_SECURE_DELETION";
395*789431f2SAndroid Build Coastguard Worker case AES_GCM_WITH_SW_ENFORCED_VERSIONED:
396*789431f2SAndroid Build Coastguard Worker return "AES_GCM_WITH_SW_ENFORCED_VERSIONED";
397*789431f2SAndroid Build Coastguard Worker case AES_GCM_WITH_SECURE_DELETION_VERSIONED:
398*789431f2SAndroid Build Coastguard Worker return "AES_GCM_WITH_SECURE_DELETION_VERSIONED";
399*789431f2SAndroid Build Coastguard Worker }
400*789431f2SAndroid Build Coastguard Worker CHECK(false) << "Shouldn't be able to get here";
401*789431f2SAndroid Build Coastguard Worker return "Unexpected";
402*789431f2SAndroid Build Coastguard Worker });
403*789431f2SAndroid Build Coastguard Worker
404*789431f2SAndroid Build Coastguard Worker using SecureDeletionTest = KeyBlobTest;
405*789431f2SAndroid Build Coastguard Worker
406*789431f2SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(SecureDeletionFormats, SecureDeletionTest,
407*789431f2SAndroid Build Coastguard Worker ::testing::Values(AES_GCM_WITH_SECURE_DELETION,
408*789431f2SAndroid Build Coastguard Worker AES_GCM_WITH_SECURE_DELETION_VERSIONED),
__anona3395e460302(const ::testing::TestParamInfo<KeyBlobTest::ParamType>& info) 409*789431f2SAndroid Build Coastguard Worker [](const ::testing::TestParamInfo<KeyBlobTest::ParamType>& info) {
410*789431f2SAndroid Build Coastguard Worker switch (info.param) {
411*789431f2SAndroid Build Coastguard Worker case AES_OCB:
412*789431f2SAndroid Build Coastguard Worker return "AES_OCB";
413*789431f2SAndroid Build Coastguard Worker case AES_GCM_WITH_SW_ENFORCED:
414*789431f2SAndroid Build Coastguard Worker return "AES_GCM_WITH_SW_ENFORCED";
415*789431f2SAndroid Build Coastguard Worker case AES_GCM_WITH_SECURE_DELETION:
416*789431f2SAndroid Build Coastguard Worker return "AES_GCM_WITH_SECURE_DELETION";
417*789431f2SAndroid Build Coastguard Worker case AES_GCM_WITH_SW_ENFORCED_VERSIONED:
418*789431f2SAndroid Build Coastguard Worker return "AES_GCM_WITH_SW_ENFORCED_VERSIONED";
419*789431f2SAndroid Build Coastguard Worker case AES_GCM_WITH_SECURE_DELETION_VERSIONED:
420*789431f2SAndroid Build Coastguard Worker return "AES_GCM_WITH_SECURE_DELETION_VERSIONED";
421*789431f2SAndroid Build Coastguard Worker }
422*789431f2SAndroid Build Coastguard Worker CHECK(false) << "Shouldn't be able to get here";
423*789431f2SAndroid Build Coastguard Worker return "Unexpected";
424*789431f2SAndroid Build Coastguard Worker });
425*789431f2SAndroid Build Coastguard Worker
TEST_P(SecureDeletionTest,WrongFactoryResetSecret)426*789431f2SAndroid Build Coastguard Worker TEST_P(SecureDeletionTest, WrongFactoryResetSecret) {
427*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Encrypt(GetParam()));
428*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Serialize());
429*789431f2SAndroid Build Coastguard Worker
430*789431f2SAndroid Build Coastguard Worker SecureDeletionData wrong_secure_deletion(std::move(secure_deletion_data_));
431*789431f2SAndroid Build Coastguard Worker wrong_secure_deletion.factory_reset_secret.Reinitialize("Wrong", sizeof("Wrong"));
432*789431f2SAndroid Build Coastguard Worker
433*789431f2SAndroid Build Coastguard Worker // Deserialization shouldn't be affected, but decryption should fail.
434*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Deserialize());
435*789431f2SAndroid Build Coastguard Worker auto result = DecryptKey(deserialized_key_, hidden_, wrong_secure_deletion, master_key_);
436*789431f2SAndroid Build Coastguard Worker EXPECT_FALSE(result.isOk());
437*789431f2SAndroid Build Coastguard Worker EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, result.error());
438*789431f2SAndroid Build Coastguard Worker }
439*789431f2SAndroid Build Coastguard Worker
TEST_P(SecureDeletionTest,WrongSecureDeletionSecret)440*789431f2SAndroid Build Coastguard Worker TEST_P(SecureDeletionTest, WrongSecureDeletionSecret) {
441*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Encrypt(GetParam()));
442*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Serialize());
443*789431f2SAndroid Build Coastguard Worker
444*789431f2SAndroid Build Coastguard Worker SecureDeletionData wrong_secure_deletion(std::move(secure_deletion_data_));
445*789431f2SAndroid Build Coastguard Worker wrong_secure_deletion.secure_deletion_secret.Reinitialize("Wrong", sizeof("Wrong"));
446*789431f2SAndroid Build Coastguard Worker
447*789431f2SAndroid Build Coastguard Worker // Deserialization shouldn't be affected, but decryption should fail.
448*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Deserialize());
449*789431f2SAndroid Build Coastguard Worker auto result = DecryptKey(deserialized_key_, hidden_, wrong_secure_deletion, master_key_);
450*789431f2SAndroid Build Coastguard Worker EXPECT_FALSE(result.isOk());
451*789431f2SAndroid Build Coastguard Worker EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, result.error());
452*789431f2SAndroid Build Coastguard Worker }
453*789431f2SAndroid Build Coastguard Worker
TEST_P(SecureDeletionTest,WrongSecureDeletionKeySlot)454*789431f2SAndroid Build Coastguard Worker TEST_P(SecureDeletionTest, WrongSecureDeletionKeySlot) {
455*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Encrypt(GetParam()));
456*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Serialize());
457*789431f2SAndroid Build Coastguard Worker
458*789431f2SAndroid Build Coastguard Worker SecureDeletionData wrong_secure_deletion(std::move(secure_deletion_data_));
459*789431f2SAndroid Build Coastguard Worker ++wrong_secure_deletion.key_slot;
460*789431f2SAndroid Build Coastguard Worker
461*789431f2SAndroid Build Coastguard Worker // Deserialization shouldn't be affected, but decryption should fail.
462*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, Deserialize());
463*789431f2SAndroid Build Coastguard Worker auto result = DecryptKey(deserialized_key_, hidden_, wrong_secure_deletion, master_key_);
464*789431f2SAndroid Build Coastguard Worker EXPECT_FALSE(result.isOk());
465*789431f2SAndroid Build Coastguard Worker EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, result.error());
466*789431f2SAndroid Build Coastguard Worker }
467*789431f2SAndroid Build Coastguard Worker
TEST(KmErrorOrDeathTest,UncheckedError)468*789431f2SAndroid Build Coastguard Worker TEST(KmErrorOrDeathTest, UncheckedError) {
469*789431f2SAndroid Build Coastguard Worker ASSERT_DEATH({ KmErrorOr<int> kmError(KM_ERROR_UNKNOWN_ERROR); }, "");
470*789431f2SAndroid Build Coastguard Worker }
471*789431f2SAndroid Build Coastguard Worker
TEST(KmErrorOrDeathTest,UseValueWithoutChecking)472*789431f2SAndroid Build Coastguard Worker TEST(KmErrorOrDeathTest, UseValueWithoutChecking) {
473*789431f2SAndroid Build Coastguard Worker ASSERT_DEATH(
474*789431f2SAndroid Build Coastguard Worker {
475*789431f2SAndroid Build Coastguard Worker KmErrorOr<int> kmError(KM_ERROR_UNKNOWN_ERROR);
476*789431f2SAndroid Build Coastguard Worker kmError.value();
477*789431f2SAndroid Build Coastguard Worker kmError.isOk(); // Check here so dtor won't abort().
478*789431f2SAndroid Build Coastguard Worker },
479*789431f2SAndroid Build Coastguard Worker "");
480*789431f2SAndroid Build Coastguard Worker }
481*789431f2SAndroid Build Coastguard Worker
TEST(KmErrorOrDeathTest,CheckAfterReturn)482*789431f2SAndroid Build Coastguard Worker TEST(KmErrorOrDeathTest, CheckAfterReturn) {
483*789431f2SAndroid Build Coastguard Worker auto func = []() -> KmErrorOr<int> {
484*789431f2SAndroid Build Coastguard Worker // This instance will have its content moved and then be destroyed. It
485*789431f2SAndroid Build Coastguard Worker // shouldn't abort()
486*789431f2SAndroid Build Coastguard Worker return KmErrorOr<int>(KM_ERROR_UNEXPECTED_NULL_POINTER);
487*789431f2SAndroid Build Coastguard Worker };
488*789431f2SAndroid Build Coastguard Worker
489*789431f2SAndroid Build Coastguard Worker {
490*789431f2SAndroid Build Coastguard Worker auto err = func();
491*789431f2SAndroid Build Coastguard Worker ASSERT_FALSE(err.isOk()); // Check here, so it isn't destroyed.
492*789431f2SAndroid Build Coastguard Worker }
493*789431f2SAndroid Build Coastguard Worker
494*789431f2SAndroid Build Coastguard Worker ASSERT_DEATH({ auto err = func(); }, "");
495*789431f2SAndroid Build Coastguard Worker }
496*789431f2SAndroid Build Coastguard Worker
TEST(KmErrorOrDeathTest,CheckAfterMoveAssign)497*789431f2SAndroid Build Coastguard Worker TEST(KmErrorOrDeathTest, CheckAfterMoveAssign) {
498*789431f2SAndroid Build Coastguard Worker ASSERT_DEATH(
499*789431f2SAndroid Build Coastguard Worker {
500*789431f2SAndroid Build Coastguard Worker KmErrorOr<int> err(KM_ERROR_UNEXPECTED_NULL_POINTER);
501*789431f2SAndroid Build Coastguard Worker KmErrorOr<int> err2(4);
502*789431f2SAndroid Build Coastguard Worker
503*789431f2SAndroid Build Coastguard Worker err2 = std::move(err); // This swaps err and err2
504*789431f2SAndroid Build Coastguard Worker
505*789431f2SAndroid Build Coastguard Worker // Checking only one isn't enough. Both were unchecked.
506*789431f2SAndroid Build Coastguard Worker EXPECT_FALSE(err2.isOk());
507*789431f2SAndroid Build Coastguard Worker },
508*789431f2SAndroid Build Coastguard Worker "");
509*789431f2SAndroid Build Coastguard Worker
510*789431f2SAndroid Build Coastguard Worker ASSERT_DEATH(
511*789431f2SAndroid Build Coastguard Worker {
512*789431f2SAndroid Build Coastguard Worker KmErrorOr<int> err(KM_ERROR_UNEXPECTED_NULL_POINTER);
513*789431f2SAndroid Build Coastguard Worker KmErrorOr<int> err2(4);
514*789431f2SAndroid Build Coastguard Worker
515*789431f2SAndroid Build Coastguard Worker err2 = std::move(err); // This swaps err and err2
516*789431f2SAndroid Build Coastguard Worker
517*789431f2SAndroid Build Coastguard Worker // Checking only one isn't enough. Both were unchecked.
518*789431f2SAndroid Build Coastguard Worker EXPECT_TRUE(err.isOk());
519*789431f2SAndroid Build Coastguard Worker },
520*789431f2SAndroid Build Coastguard Worker "");
521*789431f2SAndroid Build Coastguard Worker
522*789431f2SAndroid Build Coastguard Worker {
523*789431f2SAndroid Build Coastguard Worker KmErrorOr<int> err(KM_ERROR_UNEXPECTED_NULL_POINTER);
524*789431f2SAndroid Build Coastguard Worker KmErrorOr<int> err2(4);
525*789431f2SAndroid Build Coastguard Worker err2 = std::move(err); // This swaps err and err2
526*789431f2SAndroid Build Coastguard Worker
527*789431f2SAndroid Build Coastguard Worker // Must check both to avoid abort().
528*789431f2SAndroid Build Coastguard Worker EXPECT_TRUE(err.isOk());
529*789431f2SAndroid Build Coastguard Worker EXPECT_FALSE(err2.isOk());
530*789431f2SAndroid Build Coastguard Worker }
531*789431f2SAndroid Build Coastguard Worker
532*789431f2SAndroid Build Coastguard Worker ASSERT_DEATH(
533*789431f2SAndroid Build Coastguard Worker {
534*789431f2SAndroid Build Coastguard Worker KmErrorOr<int> err(KM_ERROR_UNEXPECTED_NULL_POINTER);
535*789431f2SAndroid Build Coastguard Worker KmErrorOr<int> err2(4);
536*789431f2SAndroid Build Coastguard Worker
537*789431f2SAndroid Build Coastguard Worker err.isOk(); // Check err before swap
538*789431f2SAndroid Build Coastguard Worker err2 = std::move(err); // This swaps err and err2
539*789431f2SAndroid Build Coastguard Worker },
540*789431f2SAndroid Build Coastguard Worker "");
541*789431f2SAndroid Build Coastguard Worker
542*789431f2SAndroid Build Coastguard Worker {
543*789431f2SAndroid Build Coastguard Worker KmErrorOr<int> err(KM_ERROR_UNEXPECTED_NULL_POINTER);
544*789431f2SAndroid Build Coastguard Worker KmErrorOr<int> err2(4);
545*789431f2SAndroid Build Coastguard Worker
546*789431f2SAndroid Build Coastguard Worker err.isOk(); // Check err before swap
547*789431f2SAndroid Build Coastguard Worker err2 = std::move(err); // This swaps err and err2
548*789431f2SAndroid Build Coastguard Worker
549*789431f2SAndroid Build Coastguard Worker // err2 is checked, check err
550*789431f2SAndroid Build Coastguard Worker EXPECT_TRUE(err.isOk());
551*789431f2SAndroid Build Coastguard Worker }
552*789431f2SAndroid Build Coastguard Worker }
553*789431f2SAndroid Build Coastguard Worker
TEST(KmErrorOr,CheckAfterMove)554*789431f2SAndroid Build Coastguard Worker TEST(KmErrorOr, CheckAfterMove) {
555*789431f2SAndroid Build Coastguard Worker KmErrorOr<int> err(KM_ERROR_UNEXPECTED_NULL_POINTER);
556*789431f2SAndroid Build Coastguard Worker
557*789431f2SAndroid Build Coastguard Worker KmErrorOr<int> err2(std::move(err)); // err won't abort
558*789431f2SAndroid Build Coastguard Worker EXPECT_FALSE(err2.isOk()); // err2 won't abort
559*789431f2SAndroid Build Coastguard Worker EXPECT_EQ(err2.error(), KM_ERROR_UNEXPECTED_NULL_POINTER);
560*789431f2SAndroid Build Coastguard Worker }
561*789431f2SAndroid Build Coastguard Worker
TEST(KmErrorOrTest,UseErrorWithoutChecking)562*789431f2SAndroid Build Coastguard Worker TEST(KmErrorOrTest, UseErrorWithoutChecking) {
563*789431f2SAndroid Build Coastguard Worker KmErrorOr<int> kmError(99);
564*789431f2SAndroid Build Coastguard Worker // Checking error before using isOk() always returns KM_ERROR_UNKNOWN_ERROR.
565*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_UNKNOWN_ERROR, kmError.error());
566*789431f2SAndroid Build Coastguard Worker ASSERT_TRUE(kmError.isOk());
567*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(KM_ERROR_OK, kmError.error());
568*789431f2SAndroid Build Coastguard Worker ASSERT_EQ(99, *kmError);
569*789431f2SAndroid Build Coastguard Worker }
570*789431f2SAndroid Build Coastguard Worker
TEST(KmErrorTest,DefaultCtor)571*789431f2SAndroid Build Coastguard Worker TEST(KmErrorTest, DefaultCtor) {
572*789431f2SAndroid Build Coastguard Worker KmErrorOr<int> err;
573*789431f2SAndroid Build Coastguard Worker // Default-constructed objects don't need to be tested. Should not crash.
574*789431f2SAndroid Build Coastguard Worker }
575*789431f2SAndroid Build Coastguard Worker
576*789431f2SAndroid Build Coastguard Worker } // namespace keymaster::test
577