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 // TODO(154013771): this is copied from vold and modified to remove un-needed
18 // methods and use std::string instead of KeyBuffer. We should instead
19 // create a library to support both.
20 
21 #include "Keymaster.h"
22 
23 #include <android-base/logging.h>
24 #include <keymasterV4_1/authorization_set.h>
25 #include <keymasterV4_1/keymaster_utils.h>
26 
27 namespace android {
28 namespace kernel {
29 
30 using ::android::hardware::hidl_string;
31 using ::android::hardware::hidl_vec;
32 using ::android::hardware::keymaster::V4_0::SecurityLevel;
33 
Keymaster()34 Keymaster::Keymaster() {
35   auto devices = KmDevice::enumerateAvailableDevices();
36   for (auto& dev : devices) {
37     // Do not use StrongBox for device encryption / credential encryption.  If a
38     // security chip is present it will have Weaver, which already strengthens
39     // CE.  We get no additional benefit from using StrongBox here, so skip it.
40     if (dev->halVersion().securityLevel != SecurityLevel::STRONGBOX) {
41       mDevice = std::move(dev);
42       break;
43     }
44   }
45   if (!mDevice) return;
46   auto& version = mDevice->halVersion();
47   LOG(INFO) << "Using " << version.keymasterName << " from "
48             << version.authorName << " for encryption.  Security level: "
49             << toString(version.securityLevel)
50             << ", HAL: " << mDevice->descriptor() << "/"
51             << mDevice->instanceName();
52 }
53 
generateKey(const km::AuthorizationSet & inParams,std::string * key)54 bool Keymaster::generateKey(const km::AuthorizationSet& inParams,
55                             std::string* key) {
56   km::ErrorCode km_error;
57   auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<uint8_t>& keyBlob,
58                     const km::KeyCharacteristics& /*ignored*/) {
59     km_error = ret;
60     if (km_error != km::ErrorCode::OK) return;
61     if (key)
62       key->assign(reinterpret_cast<const char*>(&keyBlob[0]), keyBlob.size());
63   };
64 
65   auto error = mDevice->generateKey(inParams.hidl_data(), hidlCb);
66   if (!error.isOk()) {
67     LOG(ERROR) << "generate_key failed: " << error.description();
68     return false;
69   }
70   if (km_error != km::ErrorCode::OK) {
71     LOG(ERROR) << "generate_key failed, code " << int32_t(km_error);
72     return false;
73   }
74   return true;
75 }
76 
importKey(const km::AuthorizationSet & inParams,km::KeyFormat format,const std::string & key,std::string * outKeyBlob)77 bool Keymaster::importKey(const km::AuthorizationSet& inParams,
78                           km::KeyFormat format, const std::string& key,
79                           std::string* outKeyBlob) {
80   km::ErrorCode km_error;
81   auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<uint8_t>& keyBlob,
82                     const km::KeyCharacteristics& /*ignored*/) {
83     km_error = ret;
84     if (km_error != km::ErrorCode::OK) return;
85     if (outKeyBlob)
86       outKeyBlob->assign(reinterpret_cast<const char*>(&keyBlob[0]),
87                          keyBlob.size());
88   };
89   hidl_vec<uint8_t> hidlKey;
90   hidlKey.setToExternal(
91       const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(key.data())),
92       static_cast<size_t>(key.size()));
93 
94   auto error =
95       mDevice->importKey(inParams.hidl_data(), format, hidlKey, hidlCb);
96   if (!error.isOk()) {
97     LOG(ERROR) << "importKey failed: " << error.description();
98     return false;
99   }
100   if (km_error != km::ErrorCode::OK) {
101     LOG(ERROR) << "importKey failed, code " << int32_t(km_error);
102     return false;
103   }
104   return true;
105 }
106 
exportKey(const std::string & kmKey,std::string * key)107 bool Keymaster::exportKey(const std::string& kmKey, std::string* key) {
108   auto kmKeyBlob =
109       km::support::blob2hidlVec(std::string(kmKey.data(), kmKey.size()));
110   km::ErrorCode km_error;
111   auto hidlCb = [&](km::ErrorCode ret,
112                     const hidl_vec<uint8_t>& exportedKeyBlob) {
113     km_error = ret;
114     if (km_error != km::ErrorCode::OK) return;
115     if (key)
116       key->assign(reinterpret_cast<const char*>(&exportedKeyBlob[0]),
117                   exportedKeyBlob.size());
118   };
119   auto error =
120       mDevice->exportKey(km::KeyFormat::RAW, kmKeyBlob, {}, {}, hidlCb);
121   if (!error.isOk()) {
122     LOG(ERROR) << "export_key failed: " << error.description();
123     return false;
124   }
125   if (km_error != km::ErrorCode::OK) {
126     LOG(ERROR) << "export_key failed, code " << int32_t(km_error);
127     return false;
128   }
129   return true;
130 }
131 
deleteKey(const std::string & key)132 bool Keymaster::deleteKey(const std::string& key) {
133   auto keyBlob = km::support::blob2hidlVec(key);
134   auto error = mDevice->deleteKey(keyBlob);
135   if (!error.isOk()) {
136     LOG(ERROR) << "delete_key failed: " << error.description();
137     return false;
138   }
139   if (error != km::ErrorCode::OK) {
140     LOG(ERROR) << "delete_key failed, code " << int32_t(km::ErrorCode(error));
141     return false;
142   }
143   return true;
144 }
145 
upgradeKey(const std::string & oldKey,const km::AuthorizationSet & inParams,std::string * newKey)146 bool Keymaster::upgradeKey(const std::string& oldKey,
147                            const km::AuthorizationSet& inParams,
148                            std::string* newKey) {
149   auto oldKeyBlob = km::support::blob2hidlVec(oldKey);
150   km::ErrorCode km_error;
151   auto hidlCb = [&](km::ErrorCode ret,
152                     const hidl_vec<uint8_t>& upgradedKeyBlob) {
153     km_error = ret;
154     if (km_error != km::ErrorCode::OK) return;
155     if (newKey)
156       newKey->assign(reinterpret_cast<const char*>(&upgradedKeyBlob[0]),
157                      upgradedKeyBlob.size());
158   };
159   auto error = mDevice->upgradeKey(oldKeyBlob, inParams.hidl_data(), hidlCb);
160   if (!error.isOk()) {
161     LOG(ERROR) << "upgrade_key failed: " << error.description();
162     return false;
163   }
164   if (km_error != km::ErrorCode::OK) {
165     LOG(ERROR) << "upgrade_key failed, code " << int32_t(km_error);
166     return false;
167   }
168   return true;
169 }
170 
171 }  // namespace kernel
172 }  // namespace android
173