Revert^2 "Move keymint to android.hardware.security."
3d1d8409499201442daa5a58d90c33760edba81e
Bug: 175345910
Bug: 171429297
Change-Id: I3f96d11f7d49e48904ab2ba907ac1c616c0f9684
diff --git a/ng/AndroidKeyMintDevice.cpp b/ng/AndroidKeyMintDevice.cpp
new file mode 100644
index 0000000..82e7712
--- /dev/null
+++ b/ng/AndroidKeyMintDevice.cpp
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2020, 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.
+ */
+
+#define LOG_TAG "android.hardware.security.keymint-impl"
+#include <log/log.h>
+
+#include "AndroidKeyMintDevice.h"
+
+#include <aidl/android/hardware/security/keymint/ErrorCode.h>
+
+#include <keymaster/android_keymaster.h>
+#include <keymaster/contexts/pure_soft_keymaster_context.h>
+#include <keymaster/keymaster_configuration.h>
+
+#include "AndroidKeyMintOperation.h"
+#include "KeyMintUtils.h"
+
+namespace aidl::android::hardware::security::keymint {
+
+using namespace ::keymaster;
+
+constexpr size_t kOperationTableSize = 16;
+
+AndroidKeyMintDevice::AndroidKeyMintDevice(SecurityLevel securityLevel)
+ : impl_(new ::keymaster::AndroidKeymaster(
+ [&]() -> auto {
+ auto context = new PureSoftKeymasterContext(
+ KmVersion::KEYMINT_1, static_cast<keymaster_security_level_t>(securityLevel));
+ context->SetSystemVersion(::keymaster::GetOsVersion(),
+ ::keymaster::GetOsPatchlevel());
+ return context;
+ }(),
+ kOperationTableSize)),
+ securityLevel_(securityLevel) {}
+
+AndroidKeyMintDevice::~AndroidKeyMintDevice() {}
+
+ScopedAStatus AndroidKeyMintDevice::getHardwareInfo(KeyMintHardwareInfo* info) {
+ info->versionNumber = 1;
+ info->securityLevel = securityLevel_;
+ info->keyMintName = "FakeKeyMintDevice";
+ info->keyMintAuthorName = "Google";
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus AndroidKeyMintDevice::verifyAuthorization(int64_t challenge, //
+ const HardwareAuthToken& authToken, //
+ VerificationToken* verificationToken) {
+
+ VerifyAuthorizationRequest request;
+ request.challenge = static_cast<uint64_t>(challenge);
+ request.auth_token.challenge = authToken.challenge;
+ request.auth_token.user_id = authToken.userId;
+ request.auth_token.authenticator_id = authToken.authenticatorId;
+ request.auth_token.authenticator_type = legacy_enum_conversion(authToken.authenticatorType);
+
+ // TODO(seleneh) b/162481130 remove the casting once uint is supported in aidl
+ request.auth_token.timestamp = static_cast<uint64_t>(authToken.timestamp.milliSeconds);
+ KeymasterBlob mac(authToken.mac.data(), authToken.mac.size());
+ request.auth_token.mac = KeymasterBlob(authToken.mac.data(), authToken.mac.size());
+
+ auto response = impl_->VerifyAuthorization(request);
+
+ if (response.error != KM_ERROR_OK) {
+ return kmError2ScopedAStatus(response.error);
+ }
+
+ verificationToken->challenge = response.token.challenge;
+ verificationToken->timestamp.milliSeconds = static_cast<int64_t>(response.token.timestamp);
+ verificationToken->securityLevel = legacy_enum_conversion(response.token.security_level);
+ verificationToken->mac = kmBlob2vector(response.token.mac);
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus AndroidKeyMintDevice::addRngEntropy(const vector<uint8_t>& data) {
+ if (data.size() == 0) {
+ return ScopedAStatus::ok();
+ }
+
+ AddEntropyRequest request;
+ request.random_data.Reinitialize(data.data(), data.size());
+
+ AddEntropyResponse response;
+ impl_->AddRngEntropy(request, &response);
+
+ return kmError2ScopedAStatus(response.error);
+}
+
+ScopedAStatus AndroidKeyMintDevice::generateKey(const vector<KeyParameter>& keyParams,
+ ByteArray* generatedKeyBlob,
+ KeyCharacteristics* generatedKeyCharacteristics,
+ vector<Certificate>* /* certChain */) {
+
+ GenerateKeyRequest request;
+ request.key_description.Reinitialize(KmParamSet(keyParams));
+
+ GenerateKeyResponse response;
+ impl_->GenerateKey(request, &response);
+
+ if (response.error != KM_ERROR_OK) {
+ // Note a key difference between this current aidl and previous hal, is
+ // that hal returns void where as aidl returns the error status. If
+ // aidl returns error, then aidl will not return any change you may make
+ // to the out parameters. This is quite different from hal where all
+ // output variable can be modified due to hal returning void.
+ //
+ // So the caller need to be aware not to expect aidl functions to clear
+ // the output variables for you in case of error. If you left some
+ // wrong data set in the out parameters, they will stay there.
+ return kmError2ScopedAStatus(response.error);
+ }
+
+ generatedKeyBlob->data = kmBlob2vector(response.key_blob);
+ generatedKeyCharacteristics->hardwareEnforced = kmParamSet2Aidl(response.enforced);
+ generatedKeyCharacteristics->softwareEnforced = kmParamSet2Aidl(response.unenforced);
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus AndroidKeyMintDevice::importKey(const vector<KeyParameter>& keyParams,
+ KeyFormat keyFormat, const vector<uint8_t>& keyData,
+ ByteArray* importedKeyBlob,
+ KeyCharacteristics* importedKeyCharacteristics,
+ vector<Certificate>* /* certChain */) {
+
+ ImportKeyRequest request;
+ request.key_description.Reinitialize(KmParamSet(keyParams));
+ request.key_format = legacy_enum_conversion(keyFormat);
+ request.SetKeyMaterial(keyData.data(), keyData.size());
+
+ ImportKeyResponse response;
+ impl_->ImportKey(request, &response);
+
+ if (response.error != KM_ERROR_OK) {
+ return kmError2ScopedAStatus(response.error);
+ }
+
+ importedKeyBlob->data = kmBlob2vector(response.key_blob);
+ importedKeyCharacteristics->hardwareEnforced = kmParamSet2Aidl(response.enforced);
+ importedKeyCharacteristics->softwareEnforced = kmParamSet2Aidl(response.unenforced);
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus AndroidKeyMintDevice::importWrappedKey(
+ const vector<uint8_t>& wrappedKeyData, const vector<uint8_t>& wrappingKeyBlob,
+ const vector<uint8_t>& maskingKey, const vector<KeyParameter>& unwrappingParams,
+ int64_t passwordSid, int64_t biometricSid, ByteArray* importedKeyBlob,
+ KeyCharacteristics* importedKeyCharacteristics) {
+
+ ImportWrappedKeyRequest request;
+ request.SetWrappedMaterial(wrappedKeyData.data(), wrappedKeyData.size());
+ request.SetWrappingMaterial(wrappingKeyBlob.data(), wrappingKeyBlob.size());
+ request.SetMaskingKeyMaterial(maskingKey.data(), maskingKey.size());
+ request.additional_params.Reinitialize(KmParamSet(unwrappingParams));
+ request.password_sid = static_cast<uint64_t>(passwordSid);
+ request.biometric_sid = static_cast<uint64_t>(biometricSid);
+
+ ImportWrappedKeyResponse response;
+ impl_->ImportWrappedKey(request, &response);
+
+ if (response.error != KM_ERROR_OK) {
+ return kmError2ScopedAStatus(response.error);
+ }
+
+ importedKeyBlob->data = kmBlob2vector(response.key_blob);
+ importedKeyCharacteristics->hardwareEnforced = kmParamSet2Aidl(response.enforced);
+ importedKeyCharacteristics->softwareEnforced = kmParamSet2Aidl(response.unenforced);
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus AndroidKeyMintDevice::upgradeKey(const vector<uint8_t>& keyBlobToUpgrade,
+ const vector<KeyParameter>& upgradeParams,
+ vector<uint8_t>* keyBlob) {
+
+ UpgradeKeyRequest request;
+ request.SetKeyMaterial(keyBlobToUpgrade.data(), keyBlobToUpgrade.size());
+ request.upgrade_params.Reinitialize(KmParamSet(upgradeParams));
+
+ UpgradeKeyResponse response;
+ impl_->UpgradeKey(request, &response);
+
+ if (response.error != KM_ERROR_OK) {
+ return kmError2ScopedAStatus(response.error);
+ }
+
+ *keyBlob = kmBlob2vector(response.upgraded_key);
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus AndroidKeyMintDevice::deleteKey(const vector<uint8_t>& keyBlob) {
+ DeleteKeyRequest request;
+ request.SetKeyMaterial(keyBlob.data(), keyBlob.size());
+
+ DeleteKeyResponse response;
+ impl_->DeleteKey(request, &response);
+
+ return kmError2ScopedAStatus(response.error);
+}
+
+ScopedAStatus AndroidKeyMintDevice::deleteAllKeys() {
+ // There's nothing to be done to delete software key blobs.
+ DeleteAllKeysRequest request;
+ DeleteAllKeysResponse response;
+ impl_->DeleteAllKeys(request, &response);
+
+ return kmError2ScopedAStatus(response.error);
+}
+
+ScopedAStatus AndroidKeyMintDevice::destroyAttestationIds() {
+ return kmError2ScopedAStatus(KM_ERROR_UNIMPLEMENTED);
+}
+
+ScopedAStatus AndroidKeyMintDevice::begin(KeyPurpose purpose, const vector<uint8_t>& keyBlob,
+ const vector<KeyParameter>& params,
+ const HardwareAuthToken& authToken, BeginResult* result) {
+
+ BeginOperationRequest request;
+ request.purpose = legacy_enum_conversion(purpose);
+ request.SetKeyMaterial(keyBlob.data(), keyBlob.size());
+ request.additional_params.Reinitialize(KmParamSet(params));
+
+ vector<uint8_t> vector_token = authToken2AidlVec(authToken);
+ request.additional_params.push_back(
+ TAG_AUTH_TOKEN, reinterpret_cast<uint8_t*>(vector_token.data()), vector_token.size());
+
+ BeginOperationResponse response;
+ impl_->BeginOperation(request, &response);
+
+ if (response.error != KM_ERROR_OK) {
+ return kmError2ScopedAStatus(response.error);
+ }
+
+ result->params = kmParamSet2Aidl(response.output_params);
+ result->challenge = response.op_handle;
+ result->operation =
+ ndk::SharedRefBase::make<AndroidKeyMintOperation>(impl_, response.op_handle);
+ return ScopedAStatus::ok();
+}
+
+IKeyMintDevice* CreateKeyMintDevice(SecurityLevel securityLevel) {
+
+ return ::new AndroidKeyMintDevice(securityLevel);
+}
+
+} // namespace aidl::android::hardware::security::keymint