blob: 4b06c0d7d4de170d74b1221df3652b0a1249a95c [file] [log] [blame]
/*
**
** Copyright 2017, The Android Open Source Project
** Copyright 2020, Fairphone B.V.
**
** 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.
*/
#define LOG_TAG "KM0_passthrough"
#include <keymaster/contexts/keymaster0_passthrough_context.h>
#include <memory>
#include <log/log.h>
namespace keymaster {
Keymaster0PassthroughContext::Keymaster0PassthroughContext(keymaster0_device_t *dev)
: PureSoftKeymasterContext() {
km0_engine_.reset(new Keymaster0Engine(dev));
// This discards the parent, software-only RSA and EC factories.
rsa_factory_.reset(new RsaKeymaster0KeyFactory(this, km0_engine_.get()));
ec_factory_.reset(new EcdsaKeymaster0KeyFactory(this, km0_engine_.get()));
}
Keymaster0PassthroughContext::~Keymaster0PassthroughContext() {
}
keymaster_error_t Keymaster0PassthroughContext::ParseKeyBlob(const KeymasterKeyBlob& blob,
const AuthorizationSet& additional_params,
UniquePtr<Key>* key) const {
// Try software first, where we can be sure it behaves as expected if it
// cannot parse the blob.
keymaster_error_t error = PureSoftKeymasterContext::ParseKeyBlob(blob, additional_params, key);
if (error == KM_ERROR_OK) {
ALOGD("Software keymaster successfully parsed the key blob.");
return error;
}
ALOGD("Software keymaster cannot parse the blob; trying legacy hardware keymaster.");
// KM0 doesn't provide an interface to get key characteristics. Instead, we
// have to make assumptions here and check for failures reported by the
// hardware engine.
// Declare that all operations shall be handled by the hardware keymaster.
AuthorizationSet hw_enforced;
hw_enforced.push_back(TAG_PURPOSE, KM_PURPOSE_SIGN);
hw_enforced.push_back(TAG_PURPOSE, KM_PURPOSE_VERIFY);
hw_enforced.push_back(TAG_PURPOSE, KM_PURPOSE_ENCRYPT);
hw_enforced.push_back(TAG_PURPOSE, KM_PURPOSE_DECRYPT);
hw_enforced.push_back(TAG_ALL_USERS);
hw_enforced.push_back(TAG_NO_AUTH_REQUIRED);
// The FP2/msm8974 legacy Android 6 Qualcomm keymaster supports RSA only, no
// digest, no padding.
hw_enforced.push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
hw_enforced.push_back(TAG_DIGEST, KM_DIGEST_NONE);
hw_enforced.push_back(TAG_PADDING, KM_PAD_NONE);
AuthorizationSet sw_enforced;
// The factory takes ownership of the object, so we need a copy.
auto key_material = blob;
error = rsa_factory_->LoadKey(move(key_material), additional_params, move(hw_enforced),
move(sw_enforced), key);
if (error == KM_ERROR_OK) {
ALOGI("Legacy hardware keymaster reports success while parsing the key blob.");
} else {
ALOGI("Legacy hardware keymaster reports failure while parsing the key blob: %i", error);
}
return error;
}
}