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

Commit d4ba314d authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Move Keymaster wrapper into support library."

parents df867155 7d339812
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