Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 96e1e311 authored by Max Bires's avatar Max Bires Committed by Automerger Merge Worker
Browse files

Porting the client <-> HAL service interface am: 261a0490 am: 23ebc59c

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1680132

Change-Id: I4b9e40a1882e9a994164df41cc93907a7be2022a
parents c8f49899 23ebc59c
Loading
Loading
Loading
Loading
+0 −26
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ cc_binary {
        "libkeymint",
        "liblog",
        "libpuresoftkeymasterdevice",
        "libremote_provisioner",
        "libutils",
    ],
    srcs: [
@@ -51,28 +50,3 @@ prebuilt_etc {
    vendor: true,
    src: "android.hardware.hardware_keystore.xml",
}

cc_library {
    name: "libremote_provisioner",
    vendor_available: true,
    static_libs: [
        "libkeymint_remote_prov_support",
    ],
    shared_libs: [
        "android.hardware.security.keymint-V1-ndk_platform",
        "libbinder_ndk",
        "libcppbor_external",
        "libcppcose_rkp",
        "libcrypto",
        "libkeymaster_portable",
        "libkeymint",
        "liblog",
        "libpuresoftkeymasterdevice",
    ],
    export_include_dirs: [
        ".",
    ],
    srcs: [
        "RemotelyProvisionedComponent.cpp",
    ],
}
+0 −175
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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 "RemotelyProvisionedComponent.h"

#include <assert.h>
#include <variant>

#include <cppbor.h>
#include <cppbor_parse.h>

#include <KeyMintUtils.h>
#include <keymaster/cppcose/cppcose.h>
#include <keymaster/keymaster_configuration.h>
#include <remote_prov/remote_prov_utils.h>

#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/rand.h>
#include <openssl/x509.h>

namespace aidl::android::hardware::security::keymint {

using ::std::string;
using ::std::tuple;
using ::std::unique_ptr;
using ::std::variant;
using ::std::vector;
using bytevec = ::std::vector<uint8_t>;

using namespace cppcose;
using namespace keymaster;

namespace {

constexpr auto STATUS_FAILED = RemotelyProvisionedComponent::STATUS_FAILED;

struct AStatusDeleter {
    void operator()(AStatus* p) { AStatus_delete(p); }
};

// TODO(swillden): Remove the dependency on AStatus stuff.  The COSE lib should use something like
// StatusOr, but it shouldn't depend on AStatus.
class Status {
  public:
    Status() {}
    Status(int32_t errCode, const std::string& errMsg)
        : status_(AStatus_fromServiceSpecificErrorWithMessage(errCode, errMsg.c_str())) {}
    explicit Status(const std::string& errMsg)
        : status_(AStatus_fromServiceSpecificErrorWithMessage(STATUS_FAILED, errMsg.c_str())) {}
    Status(AStatus* status) : status_(status) {}
    Status(Status&&) = default;
    Status(const Status&) = delete;

    operator ::ndk::ScopedAStatus() && { return ndk::ScopedAStatus(status_.release()); }

    bool isOk() { return !status_; }

    // Don't call getMessage() unless isOk() returns false;
    const char* getMessage() const { return AStatus_getMessage(status_.get()); }

  private:
    std::unique_ptr<AStatus, AStatusDeleter> status_;
};

template <typename T>
class StatusOr {
  public:
    StatusOr(AStatus* status) : status_(status) {}
    StatusOr(Status status) : status_(std::move(status)) {}
    StatusOr(T val) : value_(std::move(val)) {}

    bool isOk() { return status_.isOk(); }

    T* operator->() & {
        assert(isOk());
        return &value_.value();
    }
    T& operator*() & {
        assert(isOk());
        return value_.value();
    }
    T&& operator*() && {
        assert(isOk());
        return std::move(value_).value();
    }

    const char* getMessage() const {
        assert(!isOk());
        return status_.getMessage();
    }

    Status moveError() {
        assert(!isOk());
        return std::move(status_);
    }

    T moveValue() { return std::move(value_).value(); }

  private:
    Status status_;
    std::optional<T> value_;
};

}  // namespace

RemotelyProvisionedComponent::RemotelyProvisionedComponent(
        std::shared_ptr<keymint::AndroidKeyMintDevice> keymint) {
    impl_ = keymint->getKeymasterImpl();
}

RemotelyProvisionedComponent::~RemotelyProvisionedComponent() {}

ScopedAStatus RemotelyProvisionedComponent::getHardwareInfo(RpcHardwareInfo* info) {
    info->versionNumber = 1;
    info->rpcAuthorName = "Google";
    info->supportedEekCurve = RpcHardwareInfo::CURVE_25519;
    return ScopedAStatus::ok();
}

ScopedAStatus RemotelyProvisionedComponent::generateEcdsaP256KeyPair(bool testMode,
                                                                     MacedPublicKey* macedPublicKey,
                                                                     bytevec* privateKeyHandle) {
    GenerateRkpKeyRequest request(impl_->message_version());
    request.test_mode = testMode;
    GenerateRkpKeyResponse response(impl_->message_version());
    impl_->GenerateRkpKey(request, &response);
    if (response.error != KM_ERROR_OK) {
        return Status(-static_cast<int32_t>(response.error), "Failure in key generation.");
    }

    macedPublicKey->macedKey = km_utils::kmBlob2vector(response.maced_public_key);
    *privateKeyHandle = km_utils::kmBlob2vector(response.key_blob);
    return ScopedAStatus::ok();
}

ScopedAStatus RemotelyProvisionedComponent::generateCertificateRequest(
        bool testMode, const vector<MacedPublicKey>& keysToSign,
        const bytevec& endpointEncCertChain, const bytevec& challenge, DeviceInfo* deviceInfo,
        ProtectedData* protectedData, bytevec* keysToSignMac) {
    GenerateCsrRequest request(impl_->message_version());
    request.test_mode = testMode;
    request.num_keys = keysToSign.size();
    request.keys_to_sign_array = new KeymasterBlob[keysToSign.size()];
    for (int i = 0; i < keysToSign.size(); i++) {
        request.SetKeyToSign(i, keysToSign[i].macedKey.data(), keysToSign[i].macedKey.size());
    }
    request.SetEndpointEncCertChain(endpointEncCertChain.data(), endpointEncCertChain.size());
    request.SetChallenge(challenge.data(), challenge.size());
    GenerateCsrResponse response(impl_->message_version());
    impl_->GenerateCsr(request, &response);

    if (response.error != KM_ERROR_OK) {
        return Status(-static_cast<int32_t>(response.error), "Failure in CSR Generation.");
    }
    deviceInfo->deviceInfo = km_utils::kmBlob2vector(response.device_info_blob);
    protectedData->protectedData = km_utils::kmBlob2vector(response.protected_data_blob);
    *keysToSignMac = km_utils::kmBlob2vector(response.keys_to_sign_mac);
    return ScopedAStatus::ok();
}

}  // namespace aidl::android::hardware::security::keymint
+0 −51
Original line number Diff line number Diff line
/*
 * Copyright (C) 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.
 */

#pragma once

#include <AndroidKeyMintDevice.h>
#include <aidl/android/hardware/security/keymint/BnRemotelyProvisionedComponent.h>
#include <aidl/android/hardware/security/keymint/SecurityLevel.h>
#include <cppbor.h>
#include <keymaster/UniquePtr.h>
#include <keymaster/android_keymaster.h>

namespace aidl::android::hardware::security::keymint {

using ::ndk::ScopedAStatus;

class RemotelyProvisionedComponent : public BnRemotelyProvisionedComponent {
  public:
    explicit RemotelyProvisionedComponent(std::shared_ptr<keymint::AndroidKeyMintDevice> keymint);
    virtual ~RemotelyProvisionedComponent();

    ScopedAStatus getHardwareInfo(RpcHardwareInfo* info) override;

    ScopedAStatus generateEcdsaP256KeyPair(bool testMode, MacedPublicKey* macedPublicKey,
                                           std::vector<uint8_t>* privateKeyHandle) override;

    ScopedAStatus generateCertificateRequest(bool testMode,
                                             const std::vector<MacedPublicKey>& keysToSign,
                                             const std::vector<uint8_t>& endpointEncCertChain,
                                             const std::vector<uint8_t>& challenge,
                                             DeviceInfo* deviceInfo, ProtectedData* protectedData,
                                             std::vector<uint8_t>* keysToSignMac) override;

  private:
    std::shared_ptr<::keymaster::AndroidKeymaster> impl_;
};

}  // namespace aidl::android::hardware::security::keymint
+3 −4
Original line number Diff line number Diff line
@@ -21,14 +21,13 @@
#include <android/binder_process.h>

#include <AndroidKeyMintDevice.h>
#include <AndroidRemotelyProvisionedComponentDevice.h>
#include <AndroidSecureClock.h>
#include <AndroidSharedSecret.h>
#include <keymaster/soft_keymaster_logger.h>

#include "RemotelyProvisionedComponent.h"

using aidl::android::hardware::security::keymint::AndroidKeyMintDevice;
using aidl::android::hardware::security::keymint::RemotelyProvisionedComponent;
using aidl::android::hardware::security::keymint::AndroidRemotelyProvisionedComponentDevice;
using aidl::android::hardware::security::keymint::SecurityLevel;
using aidl::android::hardware::security::secureclock::AndroidSecureClock;
using aidl::android::hardware::security::sharedsecret::AndroidSharedSecret;
@@ -56,7 +55,7 @@ int main() {
    // Add Shared Secret Service
    addService<AndroidSharedSecret>(keyMint);
    // Add Remotely Provisioned Component Service
    addService<RemotelyProvisionedComponent>(keyMint);
    addService<AndroidRemotelyProvisionedComponentDevice>(keyMint);
    ABinderProcess_joinThreadPool();
    return EXIT_FAILURE;  // should not reach
}
+0 −1
Original line number Diff line number Diff line
@@ -106,7 +106,6 @@ cc_test {
        "libkeymint_remote_prov_support",
        "libkeymint_vts_test_utils",
        "libpuresoftkeymasterdevice",
        "libremote_provisioner",
    ],
    test_suites: [
        "general-tests",
Loading