257 lines
12 KiB
C++
257 lines
12 KiB
C++
/*
|
|
* Copyright 2015 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 SYSTEM_KEYMASTER_KEYMASTER_CONTEXT_H_
|
|
#define SYSTEM_KEYMASTER_KEYMASTER_CONTEXT_H_
|
|
|
|
#include <optional>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <hardware/keymaster_defs.h>
|
|
#include <keymaster/android_keymaster_utils.h>
|
|
#include <keymaster/keymaster_enforcement.h>
|
|
#include <keymaster/km_version.h>
|
|
#include <keymaster/remote_provisioning_context.h>
|
|
#include <keymaster/secure_key_storage.h>
|
|
|
|
namespace keymaster {
|
|
|
|
class AuthorizationSet;
|
|
class KeyFactory;
|
|
class OperationFactory;
|
|
template <typename BlobType> struct TKeymasterBlob;
|
|
typedef TKeymasterBlob<keymaster_key_blob_t> KeymasterKeyBlob;
|
|
class Key;
|
|
|
|
/**
|
|
* KeymasterContext provides a singleton abstract interface that encapsulates various
|
|
* environment-dependent elements of AndroidKeymaster.
|
|
*
|
|
* AndroidKeymaster runs in multiple contexts. Primarily:
|
|
*
|
|
* - In a trusted execution environment (TEE) as a "secure hardware" implementation. In this
|
|
* context keys are wrapped with an master key that never leaves the TEE, TEE-specific routines
|
|
* are used for random number generation, all AndroidKeymaster-enforced authorizations are
|
|
* considered hardware-enforced, and there's a bootloader-provided root of trust.
|
|
*
|
|
* - In the non-secure world as a software-only implementation. In this context keys are not
|
|
* encrypted (though they are integrity-checked) because there is no place to securely store a
|
|
* key, OpenSSL is used for random number generation, no AndroidKeymaster-enforced authorizations
|
|
* are considered hardware enforced and the root of trust is a static string.
|
|
*
|
|
* - In the non-secure world as a hybrid implementation fronting a less-capable hardware
|
|
* implementation. For example, a keymaster0 hardware implementation. In this context keys are
|
|
* not encrypted by AndroidKeymaster, but some may be opaque blobs provided by the backing
|
|
* hardware, but blobs that lack the extended authorization lists of keymaster1. In addition,
|
|
* keymaster0 lacks many features of keymaster1, including modes of operation related to the
|
|
* backing keymaster0 keys. AndroidKeymaster must extend the blobs to add authorization lists,
|
|
* and must provide the missing operation mode implementations in software, which means that
|
|
* authorization lists are partially hardware-enforced (the bits that are enforced by the
|
|
* underlying keymaster0) and partially software-enforced (the rest). OpenSSL is used for number
|
|
* generation and the root of trust is a static string.
|
|
*
|
|
* More contexts are possible.
|
|
*/
|
|
class KeymasterContext {
|
|
public:
|
|
KeymasterContext() {}
|
|
virtual ~KeymasterContext(){};
|
|
|
|
/**
|
|
* Returns the Keymaster/KeyMint version we're currently implementing.
|
|
*
|
|
* Because AndroidKeymaster supports multiple versions of Keymaster/KeyMint, with slightly
|
|
* different behavior, we sometimes need to branch based on the version currently being
|
|
* implemented. This method provides the currently-implemented version.
|
|
*/
|
|
virtual KmVersion GetKmVersion() const = 0;
|
|
|
|
/**
|
|
* Sets the system version as reported by the system *itself*. This is used to verify that the
|
|
* system believes itself to be running the same version that is reported by the bootloader, in
|
|
* hardware implementations. For SoftKeymasterDevice, this sets the version information used.
|
|
*
|
|
* If the specified values don't match the bootloader-provided values, this method must return
|
|
* KM_ERROR_INVALID_ARGUMENT;
|
|
*/
|
|
virtual keymaster_error_t SetSystemVersion(uint32_t os_version, uint32_t os_patchlevel) = 0;
|
|
|
|
/**
|
|
* Returns the system version. For hardware-based implementations this will be the value
|
|
* reported by the bootloader. For SoftKeymasterDevice it will be the verion information set by
|
|
* SetSystemVersion above.
|
|
*/
|
|
virtual void GetSystemVersion(uint32_t* os_version, uint32_t* os_patchlevel) const = 0;
|
|
|
|
virtual const KeyFactory* GetKeyFactory(keymaster_algorithm_t algorithm) const = 0;
|
|
virtual const OperationFactory* GetOperationFactory(keymaster_algorithm_t algorithm,
|
|
keymaster_purpose_t purpose) const = 0;
|
|
virtual const keymaster_algorithm_t* GetSupportedAlgorithms(size_t* algorithms_count) const = 0;
|
|
|
|
/**
|
|
* UpgradeKeyBlob takes an existing blob, parses out key material and constructs a new blob with
|
|
* the current format and OS version info.
|
|
*/
|
|
virtual keymaster_error_t UpgradeKeyBlob(const KeymasterKeyBlob& key_to_upgrade,
|
|
const AuthorizationSet& upgrade_params,
|
|
KeymasterKeyBlob* upgraded_key) const = 0;
|
|
|
|
/**
|
|
* ParseKeyBlob takes a blob and extracts authorization sets and key material, returning an
|
|
* error if the blob fails integrity checking or decryption. Note that the returned key
|
|
* material may itself be an opaque blob usable only by secure hardware (in the hybrid case).
|
|
*
|
|
* This method is called by AndroidKeymaster.
|
|
*/
|
|
virtual keymaster_error_t ParseKeyBlob(const KeymasterKeyBlob& blob,
|
|
const AuthorizationSet& additional_params,
|
|
UniquePtr<Key>* key) const = 0;
|
|
|
|
/**
|
|
* Take whatever environment-specific action is appropriate (if any) to delete the specified
|
|
* key.
|
|
*/
|
|
virtual keymaster_error_t DeleteKey(const KeymasterKeyBlob& /* blob */) const {
|
|
return KM_ERROR_OK;
|
|
}
|
|
|
|
/**
|
|
* Take whatever environment-specific action is appropriate to delete all keys.
|
|
*/
|
|
virtual keymaster_error_t DeleteAllKeys() const { return KM_ERROR_OK; }
|
|
|
|
/**
|
|
* Adds entropy to the Cryptographic Pseudo Random Number Generator used to generate key
|
|
* material, and other cryptographic protocol elements. Note that if the underlying CPRNG
|
|
* tracks the size of its entropy pool, it should not assume that the provided data contributes
|
|
* any entropy, and it should also ensure that data provided through this interface cannot
|
|
* "poison" the CPRNG outputs, making them predictable.
|
|
*/
|
|
virtual keymaster_error_t AddRngEntropy(const uint8_t* buf, size_t length) const = 0;
|
|
|
|
/**
|
|
* Return the enforcement policy for this context, or null if no enforcement should be done.
|
|
*/
|
|
virtual KeymasterEnforcement* enforcement_policy() = 0;
|
|
|
|
/**
|
|
* Generate an attestation certificate, with chain.
|
|
*
|
|
* If attest_key is null, the certificate will be signed with the factory attestation key (from
|
|
* AttestationContext) and have the issuer subject set to the subject name from the signing key
|
|
* certificate. If attest_key is non-null, it will be used to sign the certificate and the
|
|
* provided issuer subject will be used (must contain a DER-encoded X.509 NAME).
|
|
*/
|
|
virtual CertificateChain GenerateAttestation(const Key& key,
|
|
const AuthorizationSet& attest_params,
|
|
UniquePtr<Key> attest_key,
|
|
const KeymasterBlob& issuer_subject,
|
|
keymaster_error_t* error) const = 0;
|
|
|
|
/**
|
|
* Generate a self-signed certificate. If fake_signature is true, a fake signature is installed
|
|
* in the certificate, rather than an actual self-signature. The fake signature will not
|
|
* verify, of course. In this case the certificate is primarily a way to convey the public key.
|
|
*
|
|
* Note that although the return type is CertificateChain, this is for convenience and
|
|
* consistency with GenerateAttestation, the chain never contains more than a single
|
|
* certificate.
|
|
*/
|
|
virtual CertificateChain GenerateSelfSignedCertificate(const Key& key,
|
|
const AuthorizationSet& cert_params,
|
|
bool fake_signature,
|
|
keymaster_error_t* error) const = 0;
|
|
|
|
virtual keymaster_error_t
|
|
UnwrapKey(const KeymasterKeyBlob& wrapped_key_blob, const KeymasterKeyBlob& wrapping_key_blob,
|
|
const AuthorizationSet& wrapping_key_params, const KeymasterKeyBlob& masking_key,
|
|
AuthorizationSet* wrapped_key_params, keymaster_key_format_t* wrapped_key_format,
|
|
KeymasterKeyBlob* wrapped_key_material) const = 0;
|
|
|
|
/**
|
|
* Return the secure key storage for this context, or null if there is no available secure key
|
|
* storage.
|
|
*/
|
|
virtual SecureKeyStorage* secure_key_storage() { return nullptr; }
|
|
|
|
/**
|
|
* Checks that the data in |input_data| of size |input_data_size| matches the
|
|
* confirmation token given by |confirmation_token|.
|
|
*
|
|
* Note that |input_data| will already contain the prefixed message tag
|
|
* "confirmation token" (not including NUL byte) so all the implementation
|
|
* of this method needs to do is to calculate HMAC-SHA256 over |input_data|
|
|
* and compare it with |confirmation_token|. To do this the implementation
|
|
* needs access to the secret key shared with the ConfirmationUI TA.
|
|
*
|
|
* Returns KM_ERROR_OK if |input_data| matches |confirmation_token|,
|
|
* KM_ERROR_NO_USER_CONFIRMATION if it doesn't, and if memory allocation
|
|
* fails KM_ERROR_MEMORY_ALLOCATION_FAILED. If not implemented then
|
|
* KM_ERROR_UNIMPLEMENTED is returned.
|
|
*/
|
|
virtual keymaster_error_t
|
|
CheckConfirmationToken(const uint8_t* /*input_data*/, size_t /*input_data_size*/,
|
|
const uint8_t /*confirmation_token*/[kConfirmationTokenSize]) const {
|
|
return KM_ERROR_UNIMPLEMENTED;
|
|
}
|
|
|
|
/**
|
|
* Return the remote provisioning context object, or null if remote provisioning is not
|
|
* supported.
|
|
*/
|
|
virtual RemoteProvisioningContext* GetRemoteProvisioningContext() const { return nullptr; }
|
|
|
|
/**
|
|
* Sets the vendor patchlevel (format YYYYMMDD) for the implementation. This value should
|
|
* be set by the HAL service at start of day. A subsequent attempt to set a different
|
|
* value will return KM_ERROR_INVALID_ARGUMENT.
|
|
*/
|
|
virtual keymaster_error_t SetVendorPatchlevel(uint32_t /* vendor_patchlevel */) {
|
|
return KM_ERROR_UNIMPLEMENTED;
|
|
}
|
|
|
|
/**
|
|
* Sets the boot patchlevel (format YYYYMMDD) for the implementation. This value should be set
|
|
* by the bootloader. A subsequent to set a different value will return
|
|
* KM_ERROR_INVALID_ARGUMENT;
|
|
*/
|
|
virtual keymaster_error_t SetBootPatchlevel(uint32_t /* boot_patchlevel */) {
|
|
return KM_ERROR_UNIMPLEMENTED;
|
|
}
|
|
|
|
/**
|
|
* Returns the vendor patchlevel, as set by the HAL service using SetVendorPatchlevel.
|
|
*/
|
|
virtual std::optional<uint32_t> GetVendorPatchlevel() const { return std::nullopt; }
|
|
|
|
/**
|
|
* Returns the boot patchlevel. For hardware-based implementations this will be the value set by
|
|
* the bootloader. For software implementations this will be the information set by
|
|
* SetBootPatchLevel.
|
|
*/
|
|
virtual std::optional<uint32_t> GetBootPatchlevel() const { return std::nullopt; }
|
|
|
|
private:
|
|
// Uncopyable.
|
|
KeymasterContext(const KeymasterContext&);
|
|
void operator=(const KeymasterContext&);
|
|
};
|
|
|
|
} // namespace keymaster
|
|
|
|
#endif // SYSTEM_KEYMASTER_KEYMASTER_CONTEXT_H_
|