blob: 0f70ea91ba50912bfeb906c0a90d7dbf11a54b12 [file] [log] [blame]
/*
* 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.
*/
#ifndef ANDROID_LIBRARY_KEYMASTER_ENFORCEMENT_H
#define ANDROID_LIBRARY_KEYMASTER_ENFORCEMENT_H
#include <stdio.h>
#include <utils/List.h>
#include <keymaster/authorization_set.h>
using namespace android;
typedef uint32_t km_id_t;
namespace keymaster {
struct access_time_struct {
uint32_t keyid;
time_t access_time;
};
class KeymasterEnforcement {
public:
KeymasterEnforcement();
~KeymasterEnforcement();
/**
* Iterates through the authorization set and returns the corresponding keymaster error. Will
* return KM_ERROR_OK if all criteria is met for the given purpose in the authorization
* set. Used for encrypt, decrypt sign, and verify.
*/
keymaster_error_t AuthorizeOperation(const keymaster_purpose_t purpose, const km_id_t keyid,
const AuthorizationSet& auth_set, const uid_t uid);
/**
* This is maintained in system/core/include/cutiles/multiuser.h but copied here so that this
* code can be reused without access to the core Android libs.
*/
static const uint32_t MULTIUSER_APP_PER_USER_RANGE = 100000;
private:
/*
* Handles the KM_TAG_ACTIVE_DATETIME tag. Returns KM_ERROR_OK if currentTime is greater than
* the the time value associated with param.
*/
keymaster_error_t Active(const keymaster_key_param_t param, const time_t current_time);
/*
* Handles the KM_TAG_USAGE_EXPIRE_DATETIME tag. Returns KM_ERROR_OK if currentTime is less
* than the time value associated with param and if purpose is KM_PURPOSE_VERIFY. If purpose is
* not KM_PURPOSE_VERIFY will return KM_ERROR_OK.
*/
keymaster_error_t UsageNotExpired(const keymaster_key_param_t param, const time_t current_time,
const keymaster_purpose_t purpose);
/*
* Handles the KM_TAG_ORIGINATION_EXPIRE_TIME tag. Returns KM_ERROR_OK if currentTime is less
* than the time value associated with param and if purpose is KM_PURPOSE_SIGN. If purpose is
* not KM_PURPOSE_SIGN will return KM_ERROR_OK.
*/
keymaster_error_t OriginationNotExpired(const keymaster_key_param_t param,
const time_t current_time,
const keymaster_purpose_t purpose);
/*
* Handles the KM_TAG_MIN_SECONDS_BETWEEN_OPS tag. Returns KM_ERROR_OK if the difference
* between currentTime and the last accessed time for the keyid is less than the time value
* associated with param.
*/
keymaster_error_t MinTimeBetweenOpsPassed(const keymaster_key_param_t param,
const km_id_t keyid, const time_t current_time);
/*
* Handles the KM_TAG_SINGLE_USE_PER_BOOT tag. Returns KM_ERROR_OK if the keyid's last accessed
* time is -1 (has not been accessed).
*/
keymaster_error_t NotUsedSinceBoot(const km_id_t keyid);
/*
* Handles the KM_TAG_USER_ID tag. Returns KM_ERROR_OK if the integer value of the parameter is
* equal to the appId derived from the uid.
*/
keymaster_error_t UserAuthenticated(const keymaster_key_param_t param, const uid_t uid);
/*
* Handles KM_TAG_AUTH_TIMEOUT tags. Returns KM_ERROR_OK if the last time the user
* authenticated is within the required freshness.
*/
keymaster_error_t AuthenticationIsFresh(const keymaster_key_param_t param,
const time_t current_time) const;
/*
* Updates the most recent user authentication time to the current time.
*/
void UpdateUserAuthenticationTime();
/*
* Class to abstract the mechanism used to keep track of access times.
*/
class AccessTimeMap {
public:
AccessTimeMap();
/* Returns the last time the key was accessed. */
time_t last_key_access_time(uint32_t index);
/* Updates the last key access time with the currentTime parameter. */
void update_key_access_time(uint32_t index, time_t current_time);
private:
/**
* Internal datastructure that maps keyid to access time. Can be
* replaced with the cutil hashmap, linked list, etc.
*/
List<access_time_struct> last_access_list;
/* Returns an iterator to the node with the keyid or end if not found. */
List<access_time_struct>::iterator find(uint32_t keyid);
};
/*
* Tests if the purpose is a valid member of keymaster_purpose_t and if the purpose is among
* those listed in the AuthorizationSet and returns KM_ERROR_OK if so and an appropriate error
* otherwise.
*/
keymaster_error_t valid_purpose(const keymaster_purpose_t purpose,
const AuthorizationSet& auth_set);
/*
* Tests that all of the purposes in the authorization set are valid. Returns KM_ERROR_OK if so
* and KM_ERROR_UNSUPPORTED_PURPOSE otherwise.
*/
bool supported_purposes(const AuthorizationSet& auth_set);
/*
* Returns true if the purpose is among supported purposes and false otherwise.
*/
bool supported_purpose(const keymaster_purpose_t purpose);
/*
* Abstraction that currently just returns time(NULL). TODO: time() is a no-op in trusty. Still
* need to handle this.
*/
time_t get_current_time() const;
/*
* Updates the last time that the key was accessed to the current time.
*/
void update_key_access_time(const km_id_t keyid);
/*
* Returns the last time that the key was accessed.
*/
time_t get_last_access_time(const km_id_t keyid);
/*
* Generates the userId from the uid using the formula
* userId = uid / MULTIUSER_APP_PER_USER_RAGE.
*/
static uint32_t get_user_id_from_uid(const uid_t uid);
/* Returns the last time that the user authenticated. */
time_t get_last_auth_time() const;
/*
* Returns KM_ERROR_KEY_EXPIRED if the difference between the current time and the parameters's
* date_time field is positive.
*/
keymaster_error_t is_time_expired(const keymaster_key_param_t param, const time_t current_time);
/* Hashmap of last access times. */
AccessTimeMap accessTimeMap;
/* The time of the most recent user authentication. */
time_t last_auth_time;
};
}; /* namespace keymaster */
#endif // ANDROID_LIBRARY_KEYMASTER_ENFORCEMENT_H