1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "Keymaster.h"
18
19#include <android-base/logging.h>
20#include <keystore/keymaster_tags.h>
21#include <keystore/authorization_set.h>
22#include <keystore/keystore_hidl_support.h>
23
24using namespace ::keystore;
25using android::hardware::hidl_string;
26
27namespace android {
28namespace vold {
29
30KeymasterOperation::~KeymasterOperation() {
31    if (mDevice.get()) mDevice->abort(mOpHandle);
32}
33
34bool KeymasterOperation::updateCompletely(const char* input, size_t inputLen,
35        const std::function<void(const char*, size_t)> consumer) {
36    uint32_t inputConsumed = 0;
37
38    ErrorCode km_error;
39    auto hidlCB = [&] (ErrorCode ret, uint32_t inputConsumedDelta,
40            const hidl_vec<KeyParameter>& /*ignored*/, const hidl_vec<uint8_t>& _output) {
41        km_error = ret;
42        if (km_error != ErrorCode::OK) return;
43        inputConsumed += inputConsumedDelta;
44        consumer(reinterpret_cast<const char*>(&_output[0]), _output.size());
45    };
46
47    while (inputConsumed != inputLen) {
48        size_t toRead = static_cast<size_t>(inputLen - inputConsumed);
49        auto inputBlob =
50                blob2hidlVec(reinterpret_cast<const uint8_t*>(&input[inputConsumed]), toRead);
51        auto error = mDevice->update(mOpHandle, hidl_vec<KeyParameter>(), inputBlob, hidlCB);
52        if (!error.isOk()) {
53            LOG(ERROR) << "update failed: " << error.description();
54            mDevice = nullptr;
55            return false;
56        }
57        if (km_error != ErrorCode::OK) {
58            LOG(ERROR) << "update failed, code " << int32_t(km_error);
59            mDevice = nullptr;
60            return false;
61        }
62        if (inputConsumed > inputLen) {
63            LOG(ERROR) << "update reported too much input consumed";
64            mDevice = nullptr;
65            return false;
66        }
67    }
68    return true;
69}
70
71bool KeymasterOperation::finish(std::string* output) {
72    ErrorCode km_error;
73    auto hidlCb = [&] (ErrorCode ret, const hidl_vec<KeyParameter>& /*ignored*/,
74            const hidl_vec<uint8_t>& _output) {
75        km_error = ret;
76        if (km_error != ErrorCode::OK) return;
77        if (output)
78            output->assign(reinterpret_cast<const char*>(&_output[0]), _output.size());
79    };
80    auto error = mDevice->finish(mOpHandle, hidl_vec<KeyParameter>(), hidl_vec<uint8_t>(),
81            hidl_vec<uint8_t>(), hidlCb);
82    mDevice = nullptr;
83    if (!error.isOk()) {
84        LOG(ERROR) << "finish failed: " << error.description();
85        return false;
86    }
87    if (km_error != ErrorCode::OK) {
88        LOG(ERROR) << "finish failed, code " << int32_t(km_error);
89        return false;
90    }
91    return true;
92}
93
94Keymaster::Keymaster() {
95    mDevice = ::android::hardware::keymaster::V3_0::IKeymasterDevice::getService();
96}
97
98bool Keymaster::generateKey(const AuthorizationSet& inParams, std::string* key) {
99    ErrorCode km_error;
100    auto hidlCb = [&] (ErrorCode ret, const hidl_vec<uint8_t>& keyBlob,
101            const KeyCharacteristics& /*ignored*/) {
102        km_error = ret;
103        if (km_error != ErrorCode::OK) return;
104        if (key)
105            key->assign(reinterpret_cast<const char*>(&keyBlob[0]), keyBlob.size());
106    };
107
108    auto error = mDevice->generateKey(inParams.hidl_data(), hidlCb);
109    if (!error.isOk()) {
110        LOG(ERROR) << "generate_key failed: " << error.description();
111        return false;
112    }
113    if (km_error != ErrorCode::OK) {
114        LOG(ERROR) << "generate_key failed, code " << int32_t(km_error);
115        return false;
116    }
117    return true;
118}
119
120bool Keymaster::deleteKey(const std::string& key) {
121    auto keyBlob = blob2hidlVec(key);
122    auto error = mDevice->deleteKey(keyBlob);
123    if (!error.isOk()) {
124        LOG(ERROR) << "delete_key failed: " << error.description();
125        return false;
126    }
127    if (ErrorCode(error) != ErrorCode::OK) {
128        LOG(ERROR) << "delete_key failed, code " << uint32_t(ErrorCode(error));
129        return false;
130    }
131    return true;
132}
133
134bool Keymaster::upgradeKey(const std::string& oldKey, const AuthorizationSet& inParams,
135                           std::string* newKey) {
136    auto oldKeyBlob = blob2hidlVec(oldKey);
137    ErrorCode km_error;
138    auto hidlCb = [&] (ErrorCode ret, const hidl_vec<uint8_t>& upgradedKeyBlob) {
139        km_error = ret;
140        if (km_error != ErrorCode::OK) return;
141        if (newKey)
142            newKey->assign(reinterpret_cast<const char*>(&upgradedKeyBlob[0]),
143                    upgradedKeyBlob.size());
144    };
145    auto error = mDevice->upgradeKey(oldKeyBlob, inParams.hidl_data(), hidlCb);
146    if (!error.isOk()) {
147        LOG(ERROR) << "upgrade_key failed: " << error.description();
148        return false;
149    }
150    if (km_error != ErrorCode::OK) {
151        LOG(ERROR) << "upgrade_key failed, code " << int32_t(km_error);
152        return false;
153    }
154    return true;
155}
156
157KeymasterOperation Keymaster::begin(KeyPurpose purpose, const std::string& key,
158                                    const AuthorizationSet& inParams,
159                                    AuthorizationSet* outParams) {
160    auto keyBlob = blob2hidlVec(key);
161    uint64_t mOpHandle;
162    ErrorCode km_error;
163
164    auto hidlCb = [&] (ErrorCode ret, const hidl_vec<KeyParameter>& _outParams,
165            uint64_t operationHandle) {
166        km_error = ret;
167        if (km_error != ErrorCode::OK) return;
168        if (outParams)
169            *outParams = _outParams;
170        mOpHandle = operationHandle;
171    };
172
173    auto error = mDevice->begin(purpose, keyBlob, inParams.hidl_data(), hidlCb);
174    if (!error.isOk()) {
175        LOG(ERROR) << "begin failed: " << error.description();
176        return KeymasterOperation(ErrorCode::UNKNOWN_ERROR);
177    }
178    if (km_error != ErrorCode::OK) {
179        LOG(ERROR) << "begin failed, code " << int32_t(km_error);
180        return KeymasterOperation(km_error);
181    }
182    return KeymasterOperation(mDevice, mOpHandle);
183}
184bool Keymaster::isSecure() {
185    bool _isSecure = false;
186    auto rc = mDevice->getHardwareFeatures(
187            [&] (bool isSecure, bool, bool, bool, bool, const hidl_string&, const hidl_string&) {
188                _isSecure = isSecure; });
189    return rc.isOk() && _isSecure;
190}
191
192}  // namespace vold
193}  // namespace android
194
195using namespace ::android::vold;
196
197int keymaster_compatibility_cryptfs_scrypt() {
198    Keymaster dev;
199    if (!dev) {
200        LOG(ERROR) << "Failed to initiate keymaster session";
201        return -1;
202    }
203    return dev.isSecure();
204}
205
206int keymaster_create_key_for_cryptfs_scrypt(uint32_t rsa_key_size,
207                                            uint64_t rsa_exponent,
208                                            uint32_t ratelimit,
209                                            uint8_t* key_buffer,
210                                            uint32_t key_buffer_size,
211                                            uint32_t* key_out_size)
212{
213    Keymaster dev;
214    std::string key;
215    if (!dev) {
216        LOG(ERROR) << "Failed to initiate keymaster session";
217        return -1;
218    }
219    if (!key_buffer || !key_out_size) {
220        LOG(ERROR) << __FILE__ << ":" << __LINE__ << ":Invalid argument";
221        return -1;
222    }
223    if (key_out_size) {
224        *key_out_size = 0;
225    }
226
227    auto paramBuilder = AuthorizationSetBuilder()
228                            .Authorization(TAG_ALGORITHM, Algorithm::RSA)
229                            .Authorization(TAG_KEY_SIZE, rsa_key_size)
230                            .Authorization(TAG_RSA_PUBLIC_EXPONENT, rsa_exponent)
231                            .Authorization(TAG_PURPOSE, KeyPurpose::SIGN)
232                            .Authorization(TAG_PADDING, PaddingMode::NONE)
233                            .Authorization(TAG_DIGEST, Digest::NONE)
234                            .Authorization(TAG_BLOB_USAGE_REQUIREMENTS,
235                                    KeyBlobUsageRequirements::STANDALONE)
236                            .Authorization(TAG_NO_AUTH_REQUIRED)
237                            .Authorization(TAG_MIN_SECONDS_BETWEEN_OPS, ratelimit);
238
239    if (!dev.generateKey(paramBuilder, &key)) {
240        return -1;
241    }
242
243    if (key_out_size) {
244        *key_out_size = key.size();
245    }
246
247    if (key_buffer_size < key.size()) {
248        return -1;
249    }
250
251    std::copy(key.data(), key.data() + key.size(), key_buffer);
252    return 0;
253}
254
255int keymaster_sign_object_for_cryptfs_scrypt(const uint8_t* key_blob,
256                                             size_t key_blob_size,
257                                             uint32_t ratelimit,
258                                             const uint8_t* object,
259                                             const size_t object_size,
260                                             uint8_t** signature_buffer,
261                                             size_t* signature_buffer_size)
262{
263    Keymaster dev;
264    if (!dev) {
265        LOG(ERROR) << "Failed to initiate keymaster session";
266        return -1;
267    }
268    if (!key_blob || !object || !signature_buffer || !signature_buffer_size) {
269        LOG(ERROR) << __FILE__ << ":" << __LINE__ << ":Invalid argument";
270        return -1;
271    }
272
273    AuthorizationSet outParams;
274    std::string key(reinterpret_cast<const char*>(key_blob), key_blob_size);
275    std::string input(reinterpret_cast<const char*>(object), object_size);
276    std::string output;
277    KeymasterOperation op;
278
279    auto paramBuilder = AuthorizationSetBuilder()
280                            .Authorization(TAG_PADDING, PaddingMode::NONE)
281                            .Authorization(TAG_DIGEST, Digest::NONE);
282
283    while (true) {
284        op = dev.begin(KeyPurpose::SIGN, key, paramBuilder, &outParams);
285        if (op.errorCode() == ErrorCode::KEY_RATE_LIMIT_EXCEEDED) {
286            sleep(ratelimit);
287            continue;
288        } else break;
289    }
290
291    if (op.errorCode() != ErrorCode::OK) {
292        LOG(ERROR) << "Error starting keymaster signature transaction: " << int32_t(op.errorCode());
293        return -1;
294    }
295
296    if (!op.updateCompletely(input, &output)) {
297        LOG(ERROR) << "Error sending data to keymaster signature transaction: "
298                   << uint32_t(op.errorCode());
299        return -1;
300    }
301
302    if (!op.finish(&output)) {
303        LOG(ERROR) << "Error finalizing keymaster signature transaction: " << int32_t(op.errorCode());
304        return -1;
305    }
306
307    *signature_buffer = reinterpret_cast<uint8_t*>(malloc(output.size()));
308    if (*signature_buffer == nullptr) {
309        LOG(ERROR) << "Error allocation buffer for keymaster signature";
310        return -1;
311    }
312    *signature_buffer_size = output.size();
313    std::copy(output.data(), output.data() + output.size(), *signature_buffer);
314    return 0;
315}
316