12fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis/*
22fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis**
32fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis** Copyright 2017, The Android Open Source Project
42fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis**
52fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis** Licensed under the Apache License, Version 2.0 (the "License");
62fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis** you may not use this file except in compliance with the License.
72fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis** You may obtain a copy of the License at
82fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis**
92fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis**     http://www.apache.org/licenses/LICENSE-2.0
102fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis**
112fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis** Unless required by applicable law or agreed to in writing, software
122fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis** distributed under the License is distributed on an "AS IS" BASIS,
132fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis** See the License for the specific language governing permissions and
152fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis** limitations under the License.
162fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis*/
172fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
182fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis#include <keymaster/contexts/keymaster2_passthrough_context.h>
192fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
202fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis#include <keymaster/legacy_support/keymaster_passthrough_key.h>
212fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis#include <keymaster/legacy_support/keymaster_passthrough_engine.h>
222fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
232fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskisnamespace keymaster {
242fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
252fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis DanisevskisKeymaster2PassthroughContext::Keymaster2PassthroughContext(keymaster2_device_t* dev)
262fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        : device_(dev), engine_(KeymasterPassthroughEngine::createInstance(dev)) {
272fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
282fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis}
292fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
302fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskiskeymaster_error_t Keymaster2PassthroughContext::SetSystemVersion(uint32_t os_version,
312fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        uint32_t os_patchlevel) {
322fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    os_version_ = os_version;
332fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    os_patchlevel_ = os_patchlevel;
342fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    return KM_ERROR_OK;
352fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis}
362fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
372fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskisvoid Keymaster2PassthroughContext::GetSystemVersion(uint32_t* os_version,
382fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        uint32_t* os_patchlevel) const {
392fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    if (os_version) *os_version = os_version_;
402fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    if (os_patchlevel) *os_patchlevel = os_patchlevel_;
412fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis}
422fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
432fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis DanisevskisKeyFactory* Keymaster2PassthroughContext::GetKeyFactory(keymaster_algorithm_t algorithm) const {
442fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    auto& result = factories_[algorithm];
452fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    if (!result) {
462fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        result.reset(new KeymasterPassthroughKeyFactory(engine_.get(), algorithm));
472fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    }
482fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    return result.get();
492fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis}
502fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis DanisevskisOperationFactory* Keymaster2PassthroughContext::GetOperationFactory(keymaster_algorithm_t algorithm,
512fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        keymaster_purpose_t purpose) const {
522fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    auto keyfactory = GetKeyFactory(algorithm);
532fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    return keyfactory->GetOperationFactory(purpose);
542fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis}
552fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskiskeymaster_algorithm_t* Keymaster2PassthroughContext::GetSupportedAlgorithms(
562fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        size_t* algorithms_count) const {
572fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    if (algorithms_count) *algorithms_count = 0;
582fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    return nullptr;
592fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis}
602fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
612fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskiskeymaster_error_t Keymaster2PassthroughContext::UpgradeKeyBlob(
622fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        const KeymasterKeyBlob& key_to_upgrade, const AuthorizationSet& upgrade_params,
632fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        KeymasterKeyBlob* upgraded_key) const {
642fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    if (!upgraded_key) return KM_ERROR_UNEXPECTED_NULL_POINTER;
652fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    *upgraded_key = {};
662fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    return device_->upgrade_key(device_, &key_to_upgrade, &upgrade_params, upgraded_key);
672fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis}
682fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
692fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskiskeymaster_error_t Keymaster2PassthroughContext::ParseKeyBlob(const KeymasterKeyBlob& blob,
702fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        const AuthorizationSet& additional_params, UniquePtr<Key>* key) const {
712fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    keymaster_key_characteristics_t characteristics = {};
72c6d9000526f463bc109964b73ed751ae09fc2da7Janis Danisevskis    keymaster_blob_t clientId;
73c6d9000526f463bc109964b73ed751ae09fc2da7Janis Danisevskis    keymaster_blob_t applicationData;
74c6d9000526f463bc109964b73ed751ae09fc2da7Janis Danisevskis    keymaster_blob_t* clientIdPtr = &clientId;
75c6d9000526f463bc109964b73ed751ae09fc2da7Janis Danisevskis    keymaster_blob_t* applicationDataPtr = &applicationData;
762fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    if (!additional_params.GetTagValue(TAG_APPLICATION_ID, clientIdPtr)) {
772fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        clientIdPtr = nullptr;
782fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    }
792fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    if (!additional_params.GetTagValue(TAG_APPLICATION_DATA, applicationDataPtr)) {
802fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        applicationDataPtr = nullptr;
812fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    }
822fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
832fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    auto rc = device_->get_key_characteristics(device_, &blob, clientIdPtr, applicationDataPtr,
842fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis                                               &characteristics);
852fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
862fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    if (rc != KM_ERROR_OK) return rc;
872fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
882fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    AuthorizationSet hw_enforced;
892fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    AuthorizationSet sw_enforced;
902fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
912fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    hw_enforced.Reinitialize(characteristics.hw_enforced);
922fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    sw_enforced.Reinitialize(characteristics.sw_enforced);
932fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
942fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    keymaster_free_characteristics(&characteristics);
952fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
962fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    // GetKeyFactory
972fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    keymaster_algorithm_t algorithm;
982fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    if (!hw_enforced.GetTagValue(TAG_ALGORITHM, &algorithm) &&
992fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        !sw_enforced.GetTagValue(TAG_ALGORITHM, &algorithm)) {
1002fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        return KM_ERROR_INVALID_ARGUMENT;
1012fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    }
1022fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
1032fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    KeymasterKeyBlob key_material = blob;
1042fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    auto factory = GetKeyFactory(algorithm);
1052fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    return factory->LoadKey(move(key_material), additional_params, move(hw_enforced),
1062fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis                            move(sw_enforced), key);
1072fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis}
1082fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
1092fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskiskeymaster_error_t Keymaster2PassthroughContext::DeleteKey(const KeymasterKeyBlob& blob) const {
1102fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    return device_->delete_key(device_, &blob);
1112fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis}
1122fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
1132fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskiskeymaster_error_t Keymaster2PassthroughContext::DeleteAllKeys() const {
1142fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    return device_->delete_all_keys(device_);
1152fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis}
1162fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
1172fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskiskeymaster_error_t Keymaster2PassthroughContext::AddRngEntropy(const uint8_t* buf,
1182fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        size_t length) const {
1192fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    return device_->add_rng_entropy(device_, buf, length);
1202fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis}
1212fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
1222fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
1232fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis DanisevskisKeymasterEnforcement* Keymaster2PassthroughContext::enforcement_policy() {
1242fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    return nullptr;
1252fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis}
1262fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
1272fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskiskeymaster_error_t Keymaster2PassthroughContext::GenerateAttestation(const Key& key,
1282fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        const AuthorizationSet& attest_params, CertChainPtr* cert_chain) const {
1292fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    if (!cert_chain) return KM_ERROR_UNEXPECTED_NULL_POINTER;
1302fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
1312fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    keymaster_cert_chain_t cchain{};
1322fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
1332fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    auto rc = device_->attest_key(device_, &key.key_material(), &attest_params, &cchain);
1342fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    if (rc == KM_ERROR_OK) {
1352fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        cert_chain->reset(new keymaster_cert_chain_t);
1362fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        **cert_chain = { new keymaster_blob_t[cchain.entry_count], cchain.entry_count };
1372fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        for (size_t i = 0; i < cchain.entry_count; ++i) {
1382fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis            (*cert_chain)->entries[i] = { dup_array(cchain.entries[i].data,
1392fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis                                              cchain.entries[i].data_length),
1402fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis                                          cchain.entries[i].data_length };
1412fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis            free(const_cast<uint8_t*>(cchain.entries[i].data));
1422fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        }
1432fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis        free(cchain.entries);
1442fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    }
1452fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis    return rc;
1462fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis}
1472fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis
148dd7e8a099bdc6310c066d7b99f29faa8d0932c86Shawn Willdenkeymaster_error_t Keymaster2PassthroughContext::UnwrapKey(
149dd7e8a099bdc6310c066d7b99f29faa8d0932c86Shawn Willden    const KeymasterKeyBlob&, const KeymasterKeyBlob&, const AuthorizationSet&,
150dd7e8a099bdc6310c066d7b99f29faa8d0932c86Shawn Willden    const KeymasterKeyBlob&, AuthorizationSet*, keymaster_key_format_t*, KeymasterKeyBlob*) const {
151dd7e8a099bdc6310c066d7b99f29faa8d0932c86Shawn Willden    return KM_ERROR_UNIMPLEMENTED;
152dd7e8a099bdc6310c066d7b99f29faa8d0932c86Shawn Willden}
153dd7e8a099bdc6310c066d7b99f29faa8d0932c86Shawn Willden
1542fea23526da2de688d8a18a388e2bfdf2f3a5e57Janis Danisevskis} // namespace keymaster
155