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

Commit 7d339812 authored by Shawn Willden's avatar Shawn Willden
Browse files

Move Keymaster wrapper into support library.

This wrapper was used to manage KM3/KM4 compatibility in keystore.
It's also needed in vold, so this CL moves it here, to make it usable
for vold.

Test: keystore CTS tests
Change-Id: I8079b8577f7d4a8fd67f47fbe1f48861e4a0734b
parent 43ca3b0a
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -26,11 +26,17 @@ cc_library {
        "attestation_record.cpp",
        "authorization_set.cpp",
        "key_param_output.cpp",
        "Keymaster3.cpp",
        "Keymaster4.cpp",
    ],
    export_include_dirs: ["include"],
    shared_libs: [
        "android.hardware.keymaster@3.0",
        "android.hardware.keymaster@4.0",
        "libbase",
        "libcrypto",
        "libhidlbase",
        "libhidltransport",
        "libutils",
    ]
}
+325 −0
Original line number Diff line number Diff line
/*
 **
 ** 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 <keymasterV4_0/Keymaster3.h>

#include <android-base/logging.h>
#include <hardware/hw_auth_token.h>

namespace android {
namespace hardware {
namespace keymaster {
namespace V4_0 {
namespace support {

using android::hardware::details::StatusOf;

namespace {

ErrorCode convert(V3_0::ErrorCode error) {
    return static_cast<ErrorCode>(error);
}

V3_0::KeyPurpose convert(KeyPurpose purpose) {
    return static_cast<V3_0::KeyPurpose>(purpose);
}

V3_0::KeyFormat convert(KeyFormat purpose) {
    return static_cast<V3_0::KeyFormat>(purpose);
}

V3_0::KeyParameter convert(const KeyParameter& param) {
    V3_0::KeyParameter converted;
    converted.tag = static_cast<V3_0::Tag>(param.tag);
    static_assert(sizeof(converted.f) == sizeof(param.f), "This function assumes sizes match");
    memcpy(&converted.f, &param.f, sizeof(param.f));
    converted.blob = param.blob;
    return converted;
}

KeyParameter convert(const V3_0::KeyParameter& param) {
    KeyParameter converted;
    converted.tag = static_cast<Tag>(param.tag);
    static_assert(sizeof(converted.f) == sizeof(param.f), "This function assumes sizes match");
    memcpy(&converted.f, &param.f, sizeof(param.f));
    converted.blob = param.blob;
    return converted;
}

hidl_vec<V3_0::KeyParameter> convert(const hidl_vec<KeyParameter>& params) {
    hidl_vec<V3_0::KeyParameter> converted(params.size());
    for (size_t i = 0; i < params.size(); ++i) {
        converted[i] = convert(params[i]);
    }
    return converted;
}

hidl_vec<KeyParameter> convert(const hidl_vec<V3_0::KeyParameter>& params) {
    hidl_vec<KeyParameter> converted(params.size());
    for (size_t i = 0; i < params.size(); ++i) {
        converted[i] = convert(params[i]);
    }
    return converted;
}

template <typename T, typename OutIter>
inline static OutIter copy_bytes_to_iterator(const T& value, OutIter dest) {
    const uint8_t* value_ptr = reinterpret_cast<const uint8_t*>(&value);
    return std::copy(value_ptr, value_ptr + sizeof(value), dest);
}

constexpr size_t kHmacSize = 32;

inline static hidl_vec<uint8_t> authToken2HidlVec(const HardwareAuthToken& token) {
    static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) +
                          sizeof(token.authenticatorId) + sizeof(token.authenticatorType) +
                          sizeof(token.timestamp) + kHmacSize ==
                      sizeof(hw_auth_token_t),
                  "HardwareAuthToken content size does not match hw_auth_token_t size");

    hidl_vec<uint8_t> result;
    result.resize(sizeof(hw_auth_token_t));
    auto pos = result.begin();
    *pos++ = 0;  // Version byte
    pos = copy_bytes_to_iterator(token.challenge, pos);
    pos = copy_bytes_to_iterator(token.userId, pos);
    pos = copy_bytes_to_iterator(token.authenticatorId, pos);
    auto auth_type = htonl(static_cast<uint32_t>(token.authenticatorType));
    pos = copy_bytes_to_iterator(auth_type, pos);
    auto timestamp = htonq(token.timestamp);
    pos = copy_bytes_to_iterator(timestamp, pos);
    if (token.mac.size() != kHmacSize) {
        std::fill(pos, pos + kHmacSize, 0);
    } else {
        std::copy(token.mac.begin(), token.mac.end(), pos);
    }

    return result;
}

hidl_vec<V3_0::KeyParameter> convertAndAddAuthToken(const hidl_vec<KeyParameter>& params,
                                                    const HardwareAuthToken& authToken) {
    hidl_vec<V3_0::KeyParameter> converted(params.size() + 1);
    for (size_t i = 0; i < params.size(); ++i) {
        converted[i] = convert(params[i]);
    }
    converted[params.size()].tag = V3_0::Tag::AUTH_TOKEN;
    converted[params.size()].blob = authToken2HidlVec(authToken);

    return converted;
}

KeyCharacteristics convert(const V3_0::KeyCharacteristics& chars) {
    KeyCharacteristics converted;
    converted.hardwareEnforced = convert(chars.teeEnforced);
    converted.softwareEnforced = convert(chars.softwareEnforced);
    return converted;
}

}  // namespace

void Keymaster3::getVersionIfNeeded() {
    if (haveVersion_) return;

    auto rc = km3_dev_->getHardwareFeatures(
        [&](bool isSecure, bool supportsEllipticCurve, bool supportsSymmetricCryptography,
            bool supportsAttestation, bool supportsAllDigests, const hidl_string& keymasterName,
            const hidl_string& keymasterAuthorName) {
            securityLevel_ =
                isSecure ? SecurityLevel::TRUSTED_ENVIRONMENT : SecurityLevel::SOFTWARE;
            supportsEllipticCurve_ = supportsEllipticCurve;
            supportsSymmetricCryptography_ = supportsSymmetricCryptography;
            supportsAttestation_ = supportsAttestation;
            supportsAllDigests_ = supportsAllDigests;
            keymasterName_ = keymasterName;
            authorName_ = keymasterAuthorName;
        });

    CHECK(rc.isOk()) << "Got error " << rc.description() << " trying to get hardware features";

    if (securityLevel_ == SecurityLevel::SOFTWARE) {
        majorVersion_ = 3;
    } else if (supportsAttestation_) {
        majorVersion_ = 3;  // Could be 2, doesn't matter.
    } else if (supportsSymmetricCryptography_) {
        majorVersion_ = 1;
    } else {
        majorVersion_ = 0;
    }
}

Keymaster::VersionResult Keymaster3::halVersion() {
    getVersionIfNeeded();
    return {ErrorCode::OK, majorVersion_, securityLevel_, supportsEllipticCurve_};
}

Return<void> Keymaster3::getHardwareInfo(Keymaster3::getHardwareInfo_cb _hidl_cb) {
    getVersionIfNeeded();
    _hidl_cb(securityLevel_, keymasterName_ + " (wrapped by keystore::Keymaster3)", authorName_);
    return Void();
}

Return<ErrorCode> Keymaster3::addRngEntropy(const hidl_vec<uint8_t>& data) {
    auto rc = km3_dev_->addRngEntropy(data);
    if (!rc.isOk()) {
        return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
    }
    return convert(rc);
}

Return<void> Keymaster3::generateKey(const hidl_vec<KeyParameter>& keyParams,
                                     generateKey_cb _hidl_cb) {
    auto cb = [&](V3_0::ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
                  const V3_0::KeyCharacteristics& characteristics) {
        _hidl_cb(convert(error), keyBlob, convert(characteristics));
    };
    auto rc = km3_dev_->generateKey(convert(keyParams), cb);
    rc.isOk();  // move ctor prereq
    return rc;
}

Return<void> Keymaster3::getKeyCharacteristics(const hidl_vec<uint8_t>& keyBlob,
                                               const hidl_vec<uint8_t>& clientId,
                                               const hidl_vec<uint8_t>& appData,
                                               getKeyCharacteristics_cb _hidl_cb) {
    auto cb = [&](V3_0::ErrorCode error, const V3_0::KeyCharacteristics& chars) {
        _hidl_cb(convert(error), convert(chars));
    };

    auto rc = km3_dev_->getKeyCharacteristics(keyBlob, clientId, appData, cb);
    rc.isOk();  // move ctor prereq
    return rc;
}

Return<void> Keymaster3::importKey(const hidl_vec<KeyParameter>& params, KeyFormat keyFormat,
                                   const hidl_vec<uint8_t>& keyData, importKey_cb _hidl_cb) {
    auto cb = [&](V3_0::ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
                  const V3_0::KeyCharacteristics& chars) {
        _hidl_cb(convert(error), keyBlob, convert(chars));
    };
    auto rc = km3_dev_->importKey(convert(params), convert(keyFormat), keyData, cb);
    rc.isOk();  // move ctor prereq
    return rc;
}

Return<void> Keymaster3::exportKey(KeyFormat exportFormat, const hidl_vec<uint8_t>& keyBlob,
                                   const hidl_vec<uint8_t>& clientId,
                                   const hidl_vec<uint8_t>& appData, exportKey_cb _hidl_cb) {
    auto cb = [&](V3_0::ErrorCode error, const hidl_vec<uint8_t>& keyMaterial) {
        _hidl_cb(convert(error), keyMaterial);
    };
    auto rc = km3_dev_->exportKey(convert(exportFormat), keyBlob, clientId, appData, cb);
    rc.isOk();  // move ctor prereq
    return rc;
}

Return<void> Keymaster3::attestKey(const hidl_vec<uint8_t>& keyToAttest,
                                   const hidl_vec<KeyParameter>& attestParams,
                                   attestKey_cb _hidl_cb) {
    auto cb = [&](V3_0::ErrorCode error, const hidl_vec<hidl_vec<uint8_t>>& certChain) {
        _hidl_cb(convert(error), certChain);
    };
    auto rc = km3_dev_->attestKey(keyToAttest, convert(attestParams), cb);
    rc.isOk();  // move ctor prereq
    return rc;
}

Return<void> Keymaster3::upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
                                    const hidl_vec<KeyParameter>& upgradeParams,
                                    upgradeKey_cb _hidl_cb) {
    auto cb = [&](V3_0::ErrorCode error, const hidl_vec<uint8_t>& upgradedKeyBlob) {
        _hidl_cb(convert(error), upgradedKeyBlob);
    };
    auto rc = km3_dev_->upgradeKey(keyBlobToUpgrade, convert(upgradeParams), cb);
    rc.isOk();  // move ctor prereq
    return rc;
}

Return<ErrorCode> Keymaster3::deleteKey(const hidl_vec<uint8_t>& keyBlob) {
    auto rc = km3_dev_->deleteKey(keyBlob);
    if (!rc.isOk()) return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
    return convert(rc);
}

Return<ErrorCode> Keymaster3::deleteAllKeys() {
    auto rc = km3_dev_->deleteAllKeys();
    if (!rc.isOk()) return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
    return convert(rc);
}

Return<ErrorCode> Keymaster3::destroyAttestationIds() {
    auto rc = km3_dev_->destroyAttestationIds();
    if (!rc.isOk()) return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
    return convert(rc);
}

Return<void> Keymaster3::begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
                               const hidl_vec<KeyParameter>& inParams,
                               const HardwareAuthToken& authToken, begin_cb _hidl_cb) {
    auto cb = [&](V3_0::ErrorCode error, const hidl_vec<V3_0::KeyParameter>& outParams,
                  OperationHandle operationHandle) {
        _hidl_cb(convert(error), convert(outParams), operationHandle);
    };

    auto rc =
        km3_dev_->begin(convert(purpose), key, convertAndAddAuthToken(inParams, authToken), cb);
    rc.isOk();  // move ctor prereq
    return rc;
}

Return<void> Keymaster3::update(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
                                const hidl_vec<uint8_t>& input, const HardwareAuthToken& authToken,
                                const VerificationToken& /* verificationToken */,
                                update_cb _hidl_cb) {
    auto cb = [&](V3_0::ErrorCode error, uint32_t inputConsumed,
                  const hidl_vec<V3_0::KeyParameter>& outParams, const hidl_vec<uint8_t>& output) {
        _hidl_cb(convert(error), inputConsumed, convert(outParams), output);
    };

    auto rc =
        km3_dev_->update(operationHandle, convertAndAddAuthToken(inParams, authToken), input, cb);
    rc.isOk();  // move ctor prereq
    return rc;
}

Return<void> Keymaster3::finish(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
                                const hidl_vec<uint8_t>& input, const hidl_vec<uint8_t>& signature,
                                const HardwareAuthToken& authToken,
                                const VerificationToken& /* verificationToken */,
                                finish_cb _hidl_cb) {
    auto cb = [&](V3_0::ErrorCode error, const hidl_vec<V3_0::KeyParameter>& outParams,
                  const hidl_vec<uint8_t>& output) {
        _hidl_cb(convert(error), convert(outParams), output);
    };

    auto rc = km3_dev_->finish(operationHandle, convertAndAddAuthToken(inParams, authToken), input,
                               signature, cb);
    rc.isOk();  // move ctor prereq
    return rc;
}

Return<ErrorCode> Keymaster3::abort(uint64_t operationHandle) {
    auto rc = km3_dev_->abort(operationHandle);
    if (!rc.isOk()) return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
    return convert(rc);
}

}  // namespace support
}  // namespace V4_0
}  // namespace keymaster
}  // namespace hardware
}  // namespace android
+48 −0
Original line number Diff line number Diff line
/*
**
** 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 <keymasterV4_0/Keymaster4.h>

#include <android-base/logging.h>

namespace android {
namespace hardware {
namespace keymaster {
namespace V4_0 {
namespace support {

void Keymaster4::getVersionIfNeeded() {
    if (haveVersion_) return;

    auto rc = dev_->getHardwareInfo([&](SecurityLevel securityLevel, auto...) {
        securityLevel_ = securityLevel;
        haveVersion_ = true;
    });

    CHECK(rc.isOk()) << "Got error " << rc.description() << " trying to get hardware info";
}

Keymaster::VersionResult Keymaster4::halVersion() {
    getVersionIfNeeded();
    return {ErrorCode::OK, halMajorVersion(), securityLevel_, true};
}

}  // namespace support
}  // namespace V4_0
}  // namespace keymaster
}  // namespace hardware
}  // namespace android
+58 −0
Original line number Diff line number Diff line
/*
 **
 ** 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.
 */

#ifndef HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_H_
#define HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_H_

#include <android/hardware/keymaster/4.0/IKeymasterDevice.h>

namespace android {
namespace hardware {
namespace keymaster {
namespace V4_0 {
namespace support {

/**
 * Keymaster abstracts the underlying V4_0::IKeymasterDevice.  There is one implementation
 * (Keymaster4) which is a trivial passthrough and one that wraps a V3_0::IKeymasterDevice.
 *
 * The reason for adding this additional layer, rather than simply using the latest HAL directly and
 * subclassing it to wrap any older HAL, is because this provides a place to put additional methods
 * which clients can use when they need to distinguish between different underlying HAL versions,
 * while still having to use only the latest interface.
 */
class Keymaster : public IKeymasterDevice {
   public:
    virtual ~Keymaster() {}

    struct VersionResult {
        ErrorCode error;
        uint8_t majorVersion;
        SecurityLevel securityLevel;
        bool supportsEc;
    };

    virtual VersionResult halVersion() = 0;
};

}  // namespace support
}  // namespace V4_0
}  // namespace keymaster
}  // namespace hardware
}  // namespace android

#endif  // HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_H_
+129 −0
Original line number Diff line number Diff line
/*
 **
 ** 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.
 */

#ifndef HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_3_H_
#define HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_3_H_

#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>

#include "Keymaster.h"

namespace android {
namespace hardware {
namespace keymaster {
namespace V4_0 {
namespace support {

using IKeymaster3Device = ::android::hardware::keymaster::V3_0::IKeymasterDevice;

using ::android::sp;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::details::return_status;

class Keymaster3 : public Keymaster {
   public:
    using WrappedIKeymasterDevice = IKeymaster3Device;
    Keymaster3(sp<IKeymaster3Device> km3_dev) : km3_dev_(km3_dev), haveVersion_(false) {}

    VersionResult halVersion() override;

    Return<void> getHardwareInfo(getHardwareInfo_cb _hidl_cb);

    Return<void> getHmacSharingParameters(getHmacSharingParameters_cb _hidl_cb) override {
        _hidl_cb(ErrorCode::UNIMPLEMENTED, {});
        return Void();
    }

    Return<void> computeSharedHmac(const hidl_vec<HmacSharingParameters>&,
                                   computeSharedHmac_cb _hidl_cb) override {
        _hidl_cb(ErrorCode::UNIMPLEMENTED, {});
        return Void();
    }

    Return<void> verifyAuthorization(uint64_t, const hidl_vec<KeyParameter>&,
                                     const HardwareAuthToken&,
                                     verifyAuthorization_cb _hidl_cb) override {
        _hidl_cb(ErrorCode::UNIMPLEMENTED, {});
        return Void();
    }

    Return<ErrorCode> addRngEntropy(const hidl_vec<uint8_t>& data) override;
    Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams,
                             generateKey_cb _hidl_cb) override;
    Return<void> getKeyCharacteristics(const hidl_vec<uint8_t>& keyBlob,
                                       const hidl_vec<uint8_t>& clientId,
                                       const hidl_vec<uint8_t>& appData,
                                       getKeyCharacteristics_cb _hidl_cb) override;
    Return<void> importKey(const hidl_vec<KeyParameter>& params, KeyFormat keyFormat,
                           const hidl_vec<uint8_t>& keyData, importKey_cb _hidl_cb) override;

    Return<void> importWrappedKey(const hidl_vec<uint8_t>&, const hidl_vec<uint8_t>&,
                                  const hidl_vec<uint8_t>&, importWrappedKey_cb _hidl_cb) {
        _hidl_cb(ErrorCode::UNIMPLEMENTED, {}, {});
        return Void();
    }

    Return<void> exportKey(KeyFormat exportFormat, const hidl_vec<uint8_t>& keyBlob,
                           const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData,
                           exportKey_cb _hidl_cb) override;
    Return<void> attestKey(const hidl_vec<uint8_t>& keyToAttest,
                           const hidl_vec<KeyParameter>& attestParams,
                           attestKey_cb _hidl_cb) override;
    Return<void> upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
                            const hidl_vec<KeyParameter>& upgradeParams,
                            upgradeKey_cb _hidl_cb) override;
    Return<ErrorCode> deleteKey(const hidl_vec<uint8_t>& keyBlob) override;
    Return<ErrorCode> deleteAllKeys() override;
    Return<ErrorCode> destroyAttestationIds() override;
    Return<void> begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
                       const hidl_vec<KeyParameter>& inParams, const HardwareAuthToken& authToken,
                       begin_cb _hidl_cb) override;
    Return<void> update(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
                        const hidl_vec<uint8_t>& input, const HardwareAuthToken& authToken,
                        const VerificationToken& verificationToken, update_cb _hidl_cb) override;
    Return<void> finish(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
                        const hidl_vec<uint8_t>& input, const hidl_vec<uint8_t>& signature,
                        const HardwareAuthToken& authToken,
                        const VerificationToken& verificationToken, finish_cb _hidl_cb) override;
    Return<ErrorCode> abort(uint64_t operationHandle) override;

   private:
    void getVersionIfNeeded();

    sp<IKeymaster3Device> km3_dev_;

    bool haveVersion_;
    uint8_t majorVersion_;
    SecurityLevel securityLevel_;
    bool supportsEllipticCurve_;
    bool supportsSymmetricCryptography_;
    bool supportsAttestation_;
    bool supportsAllDigests_;
    std::string keymasterName_;
    std::string authorName_;
};

}  // namespace support
}  // namespace V4_0
}  // namespace keymaster
}  // namespace hardware
}  // namespace android

#endif  // HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_3_H_
Loading