/* ** ** 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. */ #include "keymaster_passthrough_operation.h" #include #include #include #include #include #include #include #include #define LOG_TAG "Keymaster2Engine" #include using std::unique_ptr; namespace keymaster { template class TKeymasterPassthroughEngine : public KeymasterPassthroughEngine { using opfactory_t = KeymasterPassthroughOperationFactory; public: /** * The engine takes ownership of the device, and will close it during destruction. */ explicit TKeymasterPassthroughEngine(const KeymasterDeviceType* km_device) : km_device_(km_device) { rsa_encrypt_op_factory_.reset( new opfactory_t(KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT, km_device_)); rsa_decrypt_op_factory_.reset( new opfactory_t(KM_ALGORITHM_RSA, KM_PURPOSE_DECRYPT, km_device_)); rsa_sign_op_factory_.reset(new opfactory_t(KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, km_device_)); rsa_verify_op_factory_.reset( new opfactory_t(KM_ALGORITHM_RSA, KM_PURPOSE_VERIFY, km_device_)); ec_encrypt_op_factory_.reset( new opfactory_t(KM_ALGORITHM_EC, KM_PURPOSE_ENCRYPT, km_device_)); ec_decrypt_op_factory_.reset( new opfactory_t(KM_ALGORITHM_EC, KM_PURPOSE_DECRYPT, km_device_)); ec_sign_op_factory_.reset(new opfactory_t(KM_ALGORITHM_EC, KM_PURPOSE_SIGN, km_device_)); ec_verify_op_factory_.reset( new opfactory_t(KM_ALGORITHM_EC, KM_PURPOSE_VERIFY, km_device_)); ec_derive_op_factory_.reset( new opfactory_t(KM_ALGORITHM_EC, KM_PURPOSE_DERIVE_KEY, km_device_)); aes_encrypt_op_factory_.reset( new opfactory_t(KM_ALGORITHM_AES, KM_PURPOSE_ENCRYPT, km_device_)); aes_decrypt_op_factory_.reset( new opfactory_t(KM_ALGORITHM_AES, KM_PURPOSE_DECRYPT, km_device_)); triple_des_encrypt_op_factory_.reset( new opfactory_t(KM_ALGORITHM_TRIPLE_DES, KM_PURPOSE_ENCRYPT, km_device_)); triple_des_decrypt_op_factory_.reset( new opfactory_t(KM_ALGORITHM_TRIPLE_DES, KM_PURPOSE_DECRYPT, km_device_)); hmac_sign_op_factory_.reset( new opfactory_t(KM_ALGORITHM_HMAC, KM_PURPOSE_SIGN, km_device_)); hmac_verify_op_factory_.reset( new opfactory_t(KM_ALGORITHM_HMAC, KM_PURPOSE_VERIFY, km_device_)); } virtual ~TKeymasterPassthroughEngine() { // QUIRK: we only take ownership if this is a KM2 device. // For KM1 the Keymaster1Engine takes ownership if (std::is_same::value) km_device_->common.close( reinterpret_cast(const_cast(km_device_))); } keymaster_error_t GenerateKey(const AuthorizationSet& key_description, KeymasterKeyBlob* key_material, AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const override; keymaster_error_t ImportKey(const AuthorizationSet& key_description, keymaster_key_format_t input_key_material_format, const KeymasterKeyBlob& input_key_material, KeymasterKeyBlob* output_key_blob, AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const override; keymaster_error_t ExportKey(keymaster_key_format_t format, const KeymasterKeyBlob& blob, const KeymasterBlob& client_id, const KeymasterBlob& app_data, KeymasterBlob* export_data) const override { keymaster_blob_t my_export_data = {}; keymaster_error_t error = km_device_->export_key(km_device_, format, &blob, &client_id, &app_data, &my_export_data); if (error != KM_ERROR_OK) return error; *export_data = KeymasterBlob(my_export_data.data, my_export_data.data_length); free(const_cast(my_export_data.data)); if (export_data->data == nullptr) { return KM_ERROR_MEMORY_ALLOCATION_FAILED; } return error; } keymaster_error_t DeleteKey(const KeymasterKeyBlob& blob) const override { return km_device_->delete_key(km_device_, &blob); } keymaster_error_t DeleteAllKeys() const override { return km_device_->delete_all_keys(km_device_); } OperationFactory* GetOperationFactory(keymaster_purpose_t purpose, keymaster_algorithm_t algorithm) const override { switch (algorithm) { case KM_ALGORITHM_RSA: switch (purpose) { case KM_PURPOSE_ENCRYPT: return rsa_encrypt_op_factory_.get(); case KM_PURPOSE_DECRYPT: return rsa_decrypt_op_factory_.get(); case KM_PURPOSE_SIGN: return rsa_sign_op_factory_.get(); case KM_PURPOSE_VERIFY: return rsa_verify_op_factory_.get(); default: return nullptr; } case KM_ALGORITHM_EC: switch (purpose) { case KM_PURPOSE_ENCRYPT: return ec_encrypt_op_factory_.get(); case KM_PURPOSE_DECRYPT: return ec_decrypt_op_factory_.get(); case KM_PURPOSE_SIGN: return ec_sign_op_factory_.get(); case KM_PURPOSE_VERIFY: return ec_verify_op_factory_.get(); case KM_PURPOSE_DERIVE_KEY: return ec_derive_op_factory_.get(); default: return nullptr; } case KM_ALGORITHM_AES: switch (purpose) { case KM_PURPOSE_ENCRYPT: return aes_encrypt_op_factory_.get(); case KM_PURPOSE_DECRYPT: return aes_decrypt_op_factory_.get(); default: return nullptr; } case KM_ALGORITHM_TRIPLE_DES: switch (purpose) { case KM_PURPOSE_ENCRYPT: return triple_des_encrypt_op_factory_.get(); case KM_PURPOSE_DECRYPT: return triple_des_decrypt_op_factory_.get(); default: return nullptr; } case KM_ALGORITHM_HMAC: switch (purpose) { case KM_PURPOSE_SIGN: return hmac_sign_op_factory_.get(); case KM_PURPOSE_VERIFY: return hmac_verify_op_factory_.get(); default: return nullptr; } } } const KeymasterDeviceType* device() const { return km_device_; } private: TKeymasterPassthroughEngine(const KeymasterPassthroughEngine&) = delete; // Uncopyable void operator=(const KeymasterPassthroughEngine&) = delete; // Unassignable const KeymasterDeviceType* const km_device_; std::unique_ptr rsa_encrypt_op_factory_; std::unique_ptr rsa_decrypt_op_factory_; std::unique_ptr rsa_sign_op_factory_; std::unique_ptr rsa_verify_op_factory_; std::unique_ptr ec_encrypt_op_factory_; std::unique_ptr ec_decrypt_op_factory_; std::unique_ptr ec_sign_op_factory_; std::unique_ptr ec_verify_op_factory_; std::unique_ptr ec_derive_op_factory_; std::unique_ptr aes_encrypt_op_factory_; std::unique_ptr aes_decrypt_op_factory_; std::unique_ptr triple_des_encrypt_op_factory_; std::unique_ptr triple_des_decrypt_op_factory_; std::unique_ptr hmac_sign_op_factory_; std::unique_ptr hmac_verify_op_factory_; }; static void ConvertCharacteristics(const keymaster_key_characteristics_t& characteristics, AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) { if (hw_enforced) hw_enforced->Reinitialize(characteristics.hw_enforced); if (sw_enforced) sw_enforced->Reinitialize(characteristics.sw_enforced); } template <> keymaster_error_t TKeymasterPassthroughEngine::GenerateKey( const AuthorizationSet& key_description, KeymasterKeyBlob* key_blob, AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const { assert(key_blob); keymaster_key_characteristics_t* characteristics = nullptr; keymaster_key_blob_t blob = {}; keymaster_error_t error = km_device_->generate_key(km_device_, &key_description, &blob, &characteristics); if (error != KM_ERROR_OK) return error; unique_ptr blob_deleter(const_cast(blob.key_material)); key_blob->key_material = dup_buffer(blob.key_material, blob.key_material_size); key_blob->key_material_size = blob.key_material_size; ConvertCharacteristics(*characteristics, hw_enforced, sw_enforced); keymaster_free_characteristics(characteristics); free(characteristics); return error; } template <> keymaster_error_t TKeymasterPassthroughEngine::GenerateKey( const AuthorizationSet& key_description, KeymasterKeyBlob* key_blob, AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const { assert(key_blob); keymaster_key_characteristics_t characteristics = {}; keymaster_key_blob_t blob = {}; keymaster_error_t error = km_device_->generate_key(km_device_, &key_description, &blob, &characteristics); if (error != KM_ERROR_OK) return error; unique_ptr blob_deleter(const_cast(blob.key_material)); key_blob->key_material = dup_buffer(blob.key_material, blob.key_material_size); key_blob->key_material_size = blob.key_material_size; ConvertCharacteristics(characteristics, hw_enforced, sw_enforced); keymaster_free_characteristics(&characteristics); return error; } template <> keymaster_error_t TKeymasterPassthroughEngine::ImportKey( const AuthorizationSet& key_description, keymaster_key_format_t input_key_material_format, const KeymasterKeyBlob& input_key_material, KeymasterKeyBlob* output_key_blob, AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const { assert(output_key_blob); keymaster_key_characteristics_t* characteristics = {}; const keymaster_blob_t input_key = {input_key_material.key_material, input_key_material.key_material_size}; keymaster_key_blob_t blob = {}; keymaster_error_t error = km_device_->import_key(km_device_, &key_description, input_key_material_format, &input_key, &blob, &characteristics); if (error != KM_ERROR_OK) return error; unique_ptr blob_deleter(const_cast(blob.key_material)); *output_key_blob = KeymasterKeyBlob(blob); ConvertCharacteristics(*characteristics, hw_enforced, sw_enforced); keymaster_free_characteristics(characteristics); free(characteristics); return error; } template <> keymaster_error_t TKeymasterPassthroughEngine::ImportKey( const AuthorizationSet& key_description, keymaster_key_format_t input_key_material_format, const KeymasterKeyBlob& input_key_material, KeymasterKeyBlob* output_key_blob, AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const { assert(output_key_blob); keymaster_key_characteristics_t characteristics = {}; const keymaster_blob_t input_key = {input_key_material.key_material, input_key_material.key_material_size}; keymaster_key_blob_t blob = {}; keymaster_error_t error = km_device_->import_key(km_device_, &key_description, input_key_material_format, &input_key, &blob, &characteristics); if (error != KM_ERROR_OK) return error; unique_ptr blob_deleter(const_cast(blob.key_material)); // TODO why duplicate the blob if we have ownership here anyway? output_key_blob->key_material = dup_buffer(blob.key_material, blob.key_material_size); output_key_blob->key_material_size = blob.key_material_size; ConvertCharacteristics(characteristics, hw_enforced, sw_enforced); keymaster_free_characteristics(&characteristics); return error; } typedef UniquePtr engine_ptr_t; engine_ptr_t KeymasterPassthroughEngine::createInstance(const keymaster1_device_t* dev) { return engine_ptr_t(new TKeymasterPassthroughEngine(dev)); } engine_ptr_t KeymasterPassthroughEngine::createInstance(const keymaster2_device_t* dev) { return engine_ptr_t(new TKeymasterPassthroughEngine(dev)); } } // namespace keymaster