| /* |
| * Copyright (C) 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <gtest/gtest.h> |
| |
| #include <errno.h> |
| #include <keymaster/authorization_set.h> |
| #include <keymaster/android_keymaster.h> |
| #include <stdio.h> |
| #include <time.h> |
| |
| #include "keymaster_enforcement.h" |
| |
| namespace keymaster { |
| namespace test { |
| |
| class KeymasterBaseTest : public ::testing::Test { |
| protected: |
| KeymasterBaseTest() { |
| past_time = 0; |
| |
| time_t t = time(NULL); |
| future_tm = localtime(&t); |
| future_tm->tm_year += 1; |
| future_time = mktime(future_tm); |
| sign_param = Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN); |
| } |
| virtual ~KeymasterBaseTest() {} |
| |
| tm past_tm; |
| tm* future_tm; |
| time_t past_time; |
| time_t future_time; |
| static const km_id_t key_id = 0xa; |
| static const uid_t uid = 0xf; |
| keymaster_key_param_t sign_param; |
| keymaster_blob_t def_app_id; |
| size_t def_app_id_size; |
| |
| static const uint32_t valid_user_id = 25; |
| static const uint32_t invalid_user_id1 = 37; |
| static const uint32_t invalid_user_id2 = 50; |
| static const uint32_t appId1 = 51; |
| static const uint32_t appId2 = 52; |
| |
| static const uint32_t validuid1 = |
| valid_user_id * KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE + |
| (appId1 % KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE); |
| static const uint32_t validuid2 = |
| valid_user_id * KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE + |
| (appId1 % KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE); |
| |
| static const uint32_t invaliduid1 = |
| invalid_user_id1 * KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE + |
| (appId1 % KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE); |
| static const uint32_t invaliduid2 = |
| invalid_user_id1 * KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE + |
| (appId2 % KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE); |
| static const uint32_t invaliduid3 = |
| invalid_user_id2 * KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE + |
| (appId1 % KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE); |
| static const uint32_t invaliduid4 = |
| invalid_user_id2 * KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE + |
| (appId2 % KeymasterEnforcement::MULTIUSER_APP_PER_USER_RANGE); |
| }; |
| |
| TEST_F(KeymasterBaseTest, TEST_VALID_KEY_PERIOD_NO_TAGS) { |
| keymaster_key_param_t params[] = { |
| sign_param, |
| }; |
| AuthorizationSet single_auth_set(params, 1); |
| KeymasterEnforcement kmen; |
| |
| keymaster_error_t kmer = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, single_auth_set, uid); |
| ASSERT_EQ(KM_ERROR_OK, kmer); |
| } |
| |
| TEST_F(KeymasterBaseTest, TEST_INVALID_ACTIVE_TIME) { |
| keymaster_key_param_t params[] = { |
| Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), |
| Authorization(TAG_NO_AUTH_REQUIRED), Authorization(TAG_ACTIVE_DATETIME, future_time), |
| }; |
| |
| KeymasterEnforcement kmen; |
| AuthorizationSet auth_set(params, 4); |
| |
| keymaster_error_t kmer_invalid_time = |
| kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid); |
| ASSERT_EQ(KM_ERROR_KEY_NOT_YET_VALID, kmer_invalid_time); |
| } |
| |
| TEST_F(KeymasterBaseTest, TEST_VALID_ACTIVE_TIME) { |
| keymaster_key_param_t params[] = { |
| Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), |
| Authorization(TAG_ACTIVE_DATETIME, past_time), |
| }; |
| |
| KeymasterEnforcement kmen; |
| AuthorizationSet auth_set(params, 3); |
| |
| keymaster_error_t kmer_valid_time = |
| kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid); |
| ASSERT_EQ(KM_ERROR_OK, kmer_valid_time); |
| } |
| |
| TEST_F(KeymasterBaseTest, TEST_INVALID_ORIGINATION_EXPIRE_TIME) { |
| keymaster_key_param_t params[] = { |
| Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), |
| Authorization(TAG_ACTIVE_DATETIME, past_time), |
| Authorization(TAG_ORIGINATION_EXPIRE_DATETIME, past_time), |
| }; |
| |
| KeymasterEnforcement kmen; |
| AuthorizationSet auth_set(params, 4); |
| |
| keymaster_error_t kmer_invalid_origination = |
| kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid); |
| ASSERT_EQ(KM_ERROR_KEY_EXPIRED, kmer_invalid_origination); |
| } |
| |
| TEST_F(KeymasterBaseTest, TEST_VALID_ORIGINATION_EXPIRE_TIME) { |
| keymaster_key_param_t params[] = { |
| Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), |
| Authorization(TAG_ACTIVE_DATETIME, past_time), |
| Authorization(TAG_ORIGINATION_EXPIRE_DATETIME, future_time), |
| }; |
| |
| KeymasterEnforcement kmen; |
| AuthorizationSet auth_set(params, 4); |
| |
| keymaster_error_t kmer_valid_origination = |
| kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid); |
| ASSERT_EQ(KM_ERROR_OK, kmer_valid_origination); |
| } |
| |
| TEST_F(KeymasterBaseTest, TEST_INVALID_USAGE_EXPIRE_TIME) { |
| keymaster_key_param_t params[] = { |
| Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY), |
| Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), |
| Authorization(TAG_ACTIVE_DATETIME, past_time), |
| Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), |
| Authorization(TAG_USAGE_EXPIRE_DATETIME, past_time), |
| }; |
| |
| KeymasterEnforcement kmen; |
| AuthorizationSet auth_set(params, 5); |
| |
| keymaster_error_t kmer_invalid_origination = |
| kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set, uid); |
| ASSERT_EQ(KM_ERROR_KEY_EXPIRED, kmer_invalid_origination); |
| } |
| |
| TEST_F(KeymasterBaseTest, TEST_VALID_USAGE_EXPIRE_TIME) { |
| keymaster_key_param_t params[] = { |
| Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY), |
| Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), |
| Authorization(TAG_ACTIVE_DATETIME, past_time), |
| Authorization(TAG_USAGE_EXPIRE_DATETIME, future_time), |
| }; |
| |
| KeymasterEnforcement kmen; |
| AuthorizationSet auth_set(params, 4); |
| |
| keymaster_error_t kmer_valid_usage = |
| kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set, uid); |
| ASSERT_EQ(KM_ERROR_OK, kmer_valid_usage); |
| } |
| |
| TEST_F(KeymasterBaseTest, TEST_VALID_SINGLE_USE_ACCESSES) { |
| keymaster_key_param_t params[] = { |
| Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), |
| Authorization(TAG_ACTIVE_DATETIME, past_time), |
| }; |
| |
| KeymasterEnforcement kmen; |
| AuthorizationSet auth_set(params, 3); |
| |
| keymaster_error_t kmer1 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid); |
| keymaster_error_t kmer2 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid); |
| |
| ASSERT_EQ(KM_ERROR_OK, kmer1); |
| ASSERT_EQ(KM_ERROR_OK, kmer2); |
| } |
| |
| TEST_F(KeymasterBaseTest, TEST_INVALID_SINGLE_USE_ACCESSES) { |
| keymaster_key_param_t params[] = { |
| Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), |
| Authorization(TAG_ACTIVE_DATETIME, past_time), Authorization(TAG_MAX_USES_PER_BOOT, 1), |
| }; |
| |
| KeymasterEnforcement kmen; |
| AuthorizationSet auth_set(params, 4); |
| |
| keymaster_error_t kmer1 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid); |
| keymaster_error_t kmer2 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid); |
| |
| ASSERT_EQ(KM_ERROR_OK, kmer1); |
| ASSERT_EQ(KM_ERROR_TOO_MANY_OPERATIONS, kmer2); |
| } |
| |
| TEST_F(KeymasterBaseTest, TEST_INVALID_TIME_BETWEEN_OPS) { |
| keymaster_key_param_t params[] = { |
| Authorization(TAG_ALL_USERS), Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), |
| Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), |
| Authorization(TAG_ACTIVE_DATETIME, past_time), |
| Authorization(TAG_MIN_SECONDS_BETWEEN_OPS, 10), |
| }; |
| |
| KeymasterEnforcement kmen; |
| AuthorizationSet auth_set(params, 5); |
| |
| keymaster_error_t kmer1 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid); |
| keymaster_error_t kmer2 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid); |
| |
| ASSERT_EQ(KM_ERROR_OK, kmer1); |
| sleep(2); |
| ASSERT_EQ(KM_ERROR_TOO_MANY_OPERATIONS, kmer2); |
| } |
| |
| TEST_F(KeymasterBaseTest, TEST_VALID_TIME_BETWEEN_OPS) { |
| keymaster_key_param_t params[] = { |
| Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY), |
| Authorization(TAG_USAGE_EXPIRE_DATETIME, future_time), |
| Authorization(TAG_ORIGINATION_EXPIRE_DATETIME, future_time), |
| Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), |
| Authorization(TAG_ACTIVE_DATETIME, past_time), |
| Authorization(TAG_MIN_SECONDS_BETWEEN_OPS, 2), |
| }; |
| |
| KeymasterEnforcement kmen; |
| AuthorizationSet auth_set(params, 7); |
| |
| keymaster_error_t kmer1 = kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set, uid); |
| sleep(3); |
| keymaster_error_t kmer2 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid); |
| |
| ASSERT_EQ(KM_ERROR_OK, kmer1); |
| ASSERT_EQ(KM_ERROR_OK, kmer2); |
| } |
| |
| TEST_F(KeymasterBaseTest, TEST_USER_ID) { |
| keymaster_key_param_t params[] = { |
| Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_USER_ID, valid_user_id), |
| }; |
| |
| KeymasterEnforcement kmen; |
| AuthorizationSet auth_set(params, 2); |
| |
| keymaster_error_t valid_kmer1 = |
| kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, validuid1); |
| keymaster_error_t valid_kmer2 = |
| kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, validuid2); |
| |
| keymaster_error_t invalid_kmer1 = |
| kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, invaliduid1); |
| keymaster_error_t invalid_kmer2 = |
| kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, invaliduid2); |
| keymaster_error_t invalid_kmer3 = |
| kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, invaliduid3); |
| keymaster_error_t invalid_kmer4 = |
| kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, invaliduid4); |
| |
| ASSERT_EQ(KM_ERROR_OK, valid_kmer1); |
| ASSERT_EQ(KM_ERROR_OK, valid_kmer2); |
| |
| ASSERT_EQ(KM_ERROR_INVALID_USER_ID, invalid_kmer1); |
| ASSERT_EQ(KM_ERROR_INVALID_USER_ID, invalid_kmer2); |
| ASSERT_EQ(KM_ERROR_INVALID_USER_ID, invalid_kmer3); |
| ASSERT_EQ(KM_ERROR_INVALID_USER_ID, invalid_kmer4); |
| } |
| |
| TEST_F(KeymasterBaseTest, TEST_INVALID_PURPOSE) { |
| keymaster_purpose_t invalidPurpose1 = static_cast<keymaster_purpose_t>(-1); |
| keymaster_purpose_t invalidPurpose2 = static_cast<keymaster_purpose_t>(4); |
| |
| keymaster_key_param_t params1[] = { |
| Authorization(TAG_PURPOSE, invalidPurpose1), Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), |
| Authorization(TAG_ACTIVE_DATETIME, past_time), |
| }; |
| |
| keymaster_key_param_t params2[] = { |
| Authorization(TAG_PURPOSE, invalidPurpose2), Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), |
| Authorization(TAG_ACTIVE_DATETIME, past_time), |
| }; |
| |
| KeymasterEnforcement kmen; |
| AuthorizationSet auth_set1(params1, 3); |
| AuthorizationSet auth_set2(params2, 3); |
| |
| keymaster_error_t kmer1 = kmen.AuthorizeOperation(invalidPurpose1, key_id, auth_set1, uid); |
| keymaster_error_t kmer2 = kmen.AuthorizeOperation(invalidPurpose2, key_id, auth_set2, uid); |
| keymaster_error_t kmer3 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set2, uid); |
| |
| ASSERT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE, kmer1); |
| ASSERT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE, kmer2); |
| ASSERT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE, kmer3); |
| } |
| |
| TEST_F(KeymasterBaseTest, TEST_INCOMPATIBLE_PURPOSE) { |
| keymaster_key_param_t params[] = { |
| Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY), |
| Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), |
| Authorization(TAG_ACTIVE_DATETIME, past_time), Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), |
| }; |
| KeymasterEnforcement kmen; |
| AuthorizationSet auth_set(params, 4); |
| |
| keymaster_error_t kmer_invalid1 = |
| kmen.AuthorizeOperation(KM_PURPOSE_ENCRYPT, key_id, auth_set, uid); |
| keymaster_error_t kmer_invalid2 = |
| kmen.AuthorizeOperation(KM_PURPOSE_DECRYPT, key_id, auth_set, uid); |
| |
| keymaster_error_t kmer_valid1 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, uid); |
| keymaster_error_t kmer_valid2 = |
| kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set, uid); |
| |
| ASSERT_EQ(KM_ERROR_OK, kmer_valid1); |
| ASSERT_EQ(KM_ERROR_OK, kmer_valid2); |
| ASSERT_EQ(KM_ERROR_INCOMPATIBLE_PURPOSE, kmer_invalid1); |
| ASSERT_EQ(KM_ERROR_INCOMPATIBLE_PURPOSE, kmer_invalid2); |
| } |
| |
| TEST_F(KeymasterBaseTest, TEST_INVALID_TAG_PAIRS) { |
| const uint8_t* app_id = reinterpret_cast<const uint8_t*>("com.app"); |
| const size_t app_size = 7; |
| keymaster_key_param_t params1[] = { |
| Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY), |
| Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), |
| Authorization(TAG_ACTIVE_DATETIME, past_time), Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), |
| // Can't have "all users" and a specific user. |
| Authorization(TAG_ALL_USERS), Authorization(TAG_USER_ID, valid_user_id), |
| }; |
| |
| keymaster_key_param_t params2[] = { |
| Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY), |
| Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), |
| Authorization(TAG_ACTIVE_DATETIME, past_time), Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), |
| // Can't have "all applications" and a specific app ID. |
| Authorization(TAG_ALL_APPLICATIONS), Authorization(TAG_APPLICATION_ID, app_id, app_size), |
| }; |
| |
| KeymasterEnforcement kmen; |
| AuthorizationSet auth_set1(params1, array_length(params1)); |
| AuthorizationSet auth_set2(params2, array_length(params2)); |
| |
| EXPECT_EQ(KM_ERROR_INVALID_TAG, |
| kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set1, validuid1)); |
| EXPECT_EQ(KM_ERROR_INVALID_TAG, |
| kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set2, validuid1)); |
| } |
| |
| }; /* namespace test */ |
| }; /* namespace keymaster */ |