xref: /aosp_15_r20/system/keymaster/tests/key_blob_test.cpp (revision 789431f29546679ab5188a97751fb38e3018d44d)
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