blob: 6dfe85bdfd17684f02d31614f20b265ac9926665 [file] [log] [blame]
Shawn Willden7d339812018-01-18 15:36:46 -07001/*
2 **
3 ** Copyright 2017, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18#include <keymasterV4_0/Keymaster3.h>
19
20#include <android-base/logging.h>
21#include <hardware/hw_auth_token.h>
22
23namespace android {
24namespace hardware {
25namespace keymaster {
26namespace V4_0 {
27namespace support {
28
29using android::hardware::details::StatusOf;
30
31namespace {
32
33ErrorCode convert(V3_0::ErrorCode error) {
34 return static_cast<ErrorCode>(error);
35}
36
37V3_0::KeyPurpose convert(KeyPurpose purpose) {
38 return static_cast<V3_0::KeyPurpose>(purpose);
39}
40
41V3_0::KeyFormat convert(KeyFormat purpose) {
42 return static_cast<V3_0::KeyFormat>(purpose);
43}
44
45V3_0::KeyParameter convert(const KeyParameter& param) {
46 V3_0::KeyParameter converted;
47 converted.tag = static_cast<V3_0::Tag>(param.tag);
48 static_assert(sizeof(converted.f) == sizeof(param.f), "This function assumes sizes match");
49 memcpy(&converted.f, &param.f, sizeof(param.f));
50 converted.blob = param.blob;
51 return converted;
52}
53
54KeyParameter convert(const V3_0::KeyParameter& param) {
55 KeyParameter converted;
56 converted.tag = static_cast<Tag>(param.tag);
57 static_assert(sizeof(converted.f) == sizeof(param.f), "This function assumes sizes match");
58 memcpy(&converted.f, &param.f, sizeof(param.f));
59 converted.blob = param.blob;
60 return converted;
61}
62
63hidl_vec<V3_0::KeyParameter> convert(const hidl_vec<KeyParameter>& params) {
64 hidl_vec<V3_0::KeyParameter> converted(params.size());
65 for (size_t i = 0; i < params.size(); ++i) {
66 converted[i] = convert(params[i]);
67 }
68 return converted;
69}
70
71hidl_vec<KeyParameter> convert(const hidl_vec<V3_0::KeyParameter>& params) {
72 hidl_vec<KeyParameter> converted(params.size());
73 for (size_t i = 0; i < params.size(); ++i) {
74 converted[i] = convert(params[i]);
75 }
76 return converted;
77}
78
79template <typename T, typename OutIter>
80inline static OutIter copy_bytes_to_iterator(const T& value, OutIter dest) {
81 const uint8_t* value_ptr = reinterpret_cast<const uint8_t*>(&value);
82 return std::copy(value_ptr, value_ptr + sizeof(value), dest);
83}
84
85constexpr size_t kHmacSize = 32;
86
87inline static hidl_vec<uint8_t> authToken2HidlVec(const HardwareAuthToken& token) {
88 static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) +
89 sizeof(token.authenticatorId) + sizeof(token.authenticatorType) +
90 sizeof(token.timestamp) + kHmacSize ==
91 sizeof(hw_auth_token_t),
92 "HardwareAuthToken content size does not match hw_auth_token_t size");
93
94 hidl_vec<uint8_t> result;
95 result.resize(sizeof(hw_auth_token_t));
96 auto pos = result.begin();
97 *pos++ = 0; // Version byte
98 pos = copy_bytes_to_iterator(token.challenge, pos);
99 pos = copy_bytes_to_iterator(token.userId, pos);
100 pos = copy_bytes_to_iterator(token.authenticatorId, pos);
101 auto auth_type = htonl(static_cast<uint32_t>(token.authenticatorType));
102 pos = copy_bytes_to_iterator(auth_type, pos);
103 auto timestamp = htonq(token.timestamp);
104 pos = copy_bytes_to_iterator(timestamp, pos);
105 if (token.mac.size() != kHmacSize) {
106 std::fill(pos, pos + kHmacSize, 0);
107 } else {
108 std::copy(token.mac.begin(), token.mac.end(), pos);
109 }
110
111 return result;
112}
113
114hidl_vec<V3_0::KeyParameter> convertAndAddAuthToken(const hidl_vec<KeyParameter>& params,
115 const HardwareAuthToken& authToken) {
116 hidl_vec<V3_0::KeyParameter> converted(params.size() + 1);
117 for (size_t i = 0; i < params.size(); ++i) {
118 converted[i] = convert(params[i]);
119 }
120 converted[params.size()].tag = V3_0::Tag::AUTH_TOKEN;
121 converted[params.size()].blob = authToken2HidlVec(authToken);
122
123 return converted;
124}
125
126KeyCharacteristics convert(const V3_0::KeyCharacteristics& chars) {
127 KeyCharacteristics converted;
128 converted.hardwareEnforced = convert(chars.teeEnforced);
129 converted.softwareEnforced = convert(chars.softwareEnforced);
130 return converted;
131}
132
133} // namespace
134
135void Keymaster3::getVersionIfNeeded() {
136 if (haveVersion_) return;
137
138 auto rc = km3_dev_->getHardwareFeatures(
139 [&](bool isSecure, bool supportsEllipticCurve, bool supportsSymmetricCryptography,
140 bool supportsAttestation, bool supportsAllDigests, const hidl_string& keymasterName,
141 const hidl_string& keymasterAuthorName) {
142 securityLevel_ =
143 isSecure ? SecurityLevel::TRUSTED_ENVIRONMENT : SecurityLevel::SOFTWARE;
144 supportsEllipticCurve_ = supportsEllipticCurve;
145 supportsSymmetricCryptography_ = supportsSymmetricCryptography;
146 supportsAttestation_ = supportsAttestation;
147 supportsAllDigests_ = supportsAllDigests;
148 keymasterName_ = keymasterName;
149 authorName_ = keymasterAuthorName;
150 });
151
152 CHECK(rc.isOk()) << "Got error " << rc.description() << " trying to get hardware features";
153
154 if (securityLevel_ == SecurityLevel::SOFTWARE) {
155 majorVersion_ = 3;
156 } else if (supportsAttestation_) {
157 majorVersion_ = 3; // Could be 2, doesn't matter.
158 } else if (supportsSymmetricCryptography_) {
159 majorVersion_ = 1;
160 } else {
161 majorVersion_ = 0;
162 }
163}
164
165Keymaster::VersionResult Keymaster3::halVersion() {
166 getVersionIfNeeded();
167 return {ErrorCode::OK, majorVersion_, securityLevel_, supportsEllipticCurve_};
168}
169
170Return<void> Keymaster3::getHardwareInfo(Keymaster3::getHardwareInfo_cb _hidl_cb) {
171 getVersionIfNeeded();
172 _hidl_cb(securityLevel_, keymasterName_ + " (wrapped by keystore::Keymaster3)", authorName_);
173 return Void();
174}
175
176Return<ErrorCode> Keymaster3::addRngEntropy(const hidl_vec<uint8_t>& data) {
177 auto rc = km3_dev_->addRngEntropy(data);
178 if (!rc.isOk()) {
179 return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
180 }
181 return convert(rc);
182}
183
184Return<void> Keymaster3::generateKey(const hidl_vec<KeyParameter>& keyParams,
185 generateKey_cb _hidl_cb) {
186 auto cb = [&](V3_0::ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
187 const V3_0::KeyCharacteristics& characteristics) {
188 _hidl_cb(convert(error), keyBlob, convert(characteristics));
189 };
190 auto rc = km3_dev_->generateKey(convert(keyParams), cb);
191 rc.isOk(); // move ctor prereq
192 return rc;
193}
194
195Return<void> Keymaster3::getKeyCharacteristics(const hidl_vec<uint8_t>& keyBlob,
196 const hidl_vec<uint8_t>& clientId,
197 const hidl_vec<uint8_t>& appData,
198 getKeyCharacteristics_cb _hidl_cb) {
199 auto cb = [&](V3_0::ErrorCode error, const V3_0::KeyCharacteristics& chars) {
200 _hidl_cb(convert(error), convert(chars));
201 };
202
203 auto rc = km3_dev_->getKeyCharacteristics(keyBlob, clientId, appData, cb);
204 rc.isOk(); // move ctor prereq
205 return rc;
206}
207
208Return<void> Keymaster3::importKey(const hidl_vec<KeyParameter>& params, KeyFormat keyFormat,
209 const hidl_vec<uint8_t>& keyData, importKey_cb _hidl_cb) {
210 auto cb = [&](V3_0::ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
211 const V3_0::KeyCharacteristics& chars) {
212 _hidl_cb(convert(error), keyBlob, convert(chars));
213 };
214 auto rc = km3_dev_->importKey(convert(params), convert(keyFormat), keyData, cb);
215 rc.isOk(); // move ctor prereq
216 return rc;
217}
218
219Return<void> Keymaster3::exportKey(KeyFormat exportFormat, const hidl_vec<uint8_t>& keyBlob,
220 const hidl_vec<uint8_t>& clientId,
221 const hidl_vec<uint8_t>& appData, exportKey_cb _hidl_cb) {
222 auto cb = [&](V3_0::ErrorCode error, const hidl_vec<uint8_t>& keyMaterial) {
223 _hidl_cb(convert(error), keyMaterial);
224 };
225 auto rc = km3_dev_->exportKey(convert(exportFormat), keyBlob, clientId, appData, cb);
226 rc.isOk(); // move ctor prereq
227 return rc;
228}
229
230Return<void> Keymaster3::attestKey(const hidl_vec<uint8_t>& keyToAttest,
231 const hidl_vec<KeyParameter>& attestParams,
232 attestKey_cb _hidl_cb) {
233 auto cb = [&](V3_0::ErrorCode error, const hidl_vec<hidl_vec<uint8_t>>& certChain) {
234 _hidl_cb(convert(error), certChain);
235 };
236 auto rc = km3_dev_->attestKey(keyToAttest, convert(attestParams), cb);
237 rc.isOk(); // move ctor prereq
238 return rc;
239}
240
241Return<void> Keymaster3::upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
242 const hidl_vec<KeyParameter>& upgradeParams,
243 upgradeKey_cb _hidl_cb) {
244 auto cb = [&](V3_0::ErrorCode error, const hidl_vec<uint8_t>& upgradedKeyBlob) {
245 _hidl_cb(convert(error), upgradedKeyBlob);
246 };
247 auto rc = km3_dev_->upgradeKey(keyBlobToUpgrade, convert(upgradeParams), cb);
248 rc.isOk(); // move ctor prereq
249 return rc;
250}
251
252Return<ErrorCode> Keymaster3::deleteKey(const hidl_vec<uint8_t>& keyBlob) {
253 auto rc = km3_dev_->deleteKey(keyBlob);
254 if (!rc.isOk()) return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
255 return convert(rc);
256}
257
258Return<ErrorCode> Keymaster3::deleteAllKeys() {
259 auto rc = km3_dev_->deleteAllKeys();
260 if (!rc.isOk()) return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
261 return convert(rc);
262}
263
264Return<ErrorCode> Keymaster3::destroyAttestationIds() {
265 auto rc = km3_dev_->destroyAttestationIds();
266 if (!rc.isOk()) return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
267 return convert(rc);
268}
269
270Return<void> Keymaster3::begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
271 const hidl_vec<KeyParameter>& inParams,
272 const HardwareAuthToken& authToken, begin_cb _hidl_cb) {
273 auto cb = [&](V3_0::ErrorCode error, const hidl_vec<V3_0::KeyParameter>& outParams,
274 OperationHandle operationHandle) {
275 _hidl_cb(convert(error), convert(outParams), operationHandle);
276 };
277
278 auto rc =
279 km3_dev_->begin(convert(purpose), key, convertAndAddAuthToken(inParams, authToken), cb);
280 rc.isOk(); // move ctor prereq
281 return rc;
282}
283
284Return<void> Keymaster3::update(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
285 const hidl_vec<uint8_t>& input, const HardwareAuthToken& authToken,
286 const VerificationToken& /* verificationToken */,
287 update_cb _hidl_cb) {
288 auto cb = [&](V3_0::ErrorCode error, uint32_t inputConsumed,
289 const hidl_vec<V3_0::KeyParameter>& outParams, const hidl_vec<uint8_t>& output) {
290 _hidl_cb(convert(error), inputConsumed, convert(outParams), output);
291 };
292
293 auto rc =
294 km3_dev_->update(operationHandle, convertAndAddAuthToken(inParams, authToken), input, cb);
295 rc.isOk(); // move ctor prereq
296 return rc;
297}
298
299Return<void> Keymaster3::finish(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
300 const hidl_vec<uint8_t>& input, const hidl_vec<uint8_t>& signature,
301 const HardwareAuthToken& authToken,
302 const VerificationToken& /* verificationToken */,
303 finish_cb _hidl_cb) {
304 auto cb = [&](V3_0::ErrorCode error, const hidl_vec<V3_0::KeyParameter>& outParams,
305 const hidl_vec<uint8_t>& output) {
306 _hidl_cb(convert(error), convert(outParams), output);
307 };
308
309 auto rc = km3_dev_->finish(operationHandle, convertAndAddAuthToken(inParams, authToken), input,
310 signature, cb);
311 rc.isOk(); // move ctor prereq
312 return rc;
313}
314
315Return<ErrorCode> Keymaster3::abort(uint64_t operationHandle) {
316 auto rc = km3_dev_->abort(operationHandle);
317 if (!rc.isOk()) return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
318 return convert(rc);
319}
320
321} // namespace support
322} // namespace V4_0
323} // namespace keymaster
324} // namespace hardware
325} // namespace android