11ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley/*
21ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley * Copyright (C) 2016 The Android Open Source Project
31ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley *
41ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley * Licensed under the Apache License, Version 2.0 (the "License");
51ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley * you may not use this file except in compliance with the License.
61ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley * You may obtain a copy of the License at
71ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley *
81ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley *      http://www.apache.org/licenses/LICENSE-2.0
91ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley *
101ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley * Unless required by applicable law or agreed to in writing, software
111ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley * distributed under the License is distributed on an "AS IS" BASIS,
121ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley * See the License for the specific language governing permissions and
141ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley * limitations under the License.
151ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley */
161ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley
171ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley#include "Keymaster.h"
181ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley
191ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley#include <android-base/logging.h>
208e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis#include <keystore/keymaster_tags.h>
218e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis#include <keystore/authorization_set.h>
228e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis#include <keystore/keystore_hidl_support.h>
238e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis
248e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskisusing namespace ::keystore;
2512e72ad9217280f29f5c33a53a241b9034ff3c65Shawn Willdenusing android::hardware::hidl_string;
261ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley
271ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowleynamespace android {
281ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowleynamespace vold {
291ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley
300323afd69d82ce900d520f4611f56e6c06fc08a1Paul CrowleyKeymasterOperation::~KeymasterOperation() {
318e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    if (mDevice.get()) mDevice->abort(mOpHandle);
320323afd69d82ce900d520f4611f56e6c06fc08a1Paul Crowley}
330323afd69d82ce900d520f4611f56e6c06fc08a1Paul Crowley
34e2e2d308df2da26838de32852318bc2cb690d052Pavel Grafovbool KeymasterOperation::updateCompletely(const char* input, size_t inputLen,
35e2e2d308df2da26838de32852318bc2cb690d052Pavel Grafov        const std::function<void(const char*, size_t)> consumer) {
36e2e2d308df2da26838de32852318bc2cb690d052Pavel Grafov    uint32_t inputConsumed = 0;
378e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis
388e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    ErrorCode km_error;
39e2e2d308df2da26838de32852318bc2cb690d052Pavel Grafov    auto hidlCB = [&] (ErrorCode ret, uint32_t inputConsumedDelta,
408e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis            const hidl_vec<KeyParameter>& /*ignored*/, const hidl_vec<uint8_t>& _output) {
418e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        km_error = ret;
428e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        if (km_error != ErrorCode::OK) return;
43e2e2d308df2da26838de32852318bc2cb690d052Pavel Grafov        inputConsumed += inputConsumedDelta;
44e2e2d308df2da26838de32852318bc2cb690d052Pavel Grafov        consumer(reinterpret_cast<const char*>(&_output[0]), _output.size());
458e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    };
468e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis
47e2e2d308df2da26838de32852318bc2cb690d052Pavel Grafov    while (inputConsumed != inputLen) {
48e2e2d308df2da26838de32852318bc2cb690d052Pavel Grafov        size_t toRead = static_cast<size_t>(inputLen - inputConsumed);
49e2e2d308df2da26838de32852318bc2cb690d052Pavel Grafov        auto inputBlob =
50e2e2d308df2da26838de32852318bc2cb690d052Pavel Grafov                blob2hidlVec(reinterpret_cast<const uint8_t*>(&input[inputConsumed]), toRead);
518e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        auto error = mDevice->update(mOpHandle, hidl_vec<KeyParameter>(), inputBlob, hidlCB);
528e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        if (!error.isOk()) {
538e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis            LOG(ERROR) << "update failed: " << error.description();
548e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis            mDevice = nullptr;
558e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis            return false;
568e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        }
578e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        if (km_error != ErrorCode::OK) {
58015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis            LOG(ERROR) << "update failed, code " << int32_t(km_error);
5913ffd8ef7a02a1b4b4d9a74f45d4a5bb6b814313Paul Crowley            mDevice = nullptr;
601ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley            return false;
611ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley        }
62e2e2d308df2da26838de32852318bc2cb690d052Pavel Grafov        if (inputConsumed > inputLen) {
631ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley            LOG(ERROR) << "update reported too much input consumed";
6413ffd8ef7a02a1b4b4d9a74f45d4a5bb6b814313Paul Crowley            mDevice = nullptr;
651ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley            return false;
661ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley        }
671ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley    }
681ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley    return true;
691ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley}
701ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley
71dff8c727c15cbe795e518e9116dfa271e67755b5Paul Crowleybool KeymasterOperation::finish(std::string* output) {
728e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    ErrorCode km_error;
738e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    auto hidlCb = [&] (ErrorCode ret, const hidl_vec<KeyParameter>& /*ignored*/,
748e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis            const hidl_vec<uint8_t>& _output) {
758e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        km_error = ret;
768e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        if (km_error != ErrorCode::OK) return;
778e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        if (output)
788e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis            output->assign(reinterpret_cast<const char*>(&_output[0]), _output.size());
798e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    };
808e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    auto error = mDevice->finish(mOpHandle, hidl_vec<KeyParameter>(), hidl_vec<uint8_t>(),
818e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis            hidl_vec<uint8_t>(), hidlCb);
8213ffd8ef7a02a1b4b4d9a74f45d4a5bb6b814313Paul Crowley    mDevice = nullptr;
838e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    if (!error.isOk()) {
848e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        LOG(ERROR) << "finish failed: " << error.description();
851ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley        return false;
861ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley    }
878e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    if (km_error != ErrorCode::OK) {
88015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        LOG(ERROR) << "finish failed, code " << int32_t(km_error);
898e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        return false;
90dff8c727c15cbe795e518e9116dfa271e67755b5Paul Crowley    }
911ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley    return true;
921ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley}
931ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley
941ef255816c50e462acc23383a9ff747c5f55c4ffPaul CrowleyKeymaster::Keymaster() {
959e8a577a6331a9b69157f7b229f48d7a611f986cChris Phoenix    mDevice = ::android::hardware::keymaster::V3_0::IKeymasterDevice::getService();
961ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley}
971ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley
988e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskisbool Keymaster::generateKey(const AuthorizationSet& inParams, std::string* key) {
998e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    ErrorCode km_error;
1008e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    auto hidlCb = [&] (ErrorCode ret, const hidl_vec<uint8_t>& keyBlob,
1018e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis            const KeyCharacteristics& /*ignored*/) {
1028e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        km_error = ret;
1038e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        if (km_error != ErrorCode::OK) return;
1048e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        if (key)
1058e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis            key->assign(reinterpret_cast<const char*>(&keyBlob[0]), keyBlob.size());
1068e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    };
1078e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis
1088e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    auto error = mDevice->generateKey(inParams.hidl_data(), hidlCb);
1098e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    if (!error.isOk()) {
1108e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        LOG(ERROR) << "generate_key failed: " << error.description();
1118e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        return false;
1128e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    }
1138e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    if (km_error != ErrorCode::OK) {
1148e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        LOG(ERROR) << "generate_key failed, code " << int32_t(km_error);
1151ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley        return false;
1161ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley    }
1171ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley    return true;
1181ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley}
1191ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley
120df528a7011b302c91579898c4a37361214ab05bbPaul Crowleybool Keymaster::deleteKey(const std::string& key) {
1218e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    auto keyBlob = blob2hidlVec(key);
1228e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    auto error = mDevice->deleteKey(keyBlob);
1238e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    if (!error.isOk()) {
1248e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        LOG(ERROR) << "delete_key failed: " << error.description();
1258e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        return false;
1268e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    }
1278e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    if (ErrorCode(error) != ErrorCode::OK) {
1288e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        LOG(ERROR) << "delete_key failed, code " << uint32_t(ErrorCode(error));
1291ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley        return false;
1301ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley    }
1311ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley    return true;
1321ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley}
1331ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley
134dff8c727c15cbe795e518e9116dfa271e67755b5Paul Crowleybool Keymaster::upgradeKey(const std::string& oldKey, const AuthorizationSet& inParams,
135dff8c727c15cbe795e518e9116dfa271e67755b5Paul Crowley                           std::string* newKey) {
1368e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    auto oldKeyBlob = blob2hidlVec(oldKey);
1378e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    ErrorCode km_error;
1388e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    auto hidlCb = [&] (ErrorCode ret, const hidl_vec<uint8_t>& upgradedKeyBlob) {
1398e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        km_error = ret;
1408e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        if (km_error != ErrorCode::OK) return;
1418e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        if (newKey)
1428e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis            newKey->assign(reinterpret_cast<const char*>(&upgradedKeyBlob[0]),
1438e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis                    upgradedKeyBlob.size());
1448e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    };
1458e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    auto error = mDevice->upgradeKey(oldKeyBlob, inParams.hidl_data(), hidlCb);
1468e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    if (!error.isOk()) {
1478e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        LOG(ERROR) << "upgrade_key failed: " << error.description();
1488e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        return false;
1498e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    }
1508e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    if (km_error != ErrorCode::OK) {
1518e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        LOG(ERROR) << "upgrade_key failed, code " << int32_t(km_error);
152dff8c727c15cbe795e518e9116dfa271e67755b5Paul Crowley        return false;
1531ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley    }
154dff8c727c15cbe795e518e9116dfa271e67755b5Paul Crowley    return true;
1551ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley}
1561ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley
1578e537b80028d11ac1f3810e959636028e77b2025Janis DanisevskisKeymasterOperation Keymaster::begin(KeyPurpose purpose, const std::string& key,
1588e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis                                    const AuthorizationSet& inParams,
1598e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis                                    AuthorizationSet* outParams) {
1608e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    auto keyBlob = blob2hidlVec(key);
1618e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    uint64_t mOpHandle;
1628e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    ErrorCode km_error;
1638e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis
1648e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    auto hidlCb = [&] (ErrorCode ret, const hidl_vec<KeyParameter>& _outParams,
1658e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis            uint64_t operationHandle) {
1668e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        km_error = ret;
1678e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        if (km_error != ErrorCode::OK) return;
1688e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        if (outParams)
1698e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis            *outParams = _outParams;
1708e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        mOpHandle = operationHandle;
1718e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    };
1728e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis
1738e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    auto error = mDevice->begin(purpose, keyBlob, inParams.hidl_data(), hidlCb);
1748e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    if (!error.isOk()) {
1758e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        LOG(ERROR) << "begin failed: " << error.description();
1768e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        return KeymasterOperation(ErrorCode::UNKNOWN_ERROR);
1778e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    }
1788e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis    if (km_error != ErrorCode::OK) {
179015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        LOG(ERROR) << "begin failed, code " << int32_t(km_error);
1808e537b80028d11ac1f3810e959636028e77b2025Janis Danisevskis        return KeymasterOperation(km_error);
1811ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley    }
18213ffd8ef7a02a1b4b4d9a74f45d4a5bb6b814313Paul Crowley    return KeymasterOperation(mDevice, mOpHandle);
1831ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley}
184015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskisbool Keymaster::isSecure() {
185015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    bool _isSecure = false;
186015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    auto rc = mDevice->getHardwareFeatures(
18712e72ad9217280f29f5c33a53a241b9034ff3c65Shawn Willden            [&] (bool isSecure, bool, bool, bool, bool, const hidl_string&, const hidl_string&) {
18812e72ad9217280f29f5c33a53a241b9034ff3c65Shawn Willden                _isSecure = isSecure; });
189015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    return rc.isOk() && _isSecure;
190015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis}
1911ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley
1921ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley}  // namespace vold
1931ef255816c50e462acc23383a9ff747c5f55c4ffPaul Crowley}  // namespace android
194015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis
195015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskisusing namespace ::android::vold;
196015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis
197015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskisint keymaster_compatibility_cryptfs_scrypt() {
198e7152c38df0f89bf4610be982542a6983b55032eJanis Danisevskis    Keymaster dev;
199e7152c38df0f89bf4610be982542a6983b55032eJanis Danisevskis    if (!dev) {
200e7152c38df0f89bf4610be982542a6983b55032eJanis Danisevskis        LOG(ERROR) << "Failed to initiate keymaster session";
201e7152c38df0f89bf4610be982542a6983b55032eJanis Danisevskis        return -1;
202e7152c38df0f89bf4610be982542a6983b55032eJanis Danisevskis    }
203e7152c38df0f89bf4610be982542a6983b55032eJanis Danisevskis    return dev.isSecure();
204015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis}
205015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis
206015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskisint keymaster_create_key_for_cryptfs_scrypt(uint32_t rsa_key_size,
207015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                                            uint64_t rsa_exponent,
208015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                                            uint32_t ratelimit,
209015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                                            uint8_t* key_buffer,
210015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                                            uint32_t key_buffer_size,
211015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                                            uint32_t* key_out_size)
212015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis{
213015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    Keymaster dev;
214015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    std::string key;
215015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    if (!dev) {
216015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        LOG(ERROR) << "Failed to initiate keymaster session";
217015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        return -1;
218015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    }
219015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    if (!key_buffer || !key_out_size) {
220015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        LOG(ERROR) << __FILE__ << ":" << __LINE__ << ":Invalid argument";
221015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        return -1;
222015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    }
223015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    if (key_out_size) {
224015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        *key_out_size = 0;
225015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    }
226015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis
227015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    auto paramBuilder = AuthorizationSetBuilder()
228015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                            .Authorization(TAG_ALGORITHM, Algorithm::RSA)
229015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                            .Authorization(TAG_KEY_SIZE, rsa_key_size)
230015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                            .Authorization(TAG_RSA_PUBLIC_EXPONENT, rsa_exponent)
231015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                            .Authorization(TAG_PURPOSE, KeyPurpose::SIGN)
232015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                            .Authorization(TAG_PADDING, PaddingMode::NONE)
233015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                            .Authorization(TAG_DIGEST, Digest::NONE)
234015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                            .Authorization(TAG_BLOB_USAGE_REQUIREMENTS,
235015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                                    KeyBlobUsageRequirements::STANDALONE)
236015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                            .Authorization(TAG_NO_AUTH_REQUIRED)
237015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                            .Authorization(TAG_MIN_SECONDS_BETWEEN_OPS, ratelimit);
238015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis
239015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    if (!dev.generateKey(paramBuilder, &key)) {
240015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        return -1;
241015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    }
242015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis
243015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    if (key_out_size) {
244015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        *key_out_size = key.size();
245015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    }
246015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis
247015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    if (key_buffer_size < key.size()) {
248015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        return -1;
249015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    }
250015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis
251015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    std::copy(key.data(), key.data() + key.size(), key_buffer);
252015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    return 0;
253015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis}
254015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis
255015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskisint keymaster_sign_object_for_cryptfs_scrypt(const uint8_t* key_blob,
256015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                                             size_t key_blob_size,
257015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                                             uint32_t ratelimit,
258015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                                             const uint8_t* object,
259015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                                             const size_t object_size,
260015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                                             uint8_t** signature_buffer,
261015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                                             size_t* signature_buffer_size)
262015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis{
263015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    Keymaster dev;
264015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    if (!dev) {
265015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        LOG(ERROR) << "Failed to initiate keymaster session";
266015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        return -1;
267015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    }
268015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    if (!key_blob || !object || !signature_buffer || !signature_buffer_size) {
269015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        LOG(ERROR) << __FILE__ << ":" << __LINE__ << ":Invalid argument";
270015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        return -1;
271015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    }
272015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis
273015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    AuthorizationSet outParams;
274015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    std::string key(reinterpret_cast<const char*>(key_blob), key_blob_size);
275015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    std::string input(reinterpret_cast<const char*>(object), object_size);
276015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    std::string output;
277015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    KeymasterOperation op;
278015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis
279015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    auto paramBuilder = AuthorizationSetBuilder()
280015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                            .Authorization(TAG_PADDING, PaddingMode::NONE)
281015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis                            .Authorization(TAG_DIGEST, Digest::NONE);
282015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis
283015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    while (true) {
284015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        op = dev.begin(KeyPurpose::SIGN, key, paramBuilder, &outParams);
2854375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang        if (op.errorCode() == ErrorCode::KEY_RATE_LIMIT_EXCEEDED) {
286015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis            sleep(ratelimit);
287015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis            continue;
288015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        } else break;
289015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    }
290015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis
2914375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang    if (op.errorCode() != ErrorCode::OK) {
2924375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang        LOG(ERROR) << "Error starting keymaster signature transaction: " << int32_t(op.errorCode());
293015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        return -1;
294015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    }
295015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis
296015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    if (!op.updateCompletely(input, &output)) {
297015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        LOG(ERROR) << "Error sending data to keymaster signature transaction: "
2984375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang                   << uint32_t(op.errorCode());
299015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        return -1;
300015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    }
301015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis
302015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    if (!op.finish(&output)) {
3034375f1be4ccdbf78ef4c5ab926d3316503a7b146Wei Wang        LOG(ERROR) << "Error finalizing keymaster signature transaction: " << int32_t(op.errorCode());
304015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        return -1;
305015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    }
306015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis
307015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    *signature_buffer = reinterpret_cast<uint8_t*>(malloc(output.size()));
308015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    if (*signature_buffer == nullptr) {
309015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        LOG(ERROR) << "Error allocation buffer for keymaster signature";
310015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis        return -1;
311015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    }
312015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    *signature_buffer_size = output.size();
313015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    std::copy(output.data(), output.data() + output.size(), *signature_buffer);
314015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis    return 0;
315015ec30b36713308db9f0051e8f97338419d7fbfJanis Danisevskis}
316