1 /*
2 **
3 ** Copyright 2018, 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 #define LOG_TAG "android.hardware.keymaster@3.0-impl.trusty"
19
20 #include <cutils/log.h>
21 #include <keymaster/android_keymaster_messages.h>
22 #include <keymaster/authorization_set.h>
23 #include <keymaster_tags.h>
24 #include <trusty_keymaster/TrustyKeymaster3Device.h>
25 #include <trusty_keymaster/ipc/trusty_keymaster_ipc.h>
26
27 using ::keymaster::AbortOperationRequest;
28 using ::keymaster::AbortOperationResponse;
29 using ::keymaster::AddEntropyRequest;
30 using ::keymaster::AddEntropyResponse;
31 using ::keymaster::AttestKeyRequest;
32 using ::keymaster::AttestKeyResponse;
33 using ::keymaster::AuthorizationSet;
34 using ::keymaster::BeginOperationRequest;
35 using ::keymaster::BeginOperationResponse;
36 using ::keymaster::ExportKeyRequest;
37 using ::keymaster::ExportKeyResponse;
38 using ::keymaster::FinishOperationRequest;
39 using ::keymaster::FinishOperationResponse;
40 using ::keymaster::GenerateKeyRequest;
41 using ::keymaster::GenerateKeyResponse;
42 using ::keymaster::GetKeyCharacteristicsRequest;
43 using ::keymaster::GetKeyCharacteristicsResponse;
44 using ::keymaster::ImportKeyRequest;
45 using ::keymaster::ImportKeyResponse;
46 using ::keymaster::UpdateOperationRequest;
47 using ::keymaster::UpdateOperationResponse;
48 using ::keymaster::ng::Tag;
49
50 namespace keymaster {
51
52 namespace {
53
legacy_enum_conversion(const Tag value)54 inline keymaster_tag_t legacy_enum_conversion(const Tag value) {
55 return keymaster_tag_t(value);
56 }
legacy_enum_conversion(const keymaster_tag_t value)57 inline Tag legacy_enum_conversion(const keymaster_tag_t value) {
58 return Tag(value);
59 }
legacy_enum_conversion(const KeyPurpose value)60 inline keymaster_purpose_t legacy_enum_conversion(const KeyPurpose value) {
61 return keymaster_purpose_t(value);
62 }
legacy_enum_conversion(const KeyFormat value)63 inline keymaster_key_format_t legacy_enum_conversion(const KeyFormat value) {
64 return keymaster_key_format_t(value);
65 }
legacy_enum_conversion(const keymaster_error_t value)66 inline ErrorCode legacy_enum_conversion(const keymaster_error_t value) {
67 return ErrorCode(value);
68 }
69
typeFromTag(const keymaster_tag_t tag)70 inline keymaster_tag_type_t typeFromTag(const keymaster_tag_t tag) {
71 return keymaster_tag_get_type(tag);
72 }
73
74 class KmParamSet : public keymaster_key_param_set_t {
75 public:
KmParamSet(const hidl_vec<KeyParameter> & keyParams)76 KmParamSet(const hidl_vec<KeyParameter>& keyParams) {
77 params = new keymaster_key_param_t[keyParams.size()];
78 length = keyParams.size();
79 for (size_t i = 0; i < keyParams.size(); ++i) {
80 auto tag = legacy_enum_conversion(keyParams[i].tag);
81 switch (typeFromTag(tag)) {
82 case KM_ENUM:
83 case KM_ENUM_REP:
84 params[i] = keymaster_param_enum(tag, keyParams[i].f.integer);
85 break;
86 case KM_UINT:
87 case KM_UINT_REP:
88 params[i] = keymaster_param_int(tag, keyParams[i].f.integer);
89 break;
90 case KM_ULONG:
91 case KM_ULONG_REP:
92 params[i] = keymaster_param_long(tag, keyParams[i].f.longInteger);
93 break;
94 case KM_DATE:
95 params[i] = keymaster_param_date(tag, keyParams[i].f.dateTime);
96 break;
97 case KM_BOOL:
98 if (keyParams[i].f.boolValue)
99 params[i] = keymaster_param_bool(tag);
100 else
101 params[i].tag = KM_TAG_INVALID;
102 break;
103 case KM_BIGNUM:
104 case KM_BYTES:
105 params[i] = keymaster_param_blob(tag, &keyParams[i].blob[0],
106 keyParams[i].blob.size());
107 break;
108 case KM_INVALID:
109 default:
110 params[i].tag = KM_TAG_INVALID;
111 /* just skip */
112 break;
113 }
114 }
115 }
KmParamSet(KmParamSet && other)116 KmParamSet(KmParamSet&& other) noexcept
117 : keymaster_key_param_set_t{other.params, other.length} {
118 other.length = 0;
119 other.params = nullptr;
120 }
121 KmParamSet(const KmParamSet&) = delete;
~KmParamSet()122 ~KmParamSet() { delete[] params; }
123 };
124
kmBlob2hidlVec(const keymaster_key_blob_t & blob)125 inline hidl_vec<uint8_t> kmBlob2hidlVec(const keymaster_key_blob_t& blob) {
126 hidl_vec<uint8_t> result;
127 result.setToExternal(const_cast<unsigned char*>(blob.key_material), blob.key_material_size);
128 return result;
129 }
130
kmBlob2hidlVec(const keymaster_blob_t & blob)131 inline hidl_vec<uint8_t> kmBlob2hidlVec(const keymaster_blob_t& blob) {
132 hidl_vec<uint8_t> result;
133 result.setToExternal(const_cast<unsigned char*>(blob.data), blob.data_length);
134 return result;
135 }
136
kmBuffer2hidlVec(const::keymaster::Buffer & buf)137 inline hidl_vec<uint8_t> kmBuffer2hidlVec(const ::keymaster::Buffer& buf) {
138 hidl_vec<uint8_t> result;
139 result.setToExternal(const_cast<unsigned char*>(buf.peek_read()), buf.available_read());
140 return result;
141 }
142
kmCertChain2Hidl(const keymaster_cert_chain_t & cert_chain)143 inline static hidl_vec<hidl_vec<uint8_t>> kmCertChain2Hidl(
144 const keymaster_cert_chain_t& cert_chain) {
145 hidl_vec<hidl_vec<uint8_t>> result;
146 if (!cert_chain.entry_count || !cert_chain.entries) return result;
147
148 result.resize(cert_chain.entry_count);
149 for (size_t i = 0; i < cert_chain.entry_count; ++i) {
150 result[i] = kmBlob2hidlVec(cert_chain.entries[i]);
151 }
152
153 return result;
154 }
155
kmParamSet2Hidl(const keymaster_key_param_set_t & set)156 static inline hidl_vec<KeyParameter> kmParamSet2Hidl(const keymaster_key_param_set_t& set) {
157 hidl_vec<KeyParameter> result;
158 if (set.length == 0 || set.params == nullptr) return result;
159
160 result.resize(set.length);
161 keymaster_key_param_t* params = set.params;
162 for (size_t i = 0; i < set.length; ++i) {
163 auto tag = params[i].tag;
164 result[i].tag = legacy_enum_conversion(tag);
165 switch (typeFromTag(tag)) {
166 case KM_ENUM:
167 case KM_ENUM_REP:
168 result[i].f.integer = params[i].enumerated;
169 break;
170 case KM_UINT:
171 case KM_UINT_REP:
172 result[i].f.integer = params[i].integer;
173 break;
174 case KM_ULONG:
175 case KM_ULONG_REP:
176 result[i].f.longInteger = params[i].long_integer;
177 break;
178 case KM_DATE:
179 result[i].f.dateTime = params[i].date_time;
180 break;
181 case KM_BOOL:
182 result[i].f.boolValue = params[i].boolean;
183 break;
184 case KM_BIGNUM:
185 case KM_BYTES:
186 result[i].blob.setToExternal(const_cast<unsigned char*>(params[i].blob.data),
187 params[i].blob.data_length);
188 break;
189 case KM_INVALID:
190 default:
191 params[i].tag = KM_TAG_INVALID;
192 /* just skip */
193 break;
194 }
195 }
196 return result;
197 }
198
addClientAndAppData(const hidl_vec<uint8_t> & clientId,const hidl_vec<uint8_t> & appData,::keymaster::AuthorizationSet * params)199 void addClientAndAppData(const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData,
200 ::keymaster::AuthorizationSet* params) {
201 params->Clear();
202 if (clientId.size()) {
203 params->push_back(::keymaster::TAG_APPLICATION_ID, clientId.data(), clientId.size());
204 }
205 if (appData.size()) {
206 params->push_back(::keymaster::TAG_APPLICATION_DATA, appData.data(), appData.size());
207 }
208 }
209
210 } // anonymous namespace
211
TrustyKeymaster3Device(TrustyKeymaster * impl)212 TrustyKeymaster3Device::TrustyKeymaster3Device(TrustyKeymaster* impl) : impl_(impl) {}
213
~TrustyKeymaster3Device()214 TrustyKeymaster3Device::~TrustyKeymaster3Device() {}
215
getHardwareFeatures(getHardwareFeatures_cb _hidl_cb)216 Return<void> TrustyKeymaster3Device::getHardwareFeatures(getHardwareFeatures_cb _hidl_cb) {
217 _hidl_cb(true /* is_secure */, true /* supports_ec */,
218 true /* supports_symmetric_cryptography */, true /* supports_attestation */,
219 true /* supportsAllDigests */, "TrustyKeymaster", "Google");
220 return Void();
221 }
222
addRngEntropy(const hidl_vec<uint8_t> & data)223 Return<ErrorCode> TrustyKeymaster3Device::addRngEntropy(const hidl_vec<uint8_t>& data) {
224 if (data.size() == 0) return ErrorCode::OK;
225 AddEntropyRequest request(impl_->message_version());
226 request.random_data.Reinitialize(data.data(), data.size());
227
228 AddEntropyResponse response(impl_->message_version());
229 impl_->AddRngEntropy(request, &response);
230
231 return legacy_enum_conversion(response.error);
232 }
233
generateKey(const hidl_vec<KeyParameter> & keyParams,generateKey_cb _hidl_cb)234 Return<void> TrustyKeymaster3Device::generateKey(const hidl_vec<KeyParameter>& keyParams,
235 generateKey_cb _hidl_cb) {
236 GenerateKeyRequest request(impl_->message_version());
237 request.key_description.Reinitialize(KmParamSet(keyParams));
238
239 GenerateKeyResponse response(impl_->message_version());
240 impl_->GenerateKey(request, &response);
241
242 KeyCharacteristics resultCharacteristics;
243 hidl_vec<uint8_t> resultKeyBlob;
244 if (response.error == KM_ERROR_OK) {
245 resultKeyBlob = kmBlob2hidlVec(response.key_blob);
246 resultCharacteristics.teeEnforced = kmParamSet2Hidl(response.enforced);
247 resultCharacteristics.softwareEnforced = kmParamSet2Hidl(response.unenforced);
248 }
249 _hidl_cb(legacy_enum_conversion(response.error), resultKeyBlob, resultCharacteristics);
250 return Void();
251 }
252
getKeyCharacteristics(const hidl_vec<uint8_t> & keyBlob,const hidl_vec<uint8_t> & clientId,const hidl_vec<uint8_t> & appData,getKeyCharacteristics_cb _hidl_cb)253 Return<void> TrustyKeymaster3Device::getKeyCharacteristics(const hidl_vec<uint8_t>& keyBlob,
254 const hidl_vec<uint8_t>& clientId,
255 const hidl_vec<uint8_t>& appData,
256 getKeyCharacteristics_cb _hidl_cb) {
257 GetKeyCharacteristicsRequest request(impl_->message_version());
258 request.SetKeyMaterial(keyBlob.data(), keyBlob.size());
259 addClientAndAppData(clientId, appData, &request.additional_params);
260
261 GetKeyCharacteristicsResponse response(impl_->message_version());
262 impl_->GetKeyCharacteristics(request, &response);
263
264 KeyCharacteristics resultCharacteristics;
265 if (response.error == KM_ERROR_OK) {
266 resultCharacteristics.teeEnforced = kmParamSet2Hidl(response.enforced);
267 resultCharacteristics.softwareEnforced = kmParamSet2Hidl(response.unenforced);
268 }
269 _hidl_cb(legacy_enum_conversion(response.error), resultCharacteristics);
270 return Void();
271 }
272
importKey(const hidl_vec<KeyParameter> & params,KeyFormat keyFormat,const hidl_vec<uint8_t> & keyData,importKey_cb _hidl_cb)273 Return<void> TrustyKeymaster3Device::importKey(const hidl_vec<KeyParameter>& params,
274 KeyFormat keyFormat,
275 const hidl_vec<uint8_t>& keyData,
276 importKey_cb _hidl_cb) {
277 ImportKeyRequest request(impl_->message_version());
278 request.key_description.Reinitialize(KmParamSet(params));
279 request.key_format = legacy_enum_conversion(keyFormat);
280 request.key_data = KeymasterKeyBlob(keyData.data(), keyData.size());
281
282 ImportKeyResponse response(impl_->message_version());
283 impl_->ImportKey(request, &response);
284
285 KeyCharacteristics resultCharacteristics;
286 hidl_vec<uint8_t> resultKeyBlob;
287 if (response.error == KM_ERROR_OK) {
288 resultKeyBlob = kmBlob2hidlVec(response.key_blob);
289 resultCharacteristics.teeEnforced = kmParamSet2Hidl(response.enforced);
290 resultCharacteristics.softwareEnforced = kmParamSet2Hidl(response.unenforced);
291 }
292 _hidl_cb(legacy_enum_conversion(response.error), resultKeyBlob, resultCharacteristics);
293 return Void();
294 }
295
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)296 Return<void> TrustyKeymaster3Device::exportKey(KeyFormat exportFormat,
297 const hidl_vec<uint8_t>& keyBlob,
298 const hidl_vec<uint8_t>& clientId,
299 const hidl_vec<uint8_t>& appData,
300 exportKey_cb _hidl_cb) {
301 ExportKeyRequest request(impl_->message_version());
302 request.key_format = legacy_enum_conversion(exportFormat);
303 request.SetKeyMaterial(keyBlob.data(), keyBlob.size());
304 addClientAndAppData(clientId, appData, &request.additional_params);
305
306 ExportKeyResponse response(impl_->message_version());
307 impl_->ExportKey(request, &response);
308
309 hidl_vec<uint8_t> resultKeyBlob;
310 if (response.error == KM_ERROR_OK) {
311 resultKeyBlob.setToExternal(response.key_data, response.key_data_length);
312 }
313 _hidl_cb(legacy_enum_conversion(response.error), resultKeyBlob);
314 return Void();
315 }
316
attestKey(const hidl_vec<uint8_t> & keyToAttest,const hidl_vec<KeyParameter> & attestParams,attestKey_cb _hidl_cb)317 Return<void> TrustyKeymaster3Device::attestKey(const hidl_vec<uint8_t>& keyToAttest,
318 const hidl_vec<KeyParameter>& attestParams,
319 attestKey_cb _hidl_cb) {
320 AttestKeyRequest request(impl_->message_version());
321 request.SetKeyMaterial(keyToAttest.data(), keyToAttest.size());
322 request.attest_params.Reinitialize(KmParamSet(attestParams));
323
324 AttestKeyResponse response(impl_->message_version());
325 impl_->AttestKey(request, &response);
326
327 hidl_vec<hidl_vec<uint8_t>> resultCertChain;
328 if (response.error == KM_ERROR_OK) {
329 resultCertChain = kmCertChain2Hidl(response.certificate_chain);
330 }
331 _hidl_cb(legacy_enum_conversion(response.error), resultCertChain);
332 return Void();
333 }
334
upgradeKey(const hidl_vec<uint8_t> & keyBlobToUpgrade,const hidl_vec<KeyParameter> & upgradeParams,upgradeKey_cb _hidl_cb)335 Return<void> TrustyKeymaster3Device::upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
336 const hidl_vec<KeyParameter>& upgradeParams,
337 upgradeKey_cb _hidl_cb) {
338 UpgradeKeyRequest request(impl_->message_version());
339 request.SetKeyMaterial(keyBlobToUpgrade.data(), keyBlobToUpgrade.size());
340 request.upgrade_params.Reinitialize(KmParamSet(upgradeParams));
341
342 UpgradeKeyResponse response(impl_->message_version());
343 impl_->UpgradeKey(request, &response);
344
345 if (response.error == KM_ERROR_OK) {
346 _hidl_cb(ErrorCode::OK, kmBlob2hidlVec(response.upgraded_key));
347 } else {
348 _hidl_cb(legacy_enum_conversion(response.error), hidl_vec<uint8_t>());
349 }
350 return Void();
351 }
352
deleteKey(const hidl_vec<uint8_t> & keyBlob)353 Return<ErrorCode> TrustyKeymaster3Device::deleteKey(const hidl_vec<uint8_t>& keyBlob) {
354 DeleteKeyRequest request(impl_->message_version());
355 request.SetKeyMaterial(keyBlob.data(), keyBlob.size());
356
357 DeleteKeyResponse response(impl_->message_version());
358 impl_->DeleteKey(request, &response);
359
360 return legacy_enum_conversion(response.error);
361 }
362
deleteAllKeys()363 Return<ErrorCode> TrustyKeymaster3Device::deleteAllKeys() {
364 DeleteAllKeysRequest request(impl_->message_version());
365 DeleteAllKeysResponse response(impl_->message_version());
366 impl_->DeleteAllKeys(request, &response);
367
368 return legacy_enum_conversion(response.error);
369 }
370
destroyAttestationIds()371 Return<ErrorCode> TrustyKeymaster3Device::destroyAttestationIds() {
372 return ErrorCode::UNIMPLEMENTED;
373 }
374
begin(KeyPurpose purpose,const hidl_vec<uint8_t> & key,const hidl_vec<KeyParameter> & inParams,begin_cb _hidl_cb)375 Return<void> TrustyKeymaster3Device::begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
376 const hidl_vec<KeyParameter>& inParams,
377 begin_cb _hidl_cb) {
378 BeginOperationRequest request(impl_->message_version());
379 request.purpose = legacy_enum_conversion(purpose);
380 request.SetKeyMaterial(key.data(), key.size());
381 request.additional_params.Reinitialize(KmParamSet(inParams));
382
383 BeginOperationResponse response(impl_->message_version());
384 impl_->BeginOperation(request, &response);
385
386 hidl_vec<KeyParameter> resultParams(impl_->message_version());
387 if (response.error == KM_ERROR_OK) {
388 resultParams = kmParamSet2Hidl(response.output_params);
389 }
390
391 _hidl_cb(legacy_enum_conversion(response.error), resultParams, response.op_handle);
392 return Void();
393 }
394
update(uint64_t operationHandle,const hidl_vec<KeyParameter> & inParams,const hidl_vec<uint8_t> & input,update_cb _hidl_cb)395 Return<void> TrustyKeymaster3Device::update(uint64_t operationHandle,
396 const hidl_vec<KeyParameter>& inParams,
397 const hidl_vec<uint8_t>& input, update_cb _hidl_cb) {
398 UpdateOperationRequest request(impl_->message_version());
399 UpdateOperationResponse response(impl_->message_version());
400 hidl_vec<KeyParameter> resultParams;
401 hidl_vec<uint8_t> resultBlob;
402 uint32_t resultConsumed = 0;
403
404 request.op_handle = operationHandle;
405 request.additional_params.Reinitialize(KmParamSet(inParams));
406
407 size_t inp_size = input.size();
408 size_t ser_size = request.SerializedSize();
409
410 if (ser_size > TRUSTY_KEYMASTER_SEND_BUF_SIZE) {
411 response.error = KM_ERROR_INVALID_INPUT_LENGTH;
412 } else {
413 if (ser_size + inp_size > TRUSTY_KEYMASTER_SEND_BUF_SIZE) {
414 inp_size = TRUSTY_KEYMASTER_SEND_BUF_SIZE - ser_size;
415 }
416 request.input.Reinitialize(input.data(), inp_size);
417
418 impl_->UpdateOperation(request, &response);
419
420 if (response.error == KM_ERROR_OK) {
421 resultConsumed = response.input_consumed;
422 resultParams = kmParamSet2Hidl(response.output_params);
423 resultBlob = kmBuffer2hidlVec(response.output);
424 }
425 }
426 _hidl_cb(legacy_enum_conversion(response.error), resultConsumed, resultParams, resultBlob);
427 return Void();
428 }
429
finish(uint64_t operationHandle,const hidl_vec<KeyParameter> & inParams,const hidl_vec<uint8_t> & input,const hidl_vec<uint8_t> & signature,finish_cb _hidl_cb)430 Return<void> TrustyKeymaster3Device::finish(uint64_t operationHandle,
431 const hidl_vec<KeyParameter>& inParams,
432 const hidl_vec<uint8_t>& input,
433 const hidl_vec<uint8_t>& signature,
434 finish_cb _hidl_cb) {
435 FinishOperationRequest request(impl_->message_version());
436 request.op_handle = operationHandle;
437 request.input.Reinitialize(input.data(), input.size());
438 request.signature.Reinitialize(signature.data(), signature.size());
439 request.additional_params.Reinitialize(KmParamSet(inParams));
440
441 FinishOperationResponse response(impl_->message_version());
442 impl_->FinishOperation(request, &response);
443
444 hidl_vec<KeyParameter> resultParams;
445 hidl_vec<uint8_t> resultBlob;
446 if (response.error == KM_ERROR_OK) {
447 resultParams = kmParamSet2Hidl(response.output_params);
448 resultBlob = kmBuffer2hidlVec(response.output);
449 }
450 _hidl_cb(legacy_enum_conversion(response.error), resultParams, resultBlob);
451 return Void();
452 }
453
abort(uint64_t operationHandle)454 Return<ErrorCode> TrustyKeymaster3Device::abort(uint64_t operationHandle) {
455 AbortOperationRequest request(impl_->message_version());
456 request.op_handle = operationHandle;
457
458 AbortOperationResponse response(impl_->message_version());
459 impl_->AbortOperation(request, &response);
460
461 return legacy_enum_conversion(response.error);
462 }
463 } // namespace keymaster
464