blob: 4fa7b8a0fd7889bb991a1635a93ee7d7872e660d [file] [log] [blame]
/*
* Copyright 2017 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 TRUSTY_APP_KEYMASTER_ACCESS_STORAGE_H_
#define TRUSTY_APP_KEYMASTER_ACCESS_STORAGE_H_
#include <keymaster/UniquePtr.h>
#include <keymaster/android_keymaster_utils.h>
#include <lib/storage/storage.h>
extern "C" {
#include <hardware/keymaster_defs.h>
#include <libatap/atap_types.h>
}
#include "keymaster_attributes.pb.h"
#include "trusty_keymaster_messages.h"
namespace keymaster {
/* The uuid size matches, by design, ATAP_HEX_UUID_LEN in
* system/iot/attestation/atap. */
static const size_t kAttestationUuidSize = 32;
/* ATAP_PRODUCT_ID_LEN in system/iot/attestation/atap. */
static const size_t kProductIdSize = 16;
static const int kMaxCertChainLength = 3;
// RSA and ECDSA are set to be the same as keymaster_algorithm_t.
enum class AttestationKeySlot {
kInvalid = 0,
kRsa = 1,
kEcdsa = 3,
kEddsa = 4,
kEpid = 5,
// 'Claimable slots are for use with the claim_key HAL method.
kClaimable0 = 128,
// 'Som' slots are for Android Things SoM keys. These are generic, that is
// they are not associated with a particular model or product.
kSomRsa = 257,
kSomEcdsa = 259,
kSomEddsa = 260,
kSomEpid = 261,
};
struct Certificate {
uint32_t cert_size;
UniquePtr<uint8_t[]> cert_data;
};
class SecureStorageManager {
public:
/**
* Get a SecureStorageManager instance. The instance returned is shared with
* all other callers, so it is not safe to call any api that does not commit
* the transaction and then let other clients use the api. get_instance will
* also discard any previous transaction to detect if the session is still
* alive, and to make the starting state more predictable.
*/
static SecureStorageManager* get_instance(bool translate_format = true);
/**
* These functions implement key and certificate chain storage on top
* Trusty's secure storage service. All data is stored in the RPMB
* filesystem.
*/
/**
* Writes |key_size| bytes at |key| to key/cert file associated with
* |key_slot|.
*/
keymaster_error_t WriteKeyToStorage(AttestationKeySlot key_slot,
const uint8_t* key,
uint32_t key_size);
/**
* Reads key associated with |key_slot|.
*/
KeymasterKeyBlob ReadKeyFromStorage(AttestationKeySlot key_slot,
keymaster_error_t* error);
/**
* Checks if |key_slot| attestation key exists in RPMB. On success, writes
* to |exists|.
*/
keymaster_error_t AttestationKeyExists(AttestationKeySlot key_slot,
bool* exists);
/**
* Writes |cert_size| bytes at |cert| to key/cert file associated with
* |key_slot| and |index|. The caller can either write to an exising
* certificate entry, or one past the end of the chain to extend the chain
* length by 1 (|index| = chain length). Fails when |index| > chain length.
*/
keymaster_error_t WriteCertToStorage(AttestationKeySlot key_slot,
const uint8_t* cert,
uint32_t cert_size,
uint32_t index);
/**
* Reads cert chain associated with |key_slot|. Stores certificate chain in
* |cert_chain| and caller takes ownership of all allocated memory.
*/
keymaster_error_t ReadCertChainFromStorage(
AttestationKeySlot key_slot,
keymaster_cert_chain_t* cert_chain);
/**
* Delete cert chain associated with |key_slot|.
*/
keymaster_error_t DeleteCertChainFromStorage(AttestationKeySlot key_slot);
/**
* Reads cert chain associated with |key_slot| in ATAP format. Stores
* certificate chain in |cert_chain| and caller takes ownership of all
* allocated memory.
*/
keymaster_error_t ReadAtapCertChainFromStorage(AttestationKeySlot key_slot,
AtapCertChain* cert_chain);
/*
* Writes the new length of the stored |key_slot| attestation certificate
* chain. If less than the existing certificate chain length, the chain is
* truncated. Input cannot be larger than the current certificate chain
* length + 1.
*/
keymaster_error_t WriteCertChainLength(AttestationKeySlot key_slot,
uint32_t cert_chain_length);
/**
* Reads the current length of the stored |key_slot| attestation certificate
* chain. On success, writes the length to |cert_chain_length|.
*/
keymaster_error_t ReadCertChainLength(AttestationKeySlot key_slot,
uint32_t* cert_chain_length);
/*
* Write a key along with the cert chain to the key/cert file associated
* with |key_slot|. cert_cahin is in ATAP types and is intended to be used
* by trusty_atap_ops.
*/
keymaster_error_t WriteAtapKeyAndCertsToStorage(
AttestationKeySlot key_slot,
const uint8_t* key,
const uint32_t key_size,
const AtapCertChain* cert_chain);
/**
* Writes the |attestation_uuid|.
*/
keymaster_error_t WriteAttestationUuid(
const uint8_t attestation_uuid[kAttestationUuidSize]);
/**
* Reads the |attestation_uuid|. If none exists, sets the uuid to all ascii
* zeros.
*/
keymaster_error_t ReadAttestationUuid(
uint8_t attestation_uuid[kAttestationUuidSize]);
/**
* Delete the |attestation_uuid|. This function is for test only.
*/
keymaster_error_t DeleteAttestationUuid();
/**
* Read the |product_id|. If none exists, sets it to all zeros.
*/
keymaster_error_t ReadProductId(uint8_t product_id[kProductIdSize]);
/**
* Set the |product_id|.
*/
keymaster_error_t SetProductId(const uint8_t product_id[kProductIdSize]);
/**
* Set the attestation IDs for the device. This function can only be used
* once unless Keymaster is in debug mode.
*/
keymaster_error_t SetAttestationIds(
const SetAttestationIdsRequest& request);
/**
* Reads the attestations IDs for the device.
*/
keymaster_error_t ReadAttestationIds(AttestationIds* attestation_ids_p);
/**
* Delete the |product_id|.
*/
keymaster_error_t DeleteProductId();
/**
* Deletes |key_slot| attestation key and associated cert chain from RPMB.
*/
keymaster_error_t DeleteKey(AttestationKeySlot key_slot, bool commit);
/**
* Delete all attestation keys and certificate chains from RPMB.
*/
keymaster_error_t DeleteAllAttestationData();
#ifdef KEYMASTER_LEGACY_FORMAT
/**
* Deprecated, for unit tests only.
*/
keymaster_error_t LegacyWriteKeyToStorage(AttestationKeySlot key_slot,
const uint8_t* key,
uint32_t key_size);
/**
* Deprecated, for unit tests only.
*/
keymaster_error_t LegacyWriteCertToStorage(AttestationKeySlot key_slot,
const uint8_t* cert,
uint32_t cert_size,
uint32_t index);
/**
* Deprecated, for unit tests only.
*/
keymaster_error_t LegacyWriteAttestationUuid(
const uint8_t attestation_uuid[kAttestationUuidSize]);
/**
* Deprecated, for unit tests only.
*/
keymaster_error_t LegacySetProductId(
const uint8_t product_id[kProductIdSize]);
#endif // #define KEYMASTER_LEGACY_FORMAT
private:
bool SecureStorageGetFileSize(const char* filename, uint64_t* size);
bool SecureStorageDeleteFile(const char* filename);
keymaster_error_t ReadKeymasterAttributes(
KeymasterAttributes** km_attributes_p);
keymaster_error_t WriteKeymasterAttributes(
const KeymasterAttributes* km_attributes,
bool commit);
keymaster_error_t WriteAttestationIds(const AttestationIds* attestation_ids,
bool commit);
keymaster_error_t ReadAttestationKey(AttestationKeySlot key_slot,
AttestationKey** attestation_key_p);
keymaster_error_t WriteAttestationKey(AttestationKeySlot key_slot,
const AttestationKey* attestation_key,
bool commit);
keymaster_error_t EncodeToFile(const pb_field_t fields[],
const void* dest_struct,
const char filename[],
bool commit);
keymaster_error_t DecodeFromFile(const pb_field_t fields[],
void* dest_struct,
const char filename[]);
/**
* Translate file format from key/cert per file to new protobuf format.
*/
keymaster_error_t TranslateLegacyFormat();
int StorageOpenSession(const char* type);
void CloseSession();
SecureStorageManager();
~SecureStorageManager();
storage_session_t session_handle_;
#ifdef KEYMASTER_LEGACY_FORMAT
keymaster_error_t LegacySecureStorageRead(const char* filename,
void* data,
uint32_t* size,
uint32_t max_size);
keymaster_error_t LegacySecureStorageWrite(const char* filename,
const uint8_t* data,
uint32_t data_size);
bool legacy_format = true;
#endif // #define KEYMASTER_LEGACY_FORMAT
};
} // namespace keymaster
#endif // TRUSTY_APP_KEYMASTER_SECURE_STORAGE_H_