Home | History | Annotate | Download | only in keymaster
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <algorithm>
     18 
     19 #include <gtest/gtest.h>
     20 
     21 #include <openssl/engine.h>
     22 
     23 #include <keymaster/authorization_set.h>
     24 #include <keymaster/google_keymaster_utils.h>
     25 #include <keymaster/keymaster_tags.h>
     26 
     27 #include <keymaster/key_blob.h>
     28 
     29 int main(int argc, char** argv) {
     30     ::testing::InitGoogleTest(&argc, argv);
     31     int result = RUN_ALL_TESTS();
     32     // Clean up stuff OpenSSL leaves around, so Valgrind doesn't complain.
     33     CRYPTO_cleanup_all_ex_data();
     34     ERR_free_strings();
     35     return result;
     36 }
     37 
     38 namespace keymaster {
     39 
     40 namespace test {
     41 
     42 const uint8_t master_key_data[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
     43 const uint8_t key_data[5] = {21, 22, 23, 24, 25};
     44 const uint8_t nonce[KeyBlob::NONCE_LENGTH]{12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
     45 
     46 class KeyBlobTest : public testing::Test {
     47   protected:
     48     KeyBlobTest() {
     49         key_.key_material = const_cast<uint8_t*>(key_data);
     50         key_.key_material_size = array_size(key_data);
     51         master_key_.key_material = const_cast<uint8_t*>(master_key_data);
     52         master_key_.key_material_size = array_size(master_key_data);
     53 
     54         enforced_.push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
     55         enforced_.push_back(TAG_KEY_SIZE, 256);
     56         enforced_.push_back(TAG_BLOB_USAGE_REQUIREMENTS, KM_BLOB_STANDALONE);
     57         enforced_.push_back(TAG_MIN_SECONDS_BETWEEN_OPS, 10);
     58         enforced_.push_back(TAG_ALL_USERS);
     59         enforced_.push_back(TAG_NO_AUTH_REQUIRED);
     60         enforced_.push_back(TAG_ORIGIN, KM_ORIGIN_HARDWARE);
     61 
     62         unenforced_.push_back(TAG_ACTIVE_DATETIME, 10);
     63         unenforced_.push_back(TAG_ORIGINATION_EXPIRE_DATETIME, 100);
     64         unenforced_.push_back(TAG_CREATION_DATETIME, 10);
     65         unenforced_.push_back(TAG_CHUNK_LENGTH, 10);
     66 
     67         hidden_.push_back(TAG_ROOT_OF_TRUST, "foo", 3);
     68         hidden_.push_back(TAG_APPLICATION_ID, "my_app", 6);
     69 
     70         blob_.reset(new KeyBlob(enforced_, unenforced_, hidden_, key_, master_key_, nonce));
     71     }
     72 
     73     AuthorizationSet enforced_;
     74     AuthorizationSet unenforced_;
     75     AuthorizationSet hidden_;
     76 
     77     UniquePtr<KeyBlob> blob_;
     78 
     79     keymaster_key_blob_t key_;
     80     keymaster_key_blob_t master_key_;
     81 };
     82 
     83 TEST_F(KeyBlobTest, EncryptDecrypt) {
     84     size_t size = blob_->SerializedSize();
     85     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
     86     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
     87 
     88     // key_data shouldn't be anywhere in the blob.
     89     uint8_t* begin = serialized_blob.get();
     90     uint8_t* end = begin + size;
     91     EXPECT_EQ(end, std::search(begin, end, key_data, key_data + array_size(key_data)));
     92 
     93     // Recover the key material.
     94     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
     95     KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
     96     EXPECT_EQ(KM_ERROR_OK, deserialized.error());
     97     EXPECT_EQ(0, memcmp(deserialized.key_material(), key_data, array_size(key_data)));
     98 }
     99 
    100 TEST_F(KeyBlobTest, WrongKeyLength) {
    101     size_t size = blob_->SerializedSize();
    102     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
    103     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
    104 
    105     // Modify the key length
    106     serialized_blob[KeyBlob::NONCE_LENGTH]++;
    107 
    108     // Decrypting with wrong nonce should fail.
    109     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
    110     KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
    111     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
    112 }
    113 
    114 TEST_F(KeyBlobTest, WrongNonce) {
    115     size_t size = blob_->SerializedSize();
    116     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
    117     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
    118 
    119     // Find the nonce, then modify it.
    120     uint8_t* begin = serialized_blob.get();
    121     uint8_t* end = begin + size;
    122     auto nonce_ptr = std::search(begin, end, nonce, nonce + array_size(nonce));
    123     ASSERT_NE(nonce_ptr, end);
    124     EXPECT_EQ(end, std::search(nonce_ptr + 1, end, nonce, nonce + array_size(nonce)));
    125     (*nonce_ptr)++;
    126 
    127     // Decrypting with wrong nonce should fail.
    128     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
    129     KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
    130     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
    131     EXPECT_NE(0, memcmp(deserialized.key_material(), key_data, array_size(key_data)));
    132 }
    133 
    134 TEST_F(KeyBlobTest, WrongTag) {
    135     size_t size = blob_->SerializedSize();
    136     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
    137     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
    138 
    139     // Find the tag, them modify it.
    140     uint8_t* begin = serialized_blob.get();
    141     uint8_t* end = begin + size;
    142     auto tag_ptr = std::search(begin, end, blob_->tag(), blob_->tag() + KeyBlob::TAG_LENGTH);
    143     ASSERT_NE(tag_ptr, end);
    144     EXPECT_EQ(end, std::search(tag_ptr + 1, end, blob_->tag(), blob_->tag() + KeyBlob::TAG_LENGTH));
    145     (*tag_ptr)++;
    146 
    147     // Decrypting with wrong tag should fail.
    148     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
    149     KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
    150     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
    151     EXPECT_NE(0, memcmp(deserialized.key_material(), key_data, array_size(key_data)));
    152 }
    153 
    154 TEST_F(KeyBlobTest, WrongCiphertext) {
    155     size_t size = blob_->SerializedSize();
    156     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
    157     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
    158 
    159     // Find the ciphertext, them modify it.
    160     uint8_t* begin = serialized_blob.get();
    161     uint8_t* end = begin + size;
    162     auto ciphertext_ptr =
    163         std::search(begin, end, blob_->encrypted_key_material(),
    164                     blob_->encrypted_key_material() + blob_->key_material_length());
    165     ASSERT_NE(ciphertext_ptr, end);
    166     EXPECT_EQ(end, std::search(ciphertext_ptr + 1, end, blob_->encrypted_key_material(),
    167                                blob_->encrypted_key_material() + blob_->key_material_length()));
    168     (*ciphertext_ptr)++;
    169 
    170     // Decrypting with wrong tag should fail.
    171     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
    172     KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
    173     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
    174     EXPECT_NE(0, memcmp(deserialized.key_material(), key_data, array_size(key_data)));
    175 }
    176 
    177 TEST_F(KeyBlobTest, WrongMasterKey) {
    178     size_t size = blob_->SerializedSize();
    179     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
    180     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
    181 
    182     uint8_t wrong_master_data[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    183     keymaster_key_blob_t wrong_master;
    184     wrong_master.key_material = wrong_master_data;
    185     wrong_master.key_material_size = array_size(wrong_master_data);
    186 
    187     // Decrypting with wrong master key should fail.
    188     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
    189     KeyBlob deserialized(encrypted_blob, hidden_, wrong_master);
    190     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
    191     EXPECT_NE(0, memcmp(deserialized.key_material(), key_data, array_size(key_data)));
    192 }
    193 
    194 TEST_F(KeyBlobTest, WrongEnforced) {
    195     size_t size = blob_->SerializedSize();
    196     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
    197     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
    198     uint8_t* begin = serialized_blob.get();
    199     uint8_t* end = begin + size;
    200 
    201     // Find enforced serialization data and modify it.
    202     size_t enforced_size = enforced_.SerializedSize();
    203     UniquePtr<uint8_t[]> enforced_data(new uint8_t[enforced_size]);
    204     enforced_.Serialize(enforced_data.get(), enforced_data.get() + enforced_size);
    205 
    206     auto enforced_ptr =
    207         std::search(begin, end, enforced_data.get(), enforced_data.get() + enforced_size);
    208     ASSERT_NE(end, enforced_ptr);
    209     EXPECT_EQ(end, std::search(enforced_ptr + 1, end, enforced_data.get(),
    210                                enforced_data.get() + enforced_size));
    211     (*(enforced_ptr + enforced_size - 1))++;
    212 
    213     // Decrypting with wrong unenforced data should fail.
    214     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
    215     KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
    216     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
    217 }
    218 
    219 TEST_F(KeyBlobTest, WrongUnenforced) {
    220     size_t size = blob_->SerializedSize();
    221     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
    222     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
    223     uint8_t* begin = serialized_blob.get();
    224     uint8_t* end = begin + size;
    225 
    226     // Find unenforced serialization data and modify it.
    227     size_t unenforced_size = unenforced_.SerializedSize();
    228     UniquePtr<uint8_t[]> unenforced_data(new uint8_t[unenforced_size]);
    229     unenforced_.Serialize(unenforced_data.get(), unenforced_data.get() + unenforced_size);
    230 
    231     auto unenforced_ptr =
    232         std::search(begin, end, unenforced_data.get(), unenforced_data.get() + unenforced_size);
    233     ASSERT_NE(end, unenforced_ptr);
    234     EXPECT_EQ(end, std::search(unenforced_ptr + 1, end, unenforced_data.get(),
    235                                unenforced_data.get() + unenforced_size));
    236     (*(unenforced_ptr + unenforced_size - 1))++;
    237 
    238     // Decrypting with wrong unenforced data should fail.
    239     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
    240     KeyBlob deserialized(encrypted_blob, hidden_, master_key_);
    241     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
    242 }
    243 
    244 TEST_F(KeyBlobTest, EmptyHidden) {
    245     size_t size = blob_->SerializedSize();
    246     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
    247     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
    248     uint8_t* begin = serialized_blob.get();
    249     uint8_t* end = begin + size;
    250 
    251     AuthorizationSet wrong_hidden;
    252 
    253     // Decrypting with wrong hidden data should fail.
    254     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
    255     KeyBlob deserialized(encrypted_blob, wrong_hidden, master_key_);
    256     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
    257 }
    258 
    259 TEST_F(KeyBlobTest, WrongRootOfTrust) {
    260     size_t size = blob_->SerializedSize();
    261     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
    262     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
    263     uint8_t* begin = serialized_blob.get();
    264     uint8_t* end = begin + size;
    265 
    266     AuthorizationSet wrong_hidden;
    267     wrong_hidden.push_back(TAG_ROOT_OF_TRUST, "bar", 3);
    268     wrong_hidden.push_back(TAG_APPLICATION_ID, "my_app", 6);
    269 
    270     // Decrypting with wrong hidden data should fail.
    271     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
    272     KeyBlob deserialized(encrypted_blob, wrong_hidden, master_key_);
    273     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
    274 }
    275 
    276 TEST_F(KeyBlobTest, WrongAppId) {
    277     size_t size = blob_->SerializedSize();
    278     UniquePtr<uint8_t[]> serialized_blob(new uint8_t[size]);
    279     blob_->Serialize(serialized_blob.get(), serialized_blob.get() + size);
    280     uint8_t* begin = serialized_blob.get();
    281     uint8_t* end = begin + size;
    282 
    283     AuthorizationSet wrong_hidden;
    284     wrong_hidden.push_back(TAG_ROOT_OF_TRUST, "foo", 3);
    285     wrong_hidden.push_back(TAG_APPLICATION_ID, "your_app", 7);
    286 
    287     // Decrypting with wrong hidden data should fail.
    288     keymaster_key_blob_t encrypted_blob = {serialized_blob.get(), size};
    289     KeyBlob deserialized(encrypted_blob, wrong_hidden, master_key_);
    290     EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, deserialized.error());
    291 }
    292 
    293 }  // namespace test
    294 }  // namespace keymaster
    295