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