| /* |
| * 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_ |