/*
 * 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 <errno.h>
#include <stdio.h>
#include <time.h>

#include <keymaster/android_keymaster.h>
#include <keymaster/authorization_set.h>
#include <keymaster/keymaster_enforcement.h>

#include "android_keymaster_test_utils.h"

namespace keymaster {
namespace test {

class TestKeymasterEnforcement : public KeymasterEnforcement {
  public:
    TestKeymasterEnforcement()
        : KeymasterEnforcement(3, 3), current_time_(10000), report_token_valid_(true) {}

    keymaster_error_t AuthorizeOperation(const keymaster_purpose_t purpose, const km_id_t keyid,
                                         const AuthorizationSet& auth_set) {
        AuthorizationSet empty_set;
        return KeymasterEnforcement::AuthorizeOperation(
            purpose, keyid, auth_set, empty_set, 0 /* op_handle */, false /* is_begin_operation */);
    }
    using KeymasterEnforcement::AuthorizeOperation;

    uint32_t get_current_time() const override { return current_time_; }
    bool activation_date_valid(uint64_t activation_date) const override {
        // Convert java date to time_t, non-portably.
        time_t activation_time = activation_date / 1000;
        return difftime(time(NULL), activation_time) >= 0;
    }
    bool expiration_date_passed(uint64_t expiration_date) const override {
        // Convert jave date to time_t, non-portably.
        time_t expiration_time = expiration_date / 1000;
        return difftime(time(NULL), expiration_time) > 0;
    }
    bool auth_token_timed_out(const hw_auth_token_t& token, uint32_t timeout) const {
        return current_time_ > ntoh(token.timestamp) + timeout;
    }
    bool ValidateTokenSignature(const hw_auth_token_t&) const override {
        return report_token_valid_;
    }

    void tick(unsigned seconds = 1) { current_time_ += seconds; }
    uint32_t current_time() { return current_time_; }
    void set_report_token_valid(bool report_token_valid) {
        report_token_valid_ = report_token_valid;
    }

  private:
    uint32_t current_time_;
    bool report_token_valid_;
};

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 = static_cast<uint64_t>(mktime(future_tm)) * 1000;
        sign_param = Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN);
    }
    virtual ~KeymasterBaseTest() {}

    TestKeymasterEnforcement kmen;

    tm past_tm;
    tm* future_tm;
    uint64_t past_time;
    uint64_t future_time;
    static const km_id_t key_id = 0xa;
    static const uid_t uid = 0xf;
    keymaster_key_param_t sign_param;
};

TEST_F(KeymasterBaseTest, TestValidKeyPeriodNoTags) {
    keymaster_key_param_t params[] = {
        sign_param,
    };
    AuthorizationSet single_auth_set(params, array_length(params));

    keymaster_error_t kmer = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, single_auth_set);
    ASSERT_EQ(KM_ERROR_OK, kmer);
}

TEST_F(KeymasterBaseTest, TestInvalidActiveTime) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_NO_AUTH_REQUIRED),
        Authorization(TAG_ACTIVE_DATETIME, future_time),
    };

    AuthorizationSet auth_set(params, array_length(params));

    keymaster_error_t kmer_invalid_time =
        kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set);
    ASSERT_EQ(KM_ERROR_KEY_NOT_YET_VALID, kmer_invalid_time);
}

TEST_F(KeymasterBaseTest, TestValidActiveTime) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_ACTIVE_DATETIME, past_time),
    };

    AuthorizationSet auth_set(params, array_length(params));

    keymaster_error_t kmer_valid_time = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set);
    ASSERT_EQ(KM_ERROR_OK, kmer_valid_time);
}

TEST_F(KeymasterBaseTest, TestInvalidOriginationExpireTime) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
        Authorization(TAG_ORIGINATION_EXPIRE_DATETIME, past_time),
    };

    AuthorizationSet auth_set(params, array_length(params));

    keymaster_error_t kmer_invalid_origination =
        kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set);
    ASSERT_EQ(KM_ERROR_KEY_EXPIRED, kmer_invalid_origination);
}

TEST_F(KeymasterBaseTest, TestInvalidOriginationExpireTimeOnUsgae) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
        Authorization(TAG_ORIGINATION_EXPIRE_DATETIME, past_time),
    };

    AuthorizationSet auth_set(params, array_length(params));

    keymaster_error_t kmer_invalid_origination =
        kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set);
    ASSERT_EQ(KM_ERROR_OK, kmer_invalid_origination);
}

TEST_F(KeymasterBaseTest, TestValidOriginationExpireTime) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
        Authorization(TAG_ORIGINATION_EXPIRE_DATETIME, future_time),
    };

    AuthorizationSet auth_set(params, array_length(params));

    keymaster_error_t kmer_valid_origination =
        kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set);
    ASSERT_EQ(KM_ERROR_OK, kmer_valid_origination);
}

TEST_F(KeymasterBaseTest, TestInvalidUsageExpireTime) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
        Authorization(TAG_USAGE_EXPIRE_DATETIME, past_time),
    };

    AuthorizationSet auth_set(params, array_length(params));

    keymaster_error_t kmer_invalid_origination =
        kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set);
    ASSERT_EQ(KM_ERROR_KEY_EXPIRED, kmer_invalid_origination);
}

TEST_F(KeymasterBaseTest, TestInvalidUsageExpireTimeOnOrigination) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
        Authorization(TAG_USAGE_EXPIRE_DATETIME, past_time),
    };

    AuthorizationSet auth_set(params, array_length(params));

    keymaster_error_t kmer_invalid_origination =
        kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set);
    ASSERT_EQ(KM_ERROR_OK, kmer_invalid_origination);
}

TEST_F(KeymasterBaseTest, TestValidUsageExpireTime) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
        Authorization(TAG_USAGE_EXPIRE_DATETIME, future_time),
    };

    AuthorizationSet auth_set(params, array_length(params));

    keymaster_error_t kmer_valid_usage =
        kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set);
    ASSERT_EQ(KM_ERROR_OK, kmer_valid_usage);
}

TEST_F(KeymasterBaseTest, TestValidSingleUseAccesses) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
    };

    AuthorizationSet auth_set(params, array_length(params));

    keymaster_error_t kmer1 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set);
    keymaster_error_t kmer2 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set);

    ASSERT_EQ(KM_ERROR_OK, kmer1);
    ASSERT_EQ(KM_ERROR_OK, kmer2);
}

TEST_F(KeymasterBaseTest, TestInvalidMaxOps) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
        Authorization(TAG_MAX_USES_PER_BOOT, 4),
    };

    AuthorizationSet auth_set(params, array_length(params));

    ASSERT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
    ASSERT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
    ASSERT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
    ASSERT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
    ASSERT_EQ(KM_ERROR_KEY_MAX_OPS_EXCEEDED,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
}

TEST_F(KeymasterBaseTest, TestOverFlowMaxOpsTable) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_MAX_USES_PER_BOOT, 2),
    };

    AuthorizationSet auth_set(params, array_length(params));

    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, 1 /* key_id */, auth_set));

    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, 2 /* key_id */, auth_set));

    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, 3 /* key_id */, auth_set));

    // Key 4 should fail, because table is full.
    EXPECT_EQ(KM_ERROR_TOO_MANY_OPERATIONS,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, 4 /* key_id */, auth_set));

    // Key 1 still works, because it's already in the table and hasn't reached max.
    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, 1 /* key_id */, auth_set));

    // Key 1 no longer works, because it's reached max.
    EXPECT_EQ(KM_ERROR_KEY_MAX_OPS_EXCEEDED,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, 1 /* key_id */, auth_set));

    // Key 4 should fail, because table is (still and forever) full.
    EXPECT_EQ(KM_ERROR_TOO_MANY_OPERATIONS,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, 4 /* key_id */, auth_set));
}

TEST_F(KeymasterBaseTest, TestInvalidTimeBetweenOps) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_MIN_SECONDS_BETWEEN_OPS, 10),
    };

    AuthorizationSet auth_set(params, array_length(params));

    keymaster_error_t kmer1 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set);
    keymaster_error_t kmer2 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set);

    ASSERT_EQ(KM_ERROR_OK, kmer1);
    kmen.tick(2);
    ASSERT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED, kmer2);
}

TEST_F(KeymasterBaseTest, TestValidTimeBetweenOps) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
        Authorization(TAG_MIN_SECONDS_BETWEEN_OPS, 2),
    };

    AuthorizationSet auth_set(params, array_length(params));

    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set));
    kmen.tick();
    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
    kmen.tick();
    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
}

TEST_F(KeymasterBaseTest, TestOptTimeoutTableOverflow) {
    keymaster_key_param_t params[] = {
        Authorization(TAG_MIN_SECONDS_BETWEEN_OPS, 4),
        Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
    };

    AuthorizationSet auth_set(params, array_length(params));

    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 1 /* key_id */, auth_set));

    kmen.tick();

    // Key 1 fails because it's too soon
    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 1 /* key_id */, auth_set));

    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 2 /* key_id */, auth_set));

    kmen.tick();

    // Key 1 fails because it's too soon
    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 1 /* key_id */, auth_set));
    // Key 2 fails because it's too soon
    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 2 /* key_id */, auth_set));

    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 3 /* key_id */, auth_set));

    kmen.tick();

    // Key 1 fails because it's too soon
    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 1 /* key_id */, auth_set));
    // Key 2 fails because it's too soon
    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 2 /* key_id */, auth_set));
    // Key 3 fails because it's too soon
    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 3 /* key_id */, auth_set));
    // Key 4 fails because the table is full
    EXPECT_EQ(KM_ERROR_TOO_MANY_OPERATIONS,
              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 4 /* key_id */, auth_set));

    kmen.tick();

    // Key 4 succeeds because key 1 expired.
    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 4 /* key_id */, auth_set));

    // Key 1 fails because the table is full... and key 1 is no longer in it.
    EXPECT_EQ(KM_ERROR_TOO_MANY_OPERATIONS,
              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 1 /* key_id */, auth_set));
    // Key 2 fails because it's too soon
    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 2 /* key_id */, auth_set));
    // Key 3 fails because it's too soon
    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 3 /* key_id */, auth_set));

    kmen.tick();

    // Key 1 succeeds because key 2 expired
    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 1 /* key_id */, auth_set));
    // Key 2 fails because the table is full... and key 2 is no longer in it.
    EXPECT_EQ(KM_ERROR_TOO_MANY_OPERATIONS,
              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 2 /* key_id */, auth_set));
    // Key 3 fails because it's too soon
    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 3 /* key_id */, auth_set));
    // Key 4 fails because it's too soon
    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 4 /* key_id */, auth_set));

    kmen.tick(4);

    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 1 /* key_id */, auth_set));
    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 2 /* key_id */, auth_set));
    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 3 /* key_id */, auth_set));
}

TEST_F(KeymasterBaseTest, TestInvalidPurpose) {
    keymaster_purpose_t invalidPurpose1 = static_cast<keymaster_purpose_t>(-1);
    keymaster_purpose_t invalidPurpose2 = static_cast<keymaster_purpose_t>(4);

    AuthorizationSet auth_set(
        AuthorizationSetBuilder().Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY));

    EXPECT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE,
              kmen.AuthorizeOperation(invalidPurpose1, key_id, auth_set));
    EXPECT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE,
              kmen.AuthorizeOperation(invalidPurpose2, key_id, auth_set));
}

TEST_F(KeymasterBaseTest, TestIncompatiblePurposeSymmetricKey) {
    AuthorizationSet auth_set(AuthorizationSetBuilder()
                                  .Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES)
                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));

    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set));

    EXPECT_EQ(KM_ERROR_INCOMPATIBLE_PURPOSE,
              kmen.AuthorizeOperation(KM_PURPOSE_ENCRYPT, key_id, auth_set));
    EXPECT_EQ(KM_ERROR_INCOMPATIBLE_PURPOSE,
              kmen.AuthorizeOperation(KM_PURPOSE_DECRYPT, key_id, auth_set));
}

TEST_F(KeymasterBaseTest, TestIncompatiblePurposeAssymmetricKey) {
    AuthorizationSet auth_set(AuthorizationSetBuilder()
                                  .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));

    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set));

    // This one is allowed because it's a pubkey op.
    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_ENCRYPT, key_id, auth_set));
    EXPECT_EQ(KM_ERROR_INCOMPATIBLE_PURPOSE,
              kmen.AuthorizeOperation(KM_PURPOSE_DECRYPT, key_id, auth_set));
}

TEST_F(KeymasterBaseTest, TestInvalidCallerNonce) {
    AuthorizationSet no_caller_nonce(AuthorizationSetBuilder()
                                         .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
                                         .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
    AuthorizationSet caller_nonce(AuthorizationSetBuilder()
                                      .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
                                      .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
                                      .Authorization(TAG_CALLER_NONCE));
    AuthorizationSet begin_params(AuthorizationSetBuilder().Authorization(TAG_NONCE, "foo", 3));

    EXPECT_EQ(KM_ERROR_OK,
              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, caller_nonce, begin_params,
                                      0 /* challenge */, false /* is_begin_operation */));
    EXPECT_EQ(KM_ERROR_CALLER_NONCE_PROHIBITED,
              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, no_caller_nonce, begin_params,
                                      0 /* challenge */, false /* is_begin_operation */));
}

TEST_F(KeymasterBaseTest, TestBootloaderOnly) {
    AuthorizationSet auth_set(AuthorizationSetBuilder()
                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
                                  .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
                                  .Authorization(TAG_BOOTLOADER_ONLY));
    EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
}

TEST_F(KeymasterBaseTest, TestInvalidTag) {
    AuthorizationSet auth_set(AuthorizationSetBuilder()
                                  .Authorization(TAG_INVALID)
                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));

    EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
}

TEST_F(KeymasterBaseTest, TestAuthPerOpSuccess) {
    hw_auth_token_t token;
    memset(&token, 0, sizeof(token));
    token.version = HW_AUTH_TOKEN_VERSION;
    token.challenge = 99;
    token.user_id = 9;
    token.authenticator_id = 0;
    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
    token.timestamp = 0;

    AuthorizationSet auth_set(AuthorizationSetBuilder()
                                  .Authorization(TAG_USER_SECURE_ID, token.user_id)
                                  .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_ANY)
                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));

    AuthorizationSet op_params;
    op_params.push_back(Authorization(TAG_AUTH_TOKEN, &token, sizeof(token)));

    EXPECT_EQ(KM_ERROR_OK,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params, token.challenge,
                                      false /* is_begin_operation */));
}

TEST_F(KeymasterBaseTest, TestAuthPerOpInvalidTokenSignature) {
    hw_auth_token_t token;
    memset(&token, 0, sizeof(token));
    token.version = HW_AUTH_TOKEN_VERSION;
    token.challenge = 99;
    token.user_id = 9;
    token.authenticator_id = 0;
    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
    token.timestamp = 0;

    AuthorizationSet auth_set(AuthorizationSetBuilder()
                                  .Authorization(TAG_USER_SECURE_ID, token.user_id)
                                  .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_ANY)
                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));

    AuthorizationSet op_params;
    op_params.push_back(Authorization(TAG_AUTH_TOKEN, &token, sizeof(token)));

    kmen.set_report_token_valid(false);
    EXPECT_EQ(KM_ERROR_KEY_USER_NOT_AUTHENTICATED,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params, token.challenge,
                                      false /* is_begin_operation */));
}

TEST_F(KeymasterBaseTest, TestAuthPerOpWrongChallenge) {
    hw_auth_token_t token;
    memset(&token, 0, sizeof(token));
    token.version = HW_AUTH_TOKEN_VERSION;
    token.challenge = 99;
    token.user_id = 9;
    token.authenticator_id = 0;
    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
    token.timestamp = 0;

    AuthorizationSet auth_set(AuthorizationSetBuilder()
                                  .Authorization(TAG_USER_SECURE_ID, token.user_id)
                                  .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_ANY)
                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));

    AuthorizationSet op_params;
    op_params.push_back(Authorization(TAG_AUTH_TOKEN, &token, sizeof(token)));

    EXPECT_EQ(KM_ERROR_KEY_USER_NOT_AUTHENTICATED,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params,
                                      token.challenge + 1 /* doesn't match token */,
                                      false /* is_begin_operation */));
}

TEST_F(KeymasterBaseTest, TestAuthPerOpNoAuthType) {
    hw_auth_token_t token;
    memset(&token, 0, sizeof(token));
    token.version = HW_AUTH_TOKEN_VERSION;
    token.challenge = 99;
    token.user_id = 9;
    token.authenticator_id = 0;
    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
    token.timestamp = 0;

    AuthorizationSet auth_set(AuthorizationSetBuilder()
                                  .Authorization(TAG_USER_SECURE_ID, token.user_id)
                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));

    AuthorizationSet op_params;
    op_params.push_back(Authorization(TAG_AUTH_TOKEN, &token, sizeof(token)));

    EXPECT_EQ(KM_ERROR_KEY_USER_NOT_AUTHENTICATED,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params, token.challenge,
                                      false /* is_begin_operation */));
}

TEST_F(KeymasterBaseTest, TestAuthPerOpWrongAuthType) {
    hw_auth_token_t token;
    memset(&token, 0, sizeof(token));
    token.version = HW_AUTH_TOKEN_VERSION;
    token.challenge = 99;
    token.user_id = 9;
    token.authenticator_id = 0;
    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
    token.timestamp = 0;

    AuthorizationSet auth_set(
        AuthorizationSetBuilder()
            .Authorization(TAG_USER_SECURE_ID, token.user_id)
            .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_FINGERPRINT /* doesn't match token */)
            .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));

    AuthorizationSet op_params;
    op_params.push_back(Authorization(TAG_AUTH_TOKEN, &token, sizeof(token)));

    EXPECT_EQ(KM_ERROR_KEY_USER_NOT_AUTHENTICATED,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params, token.challenge,
                                      false /* is_begin_operation */));
}

TEST_F(KeymasterBaseTest, TestAuthPerOpWrongSid) {
    hw_auth_token_t token;
    memset(&token, 0, sizeof(token));
    token.version = HW_AUTH_TOKEN_VERSION;
    token.challenge = 99;
    token.user_id = 9;
    token.authenticator_id = 0;
    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
    token.timestamp = 0;

    AuthorizationSet auth_set(
        AuthorizationSetBuilder()
            .Authorization(TAG_USER_SECURE_ID, token.user_id + 1 /* doesn't match token */)
            .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_ANY)
            .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));

    AuthorizationSet op_params;
    op_params.push_back(Authorization(TAG_AUTH_TOKEN, &token, sizeof(token)));

    EXPECT_EQ(KM_ERROR_KEY_USER_NOT_AUTHENTICATED,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params, token.challenge,
                                      false /* is_begin_operation */));
}

TEST_F(KeymasterBaseTest, TestAuthPerOpSuccessAlternateSid) {
    hw_auth_token_t token;
    memset(&token, 0, sizeof(token));
    token.version = HW_AUTH_TOKEN_VERSION;
    token.challenge = 99;
    token.user_id = 9;
    token.authenticator_id = 10;
    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
    token.timestamp = 0;

    AuthorizationSet auth_set(AuthorizationSetBuilder()
                                  .Authorization(TAG_USER_SECURE_ID, token.authenticator_id)
                                  .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_ANY)
                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));

    AuthorizationSet op_params;
    op_params.push_back(Authorization(TAG_AUTH_TOKEN, &token, sizeof(token)));

    EXPECT_EQ(KM_ERROR_OK,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params, token.challenge,
                                      false /* is_begin_operation */));
}

TEST_F(KeymasterBaseTest, TestAuthPerOpMissingToken) {
    hw_auth_token_t token;
    memset(&token, 0, sizeof(token));
    token.version = HW_AUTH_TOKEN_VERSION;
    token.challenge = 99;
    token.user_id = 9;
    token.authenticator_id = 0;
    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
    token.timestamp = 0;

    AuthorizationSet auth_set(AuthorizationSetBuilder()
                                  .Authorization(TAG_USER_SECURE_ID, token.user_id)
                                  .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_ANY)
                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));

    AuthorizationSet op_params;

    // During begin we can skip the auth token
    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params,
                                                   token.challenge, true /* is_begin_operation */));
    // Afterwards we must have authentication
    EXPECT_EQ(KM_ERROR_KEY_USER_NOT_AUTHENTICATED,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params, token.challenge,
                                      false /* is_begin_operation */));
}

TEST_F(KeymasterBaseTest, TestAuthAndNoAuth) {
    AuthorizationSet auth_set(AuthorizationSetBuilder()
                                  .Authorization(TAG_USER_SECURE_ID, 1)
                                  .Authorization(TAG_NO_AUTH_REQUIRED)
                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));

    EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
}

TEST_F(KeymasterBaseTest, TestTimedAuthSuccess) {
    hw_auth_token_t token;
    memset(&token, 0, sizeof(token));
    token.version = HW_AUTH_TOKEN_VERSION;
    token.challenge = 99;
    token.user_id = 9;
    token.authenticator_id = 0;
    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
    token.timestamp = hton(kmen.current_time());

    AuthorizationSet auth_set(AuthorizationSetBuilder()
                                  .Authorization(TAG_USER_SECURE_ID, token.user_id)
                                  .Authorization(TAG_AUTH_TIMEOUT, 1)
                                  .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_ANY)
                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));

    AuthorizationSet op_params;
    op_params.push_back(Authorization(TAG_AUTH_TOKEN, &token, sizeof(token)));

    EXPECT_EQ(KM_ERROR_OK,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params,
                                      0 /* irrelevant */, false /* is_begin_operation */));
}

TEST_F(KeymasterBaseTest, TestTimedAuthTimedOut) {
    hw_auth_token_t token;
    memset(&token, 0, sizeof(token));
    token.version = HW_AUTH_TOKEN_VERSION;
    token.challenge = 99;
    token.user_id = 9;
    token.authenticator_id = 0;
    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
    token.timestamp = hton(static_cast<uint64_t>(kmen.current_time()));

    AuthorizationSet auth_set(AuthorizationSetBuilder()
                                  .Authorization(TAG_USER_SECURE_ID, token.user_id)
                                  .Authorization(TAG_AUTH_TIMEOUT, 1)
                                  .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_ANY)
                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));

    AuthorizationSet op_params;
    op_params.push_back(Authorization(TAG_AUTH_TOKEN, &token, sizeof(token)));

    EXPECT_EQ(KM_ERROR_OK,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params,
                                      0 /* irrelevant */, false /* is_begin_operation */));

    kmen.tick(1);

    // token still good
    EXPECT_EQ(KM_ERROR_OK,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params,
                                      0 /* irrelevant */, false /* is_begin_operation */));

    kmen.tick(1);

    // token expired, not allowed during begin.
    EXPECT_EQ(KM_ERROR_KEY_USER_NOT_AUTHENTICATED,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params,
                                      0 /* irrelevant */, true /* is_begin_operation */));

    // token expired, afterwards it's okay.
    EXPECT_EQ(KM_ERROR_OK,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params,
                                      0 /* irrelevant */, false /* is_begin_operation */));
}

TEST_F(KeymasterBaseTest, TestTimedAuthMissingToken) {
    hw_auth_token_t token;
    memset(&token, 0, sizeof(token));
    token.version = HW_AUTH_TOKEN_VERSION;
    token.challenge = 99;
    token.user_id = 9;
    token.authenticator_id = 0;
    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
    token.timestamp = hton(static_cast<uint64_t>(kmen.current_time()));

    AuthorizationSet auth_set(AuthorizationSetBuilder()
                                  .Authorization(TAG_USER_SECURE_ID, token.user_id)
                                  .Authorization(TAG_AUTH_TIMEOUT, 1)
                                  .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_ANY)
                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));

    AuthorizationSet op_params;

    // Unlike auth-per-op, must have the auth token during begin.
    EXPECT_EQ(KM_ERROR_KEY_USER_NOT_AUTHENTICATED,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params, token.challenge,
                                      true /* is_begin_operation */));

    // And later (though begin would fail, so there wouldn't be a later).
    EXPECT_EQ(KM_ERROR_KEY_USER_NOT_AUTHENTICATED,
              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params, token.challenge,
                                      false /* is_begin_operation */));
}

TEST_F(KeymasterBaseTest, TestCreateKeyId) {
    keymaster_key_blob_t blob = {reinterpret_cast<const uint8_t*>("foobar"), 6};

    km_id_t key_id = 0;
    EXPECT_TRUE(KeymasterEnforcement::CreateKeyId(blob, &key_id));
    EXPECT_NE(0U, key_id);
}

}; /* namespace test */
}; /* namespace keymaster */
