• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 <aidl/android/hardware/security/see/hwcrypto/BnCryptoOperationContext.h>
18 #include <aidl/android/hardware/security/see/hwcrypto/BnHwCryptoOperations.h>
19 #include <aidl/android/hardware/security/see/hwcrypto/BnOpaqueKey.h>
20 #include <aidl/android/hardware/security/see/hwcrypto/IOpaqueKey.h>
21 #include <android-base/logging.h>
22 #include <android/hardware/security/see/hwcrypto/BnHwCryptoKey.h>
23 #include <binder/RpcTrusty.h>
24 #include <trusty/tipc.h>
25 #include <optional>
26 #include <string>
27 #include "hwcryptokeyimpl.h"
28 
29 using android::IBinder;
30 using android::IInterface;
31 using android::RpcSession;
32 using android::RpcTrustyConnectWithSessionInitializer;
33 using android::sp;
34 using android::wp;
35 using android::base::ErrnoError;
36 using android::base::Error;
37 using android::base::Result;
38 using android::binder::Status;
39 
40 namespace android {
41 namespace trusty {
42 namespace hwcryptohalservice {
43 
44 #define HWCRYPTO_KEY_PORT "com.android.trusty.rust.hwcryptohal.V1"
45 
46 // Even though we get the cpp_hwcrypto::IOpaqueKey and cpp_hwcrypto::ICryptoOperationContext and
47 // create the ndk_hwcrypto wrappers on this library we cannot cast them back when we need them
48 // because they are received on the function calls as binder objects and there is no reliable
49 // we to do this cast yet. Because of that we are creating maps to hold the wrapped objects
50 // and translate them on function calls.
51 // TODO: Add cleanup of both keyMapping and contextMapping once we have more test infrastructure in
52 //       place.
53 std::map<std::weak_ptr<ndk_hwcrypto::IOpaqueKey>, wp<cpp_hwcrypto::IOpaqueKey>, std::owner_less<>>
54         keyMapping;
55 std::map<std::weak_ptr<ndk_hwcrypto::ICryptoOperationContext>,
56          wp<cpp_hwcrypto::ICryptoOperationContext>, std::owner_less<>>
57         contextMapping;
58 
convertStatus(Status status)59 static ndk::ScopedAStatus convertStatus(Status status) {
60     if (status.isOk()) {
61         return ndk::ScopedAStatus::ok();
62     } else {
63         auto exCode = status.exceptionCode();
64         if (exCode == Status::Exception::EX_SERVICE_SPECIFIC) {
65             return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
66                     status.serviceSpecificErrorCode(), status.exceptionMessage());
67         } else {
68             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(exCode,
69                                                                     status.exceptionMessage());
70         }
71     }
72 }
73 
convertExplicitKeyMaterial(const ndk_hwcrypto::types::ExplicitKeyMaterial & keyMaterial)74 static std::optional<cpp_hwcrypto::types::ExplicitKeyMaterial> convertExplicitKeyMaterial(
75         const ndk_hwcrypto::types::ExplicitKeyMaterial& keyMaterial) {
76     auto explicitKeyCpp = cpp_hwcrypto::types::ExplicitKeyMaterial();
77 
78     if (keyMaterial.getTag() == ndk_hwcrypto::types::ExplicitKeyMaterial::aes) {
79         auto aesKey = keyMaterial.get<ndk_hwcrypto::types::ExplicitKeyMaterial::aes>();
80         auto aesKeyCpp = cpp_hwcrypto::types::AesKey();
81         if (aesKey.getTag() == ndk_hwcrypto::types::AesKey::aes128) {
82             aesKeyCpp.set<cpp_hwcrypto::types::AesKey::aes128>(
83                     aesKey.get<ndk_hwcrypto::types::AesKey::aes128>());
84             explicitKeyCpp.set<cpp_hwcrypto::types::ExplicitKeyMaterial::aes>(aesKeyCpp);
85         } else if (aesKey.getTag() == ndk_hwcrypto::types::AesKey::aes256) {
86             aesKeyCpp.set<cpp_hwcrypto::types::AesKey::aes256>(
87                     aesKey.get<ndk_hwcrypto::types::AesKey::aes256>());
88             explicitKeyCpp.set<cpp_hwcrypto::types::ExplicitKeyMaterial::aes>(aesKeyCpp);
89         } else {
90             LOG(ERROR) << "unknown AesKey type";
91             return std::nullopt;
92         }
93     } else if (keyMaterial.getTag() == ndk_hwcrypto::types::ExplicitKeyMaterial::hmac) {
94         auto hmacKey = keyMaterial.get<ndk_hwcrypto::types::ExplicitKeyMaterial::hmac>();
95         auto hmacKeyCpp = cpp_hwcrypto::types::HmacKey();
96         if (hmacKey.getTag() == ndk_hwcrypto::types::HmacKey::sha256) {
97             hmacKeyCpp.set<cpp_hwcrypto::types::HmacKey::sha256>(
98                     hmacKey.get<ndk_hwcrypto::types::HmacKey::sha256>());
99             explicitKeyCpp.set<cpp_hwcrypto::types::ExplicitKeyMaterial::hmac>(hmacKeyCpp);
100         } else if (hmacKey.getTag() == ndk_hwcrypto::types::HmacKey::sha512) {
101             hmacKeyCpp.set<cpp_hwcrypto::types::HmacKey::sha512>(
102                     hmacKey.get<ndk_hwcrypto::types::HmacKey::sha512>());
103             explicitKeyCpp.set<cpp_hwcrypto::types::ExplicitKeyMaterial::hmac>(hmacKeyCpp);
104         } else {
105             LOG(ERROR) << "unknown HmacKey type";
106             return std::nullopt;
107         }
108     } else {
109         LOG(ERROR) << "unknown Key type";
110         return std::nullopt;
111     }
112     return explicitKeyCpp;
113 }
114 
115 class HwCryptoOperationContextNdk : public ndk_hwcrypto::BnCryptoOperationContext {
116   private:
117     sp<cpp_hwcrypto::ICryptoOperationContext> mContext;
118     std::weak_ptr<ndk_hwcrypto::ICryptoOperationContext> self;
119 
120   public:
HwCryptoOperationContextNdk(sp<cpp_hwcrypto::ICryptoOperationContext> operations)121     HwCryptoOperationContextNdk(sp<cpp_hwcrypto::ICryptoOperationContext> operations)
122         : mContext(std::move(operations)) {}
123 
~HwCryptoOperationContextNdk()124     ~HwCryptoOperationContextNdk() { contextMapping.erase(self); }
125 
Create(sp<cpp_hwcrypto::ICryptoOperationContext> operations)126     static std::shared_ptr<HwCryptoOperationContextNdk> Create(
127             sp<cpp_hwcrypto::ICryptoOperationContext> operations) {
128         if (operations == nullptr) {
129             return nullptr;
130         }
131         std::shared_ptr<HwCryptoOperationContextNdk> contextNdk =
132                 ndk::SharedRefBase::make<HwCryptoOperationContextNdk>(std::move(operations));
133 
134         if (!contextNdk) {
135             LOG(ERROR) << "failed to allocate HwCryptoOperationContext";
136             return nullptr;
137         }
138         contextNdk->self = contextNdk;
139         return contextNdk;
140     }
141 };
142 
convertOperationData(const ndk_hwcrypto::types::OperationData & ndkOperationData)143 std::optional<cpp_hwcrypto::types::OperationData> convertOperationData(
144         const ndk_hwcrypto::types::OperationData& ndkOperationData) {
145     cpp_hwcrypto::types::OperationData cppOperationData = cpp_hwcrypto::types::OperationData();
146     cpp_hwcrypto::types::MemoryBufferReference cppMemBuffRef;
147     switch (ndkOperationData.getTag()) {
148         case ndk_hwcrypto::types::OperationData::dataBuffer:
149             cppOperationData.set<cpp_hwcrypto::types::OperationData::dataBuffer>(
150                     ndkOperationData.get<ndk_hwcrypto::types::OperationData::dataBuffer>());
151             break;
152         case ndk_hwcrypto::types::OperationData::memoryBufferReference:
153             cppMemBuffRef.startOffset =
154                     ndkOperationData
155                             .get<ndk_hwcrypto::types::OperationData::memoryBufferReference>()
156                             .startOffset;
157             cppMemBuffRef.sizeBytes =
158                     ndkOperationData
159                             .get<ndk_hwcrypto::types::OperationData::memoryBufferReference>()
160                             .sizeBytes;
161             cppOperationData.set<cpp_hwcrypto::types::OperationData::memoryBufferReference>(
162                     std::move(cppMemBuffRef));
163             break;
164         default:
165             LOG(ERROR) << "received unknown operation data type";
166             return std::nullopt;
167     }
168     return cppOperationData;
169 }
170 
convertPatternParameters(const ndk_hwcrypto::PatternParameters & ndkpatternParameters)171 std::optional<cpp_hwcrypto::PatternParameters> convertPatternParameters(
172         const ndk_hwcrypto::PatternParameters& ndkpatternParameters) {
173     int64_t numberBlocksProcess = ndkpatternParameters.numberBlocksProcess;
174     int64_t numberBlocksCopy = ndkpatternParameters.numberBlocksCopy;
175     if ((numberBlocksProcess < 0) || (numberBlocksCopy < 0)) {
176         LOG(ERROR) << "received invalid pattern parameters";
177         return std::nullopt;
178     }
179     cpp_hwcrypto::PatternParameters patternParameters = cpp_hwcrypto::PatternParameters();
180     patternParameters.numberBlocksProcess = numberBlocksProcess;
181     patternParameters.numberBlocksCopy = numberBlocksCopy;
182     return patternParameters;
183 }
184 
convertSymmetricOperation(const ndk_hwcrypto::types::SymmetricOperation & ndkSymmetricOperation)185 std::optional<cpp_hwcrypto::types::SymmetricOperation> convertSymmetricOperation(
186         const ndk_hwcrypto::types::SymmetricOperation& ndkSymmetricOperation) {
187     cpp_hwcrypto::types::SymmetricOperation symmetricOperation =
188             cpp_hwcrypto::types::SymmetricOperation();
189     switch (ndkSymmetricOperation) {
190         case ndk_hwcrypto::types::SymmetricOperation::ENCRYPT:
191             symmetricOperation = cpp_hwcrypto::types::SymmetricOperation::ENCRYPT;
192             break;
193         case ndk_hwcrypto::types::SymmetricOperation::DECRYPT:
194             symmetricOperation = cpp_hwcrypto::types::SymmetricOperation::DECRYPT;
195             break;
196         default:
197             LOG(ERROR) << "invalid symmetric operation type";
198             return std::nullopt;
199     }
200     return symmetricOperation;
201 }
202 
convertSymmetricModeParameters(const ndk_hwcrypto::types::CipherModeParameters & ndkcipherModeParameters)203 cpp_hwcrypto::types::CipherModeParameters convertSymmetricModeParameters(
204         const ndk_hwcrypto::types::CipherModeParameters& ndkcipherModeParameters) {
205     cpp_hwcrypto::types::CipherModeParameters cipherModeParameters =
206             cpp_hwcrypto::types::CipherModeParameters();
207     cipherModeParameters.nonce = ndkcipherModeParameters.nonce;
208     return cipherModeParameters;
209 }
210 
convertSymmetricModeParameters(const ndk_hwcrypto::types::AesGcmMode::AesGcmModeParameters & ndkgcmModeParameters)211 cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters convertSymmetricModeParameters(
212         const ndk_hwcrypto::types::AesGcmMode::AesGcmModeParameters& ndkgcmModeParameters) {
213     cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters gcmModeParameters =
214             cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters();
215     gcmModeParameters.nonce = ndkgcmModeParameters.nonce;
216     return gcmModeParameters;
217 }
218 
convertMemoryBufferParameters(const ndk_hwcrypto::MemoryBufferParameter & ndkMemBuffParams)219 std::optional<cpp_hwcrypto::MemoryBufferParameter> convertMemoryBufferParameters(
220         const ndk_hwcrypto::MemoryBufferParameter& ndkMemBuffParams) {
221     cpp_hwcrypto::MemoryBufferParameter memBuffParams = cpp_hwcrypto::MemoryBufferParameter();
222     memBuffParams.sizeBytes = ndkMemBuffParams.sizeBytes;
223     android::os::ParcelFileDescriptor pfd;
224     ndk::ScopedFileDescriptor ndkFd;
225     switch (ndkMemBuffParams.bufferHandle.getTag()) {
226         case ndk_hwcrypto::MemoryBufferParameter::MemoryBuffer::input:
227             ndkFd = ndkMemBuffParams.bufferHandle
228                             .get<ndk_hwcrypto::MemoryBufferParameter::MemoryBuffer::input>()
229                             .dup();
230             pfd.reset(binder::unique_fd(ndkFd.release()));
231             memBuffParams.bufferHandle
232                     .set<cpp_hwcrypto::MemoryBufferParameter::MemoryBuffer::input>(std::move(pfd));
233             break;
234         case ndk_hwcrypto::MemoryBufferParameter::MemoryBuffer::output:
235             ndkFd = ndkMemBuffParams.bufferHandle
236                             .get<ndk_hwcrypto::MemoryBufferParameter::MemoryBuffer::output>()
237                             .dup();
238             pfd.reset(binder::unique_fd(ndkFd.release()));
239             memBuffParams.bufferHandle
240                     .set<cpp_hwcrypto::MemoryBufferParameter::MemoryBuffer::output>(std::move(pfd));
241             break;
242         default:
243             LOG(ERROR) << "unknown bufferHandle type";
244             return std::nullopt;
245     }
246     return memBuffParams;
247 }
248 
convertOperationParameters(const ndk_hwcrypto::OperationParameters & ndkOperationParameters)249 std::optional<cpp_hwcrypto::OperationParameters> convertOperationParameters(
250         const ndk_hwcrypto::OperationParameters& ndkOperationParameters) {
251     cpp_hwcrypto::OperationParameters operationParameters = cpp_hwcrypto::OperationParameters();
252     sp<cpp_hwcrypto::IOpaqueKey> opaqueKey;
253     cpp_hwcrypto::types::HmacOperationParameters hmacParameters =
254             cpp_hwcrypto::types::HmacOperationParameters();
255     std::optional<cpp_hwcrypto::types::SymmetricOperation> cppSymmetricOperation;
256     cpp_hwcrypto::types::CipherModeParameters cipherModeParameters;
257     cpp_hwcrypto::types::AesCipherMode cppAesCipherMode = cpp_hwcrypto::types::AesCipherMode();
258     cpp_hwcrypto::types::SymmetricOperationParameters cppSymmetricOperationParameters =
259             cpp_hwcrypto::types::SymmetricOperationParameters();
260     cpp_hwcrypto::types::SymmetricAuthOperationParameters cppSymmetricAuthOperationParameters =
261             cpp_hwcrypto::types::SymmetricAuthOperationParameters();
262     cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters cppAesGcmModeParameters =
263             cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters();
264     cpp_hwcrypto::types::AesGcmMode cppAesGcmMode = cpp_hwcrypto::types::AesGcmMode();
265     switch (ndkOperationParameters.getTag()) {
266         case ndk_hwcrypto::OperationParameters::symmetricAuthCrypto:
267             opaqueKey = retrieveCppBinder<cpp_hwcrypto::IOpaqueKey, ndk_hwcrypto::IOpaqueKey,
268                                           keyMapping>(
269                     ndkOperationParameters
270                             .get<ndk_hwcrypto::OperationParameters::symmetricAuthCrypto>()
271                             .key);
272             if (!opaqueKey) {
273                 LOG(ERROR) << "couldn't get aes key";
274                 return std::nullopt;
275             }
276             cppSymmetricAuthOperationParameters.key = std::move(opaqueKey);
277             cppSymmetricOperation = convertSymmetricOperation(
278                     ndkOperationParameters
279                             .get<ndk_hwcrypto::OperationParameters::symmetricAuthCrypto>()
280                             .direction);
281             if (!cppSymmetricOperation.has_value()) {
282                 LOG(ERROR) << "couldn't get aes direction";
283                 return std::nullopt;
284             }
285             cppSymmetricAuthOperationParameters.direction =
286                     std::move(cppSymmetricOperation.value());
287             switch (ndkOperationParameters
288                             .get<ndk_hwcrypto::OperationParameters::symmetricAuthCrypto>()
289                             .parameters.getTag()) {
290                 case ndk_hwcrypto::types::SymmetricAuthCryptoParameters::aes:
291                     switch (ndkOperationParameters
292                                     .get<ndk_hwcrypto::OperationParameters::symmetricAuthCrypto>()
293                                     .parameters
294                                     .get<ndk_hwcrypto::types::SymmetricAuthCryptoParameters::aes>()
295                                     .getTag()) {
296                         case ndk_hwcrypto::types::AesGcmMode::gcmTag16:
297                             cppAesGcmModeParameters = convertSymmetricModeParameters(
298                                     ndkOperationParameters
299                                             .get<ndk_hwcrypto::OperationParameters::
300                                                          symmetricAuthCrypto>()
301                                             .parameters
302                                             .get<ndk_hwcrypto::types::
303                                                          SymmetricAuthCryptoParameters::aes>()
304                                             .get<ndk_hwcrypto::types::AesGcmMode::gcmTag16>());
305                             cppAesGcmMode.set<cpp_hwcrypto::types::AesGcmMode::gcmTag16>(
306                                     std::move(cppAesGcmModeParameters));
307                             cppSymmetricAuthOperationParameters.parameters
308                                     .set<cpp_hwcrypto::types::SymmetricAuthCryptoParameters::aes>(
309                                             std::move(cppAesGcmMode));
310                             break;
311                         default:
312                             LOG(ERROR) << "received invalid aes gcm parameters";
313                             return std::nullopt;
314                     }
315                     break;
316                 default:
317                     LOG(ERROR) << "received invalid symmetric auth crypto parameters";
318                     return std::nullopt;
319             }
320             operationParameters.set<cpp_hwcrypto::OperationParameters::symmetricAuthCrypto>(
321                     std::move(cppSymmetricAuthOperationParameters));
322             break;
323         case ndk_hwcrypto::OperationParameters::symmetricCrypto:
324             opaqueKey = retrieveCppBinder<cpp_hwcrypto::IOpaqueKey, ndk_hwcrypto::IOpaqueKey,
325                                           keyMapping>(
326                     ndkOperationParameters.get<ndk_hwcrypto::OperationParameters::symmetricCrypto>()
327                             .key);
328             if (!opaqueKey) {
329                 LOG(ERROR) << "couldn't get aes key";
330                 return std::nullopt;
331             }
332             cppSymmetricOperationParameters.key = std::move(opaqueKey);
333             cppSymmetricOperation = convertSymmetricOperation(
334                     ndkOperationParameters.get<ndk_hwcrypto::OperationParameters::symmetricCrypto>()
335                             .direction);
336             if (!cppSymmetricOperation.has_value()) {
337                 LOG(ERROR) << "couldn't get aes direction";
338                 return std::nullopt;
339             }
340             cppSymmetricOperationParameters.direction = std::move(cppSymmetricOperation.value());
341             switch (ndkOperationParameters.get<ndk_hwcrypto::OperationParameters::symmetricCrypto>()
342                             .parameters.getTag()) {
343                 case ndk_hwcrypto::types::SymmetricCryptoParameters::aes:
344                     switch (ndkOperationParameters
345                                     .get<ndk_hwcrypto::OperationParameters::symmetricCrypto>()
346                                     .parameters
347                                     .get<ndk_hwcrypto::types::SymmetricCryptoParameters::aes>()
348                                     .getTag()) {
349                         case ndk_hwcrypto::types::AesCipherMode::cbc:
350                             cipherModeParameters = convertSymmetricModeParameters(
351                                     ndkOperationParameters
352                                             .get<ndk_hwcrypto::OperationParameters::
353                                                          symmetricCrypto>()
354                                             .parameters
355                                             .get<ndk_hwcrypto::types::SymmetricCryptoParameters::
356                                                          aes>()
357                                             .get<ndk_hwcrypto::types::AesCipherMode::cbc>());
358                             cppAesCipherMode.set<cpp_hwcrypto::types::AesCipherMode::cbc>(
359                                     std::move(cipherModeParameters));
360                             cppSymmetricOperationParameters.parameters
361                                     .set<cpp_hwcrypto::types::SymmetricCryptoParameters::aes>(
362                                             std::move(cppAesCipherMode));
363                             break;
364                         case ndk_hwcrypto::types::AesCipherMode::ctr:
365                             cipherModeParameters = convertSymmetricModeParameters(
366                                     ndkOperationParameters
367                                             .get<ndk_hwcrypto::OperationParameters::
368                                                          symmetricCrypto>()
369                                             .parameters
370                                             .get<ndk_hwcrypto::types::SymmetricCryptoParameters::
371                                                          aes>()
372                                             .get<ndk_hwcrypto::types::AesCipherMode::ctr>());
373                             cppAesCipherMode.set<cpp_hwcrypto::types::AesCipherMode::ctr>(
374                                     std::move(cipherModeParameters));
375                             cppSymmetricOperationParameters.parameters
376                                     .set<cpp_hwcrypto::types::SymmetricCryptoParameters::aes>(
377                                             std::move(cppAesCipherMode));
378                             break;
379                         default:
380                             LOG(ERROR) << "received invalid aes parameters";
381                             return std::nullopt;
382                     }
383                     break;
384                 default:
385                     LOG(ERROR) << "received invalid symmetric crypto parameters";
386                     return std::nullopt;
387             }
388             operationParameters.set<cpp_hwcrypto::OperationParameters::symmetricCrypto>(
389                     std::move(cppSymmetricOperationParameters));
390             break;
391         case ndk_hwcrypto::OperationParameters::hmac:
392             opaqueKey = retrieveCppBinder<cpp_hwcrypto::IOpaqueKey, ndk_hwcrypto::IOpaqueKey,
393                                           keyMapping>(
394                     ndkOperationParameters.get<ndk_hwcrypto::OperationParameters::hmac>().key);
395             if (!opaqueKey) {
396                 LOG(ERROR) << "couldn't get hmac key";
397                 return std::nullopt;
398             }
399             hmacParameters.key = opaqueKey;
400             operationParameters.set<cpp_hwcrypto::OperationParameters::hmac>(
401                     std::move(hmacParameters));
402             break;
403         default:
404             LOG(ERROR) << "received invalid operation parameters";
405             return std::nullopt;
406     }
407     return operationParameters;
408 }
409 
410 class HwCryptoOperationsNdk : public ndk_hwcrypto::BnHwCryptoOperations {
411   private:
412     sp<cpp_hwcrypto::IHwCryptoOperations> mHwCryptoOperations;
413 
414   public:
HwCryptoOperationsNdk(sp<cpp_hwcrypto::IHwCryptoOperations> operations)415     HwCryptoOperationsNdk(sp<cpp_hwcrypto::IHwCryptoOperations> operations)
416         : mHwCryptoOperations(std::move(operations)) {}
417 
Create(sp<cpp_hwcrypto::IHwCryptoOperations> operations)418     static std::shared_ptr<HwCryptoOperationsNdk> Create(
419             sp<cpp_hwcrypto::IHwCryptoOperations> operations) {
420         if (operations == nullptr) {
421             return nullptr;
422         }
423         std::shared_ptr<HwCryptoOperationsNdk> operationsNdk =
424                 ndk::SharedRefBase::make<HwCryptoOperationsNdk>(std::move(operations));
425 
426         if (!operationsNdk) {
427             LOG(ERROR) << "failed to allocate HwCryptoOperations";
428             return nullptr;
429         }
430         return operationsNdk;
431     }
432 
processCommandList(std::vector<ndk_hwcrypto::CryptoOperationSet> * operationSets,std::vector<ndk_hwcrypto::CryptoOperationResult> * aidl_return)433     ndk::ScopedAStatus processCommandList(
434             std::vector<ndk_hwcrypto::CryptoOperationSet>* operationSets,
435             std::vector<ndk_hwcrypto::CryptoOperationResult>* aidl_return) {
436         Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
437         if (operationSets == nullptr) {
438             LOG(ERROR) << "received a null operation set";
439             return convertStatus(status);
440         }
441         if (aidl_return == nullptr) {
442             LOG(ERROR) << "received a null CryptoOperationResult set";
443             return convertStatus(status);
444         }
445         std::vector<cpp_hwcrypto::CryptoOperationResult> binderResult;
446         std::vector<cpp_hwcrypto::CryptoOperationSet> cppOperationSets;
447         for (ndk_hwcrypto::CryptoOperationSet& operationSet : *operationSets) {
448             cpp_hwcrypto::CryptoOperationSet cppSingleOperation =
449                     cpp_hwcrypto::CryptoOperationSet();
450             cppSingleOperation.context =
451                     retrieveCppBinder<cpp_hwcrypto::ICryptoOperationContext,
452                                       ndk_hwcrypto::ICryptoOperationContext, contextMapping>(
453                             operationSet.context);
454             for (ndk_hwcrypto::CryptoOperation& operation : operationSet.operations) {
455                 cpp_hwcrypto::CryptoOperation cppOperation;
456                 cpp_hwcrypto::types::Void voidObj;
457                 std::optional<cpp_hwcrypto::types::OperationData> cppOperationData;
458                 std::optional<cpp_hwcrypto::PatternParameters> cppPatternParameters;
459                 std::optional<cpp_hwcrypto::OperationParameters> cppOperationParameters;
460                 std::optional<cpp_hwcrypto::MemoryBufferParameter> cppMemBuffParams;
461                 switch (operation.getTag()) {
462                     case ndk_hwcrypto::CryptoOperation::setMemoryBuffer:
463                         cppMemBuffParams = convertMemoryBufferParameters(
464                                 operation.get<ndk_hwcrypto::CryptoOperation::setMemoryBuffer>());
465                         if (cppMemBuffParams.has_value()) {
466                             cppOperation.set<cpp_hwcrypto::CryptoOperation::setMemoryBuffer>(
467                                     std::move(cppMemBuffParams.value()));
468                         } else {
469                             return convertStatus(status);
470                         }
471                         break;
472                     case ndk_hwcrypto::CryptoOperation::setOperationParameters:
473                         cppOperationParameters = convertOperationParameters(
474                                 operation.get<
475                                         ndk_hwcrypto::CryptoOperation::setOperationParameters>());
476                         if (cppOperationParameters.has_value()) {
477                             cppOperation.set<cpp_hwcrypto::CryptoOperation::setOperationParameters>(
478                                     std::move(cppOperationParameters.value()));
479                         } else {
480                             LOG(ERROR) << "couldn't convert operation parameters";
481                             return convertStatus(status);
482                         }
483                         break;
484                     case ndk_hwcrypto::CryptoOperation::setPattern:
485                         cppPatternParameters = convertPatternParameters(
486                                 operation.get<ndk_hwcrypto::CryptoOperation::setPattern>());
487                         if (cppPatternParameters.has_value()) {
488                             cppOperation.set<cpp_hwcrypto::CryptoOperation::setPattern>(
489                                     std::move(cppPatternParameters.value()));
490                         } else {
491                             LOG(ERROR) << "couldn't convert pattern parameters";
492                             return convertStatus(status);
493                         }
494                         break;
495                     case ndk_hwcrypto::CryptoOperation::copyData:
496                         cppOperationData = convertOperationData(
497                                 operation.get<ndk_hwcrypto::CryptoOperation::copyData>());
498                         if (cppOperationData.has_value()) {
499                             cppOperation.set<cpp_hwcrypto::CryptoOperation::copyData>(
500                                     std::move(cppOperationData.value()));
501                         } else {
502                             LOG(ERROR) << "couldn't convert CryptoOperation::copyData";
503                             return convertStatus(status);
504                         }
505                         break;
506                     case ndk_hwcrypto::CryptoOperation::aadInput:
507                         cppOperationData = convertOperationData(
508                                 operation.get<ndk_hwcrypto::CryptoOperation::aadInput>());
509                         if (cppOperationData.has_value()) {
510                             cppOperation.set<cpp_hwcrypto::CryptoOperation::aadInput>(
511                                     std::move(cppOperationData.value()));
512                         } else {
513                             LOG(ERROR) << "couldn't convert CryptoOperation::aadInput";
514                             return convertStatus(status);
515                         }
516                         break;
517                     case ndk_hwcrypto::CryptoOperation::dataInput:
518                         cppOperationData = convertOperationData(
519                                 operation.get<ndk_hwcrypto::CryptoOperation::dataInput>());
520                         if (cppOperationData.has_value()) {
521                             cppOperation.set<cpp_hwcrypto::CryptoOperation::dataInput>(
522                                     std::move(cppOperationData.value()));
523                         } else {
524                             LOG(ERROR) << "couldn't convert CryptoOperation::dataInput";
525                             return convertStatus(status);
526                         }
527                         break;
528                     case ndk_hwcrypto::CryptoOperation::dataOutput:
529                         cppOperationData = convertOperationData(
530                                 operation.get<ndk_hwcrypto::CryptoOperation::dataOutput>());
531                         if (cppOperationData.has_value()) {
532                             cppOperation.set<cpp_hwcrypto::CryptoOperation::dataOutput>(
533                                     std::move(cppOperationData.value()));
534                         } else {
535                             LOG(ERROR) << "couldn't convert CryptoOperation::dataOutput";
536                             return convertStatus(status);
537                         }
538                         break;
539                     case ndk_hwcrypto::CryptoOperation::destroyContext:
540                         cppOperation.set<cpp_hwcrypto::CryptoOperation::destroyContext>(
541                                 std::move(voidObj));
542                         break;
543                     case ndk_hwcrypto::CryptoOperation::finish:
544                         cppOperation.set<cpp_hwcrypto::CryptoOperation::finish>(std::move(voidObj));
545                         break;
546                     default:
547                         // This shouldn't happen
548                         LOG(ERROR) << "received unknown crypto operation";
549                         return convertStatus(status);
550                 }
551                 cppSingleOperation.operations.push_back(std::move(cppOperation));
552             }
553             cppOperationSets.push_back(std::move(cppSingleOperation));
554         }
555         status = mHwCryptoOperations->processCommandList(&cppOperationSets, &binderResult);
556         if (status.isOk()) {
557             *aidl_return = std::vector<ndk_hwcrypto::CryptoOperationResult>();
558             for (cpp_hwcrypto::CryptoOperationResult& result : binderResult) {
559                 ndk_hwcrypto::CryptoOperationResult ndkResult =
560                         ndk_hwcrypto::CryptoOperationResult();
561                 if (result.context != nullptr) {
562                     insertBinderMapping<cpp_hwcrypto::ICryptoOperationContext,
563                                         ndk_hwcrypto::ICryptoOperationContext,
564                                         HwCryptoOperationContextNdk, contextMapping>(
565                             result.context, &ndkResult.context);
566                 } else {
567                     ndkResult.context = nullptr;
568                 }
569                 aidl_return->push_back(std::move(ndkResult));
570             }
571         } else {
572             // No reason to copy back the data output vectors if this failed
573             LOG(ERROR) << "couldn't process command list";
574             return convertStatus(status);
575         }
576         // We need to copy the vectors from the cpp operations back to the ndk one
577         if (cppOperationSets.size() != operationSets->size()) {
578             LOG(ERROR) << "ndk and cpp operation sets had a different number of elements";
579             return convertStatus(Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT));
580         }
581         for (unsigned setIdx = 0; setIdx < cppOperationSets.size(); ++setIdx) {
582             if (cppOperationSets[setIdx].operations.size() !=
583                 (*operationSets)[setIdx].operations.size()) {
584                 LOG(ERROR) << "ndk and cpp operations on set " << setIdx
585                            << " had a different number of elements";
586                 return convertStatus(Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT));
587             }
588             for (unsigned operationIdx = 0;
589                  operationIdx < cppOperationSets[setIdx].operations.size(); ++operationIdx) {
590                 if (cppOperationSets[setIdx].operations[operationIdx].getTag() ==
591                     cpp_hwcrypto::CryptoOperation::dataOutput) {
592                     if ((*operationSets)[setIdx].operations[operationIdx].getTag() !=
593                         ndk_hwcrypto::CryptoOperation::dataOutput) {
594                         LOG(ERROR)
595                                 << "ndk and cpp operations on set " << setIdx << " and operation "
596                                 << operationIdx << " had a different operation type";
597                         return convertStatus(
598                                 Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT));
599                     }
600                     if (cppOperationSets[setIdx]
601                                 .operations[operationIdx]
602                                 .get<cpp_hwcrypto::CryptoOperation::dataOutput>()
603                                 .getTag() == cpp_hwcrypto::types::OperationData::dataBuffer) {
604                         // This is the only case on which we need to move the data backto the
605                         // original array
606                         if ((*operationSets)[setIdx]
607                                     .operations[operationIdx]
608                                     .get<ndk_hwcrypto::CryptoOperation::dataOutput>()
609                                     .getTag() != ndk_hwcrypto::types::OperationData::dataBuffer) {
610                             LOG(ERROR) << "ndk and cpp operations on set " << setIdx
611                                        << " and operation " << operationIdx
612                                        << " had a different operation data output type";
613                             return convertStatus(
614                                     Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT));
615                         }
616                         (*operationSets)[setIdx]
617                                 .operations[operationIdx]
618                                 .get<ndk_hwcrypto::CryptoOperation::dataOutput>()
619                                 .set<ndk_hwcrypto::types::OperationData::dataBuffer>(
620                                         cppOperationSets[setIdx]
621                                                 .operations[operationIdx]
622                                                 .get<cpp_hwcrypto::CryptoOperation::dataOutput>()
623                                                 .get<cpp_hwcrypto::types::OperationData::
624                                                              dataBuffer>());
625                     }
626                 }
627             }
628         }
629         return convertStatus(status);
630     }
631 };
632 
633 class OpaqueKeyNdk : public ndk_hwcrypto::BnOpaqueKey {
634   private:
635     sp<cpp_hwcrypto::IOpaqueKey> mOpaqueKey;
636     std::weak_ptr<ndk_hwcrypto::IOpaqueKey> self;
637 
638   public:
OpaqueKeyNdk(sp<cpp_hwcrypto::IOpaqueKey> opaqueKey)639     OpaqueKeyNdk(sp<cpp_hwcrypto::IOpaqueKey> opaqueKey) : mOpaqueKey(std::move(opaqueKey)) {}
640 
~OpaqueKeyNdk()641     ~OpaqueKeyNdk() { keyMapping.erase(self); }
642 
Create(sp<cpp_hwcrypto::IOpaqueKey> opaqueKey)643     static std::shared_ptr<OpaqueKeyNdk> Create(sp<cpp_hwcrypto::IOpaqueKey> opaqueKey) {
644         if (opaqueKey == nullptr) {
645             return nullptr;
646         }
647         std::shared_ptr<OpaqueKeyNdk> opaqueKeyNdk =
648                 ndk::SharedRefBase::make<OpaqueKeyNdk>(std::move(opaqueKey));
649 
650         if (!opaqueKeyNdk) {
651             LOG(ERROR) << "failed to allocate HwCryptoKey";
652             return nullptr;
653         }
654         opaqueKeyNdk->self = opaqueKeyNdk;
655         return opaqueKeyNdk;
656     }
657 
exportWrappedKey(const std::shared_ptr<ndk_hwcrypto::IOpaqueKey> & wrappingKey,::std::vector<uint8_t> * aidl_return)658     ndk::ScopedAStatus exportWrappedKey(
659             const std::shared_ptr<ndk_hwcrypto::IOpaqueKey>& wrappingKey,
660             ::std::vector<uint8_t>* aidl_return) {
661         Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
662         auto wrappingKeyNdk =
663                 retrieveCppBinder<cpp_hwcrypto::IOpaqueKey, ndk_hwcrypto::IOpaqueKey, keyMapping>(
664                         wrappingKey);
665         if (wrappingKeyNdk == nullptr) {
666             LOG(ERROR) << "couldn't get wrapped key";
667             return convertStatus(status);
668         }
669         status = mOpaqueKey->exportWrappedKey(wrappingKeyNdk, aidl_return);
670         return convertStatus(status);
671     }
672 
getKeyPolicy(ndk_hwcrypto::KeyPolicy * aidl_return)673     ndk::ScopedAStatus getKeyPolicy(ndk_hwcrypto::KeyPolicy* aidl_return) {
674         Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
675         if (aidl_return == nullptr) {
676             LOG(ERROR) << "return value passed to getKeyPolicy is nullptr";
677             return convertStatus(status);
678         }
679         cpp_hwcrypto::KeyPolicy cppPolicy = cpp_hwcrypto::KeyPolicy();
680 
681         status = mOpaqueKey->getKeyPolicy(&cppPolicy);
682         if (status.isOk()) {
683             auto ndkPolicy =
684                     convertKeyPolicy<ndk_hwcrypto::KeyPolicy, cpp_hwcrypto::KeyPolicy>(cppPolicy);
685             *aidl_return = std::move(ndkPolicy);
686         }
687         return convertStatus(status);
688     }
689 
getPublicKey(::std::vector<uint8_t> * aidl_return)690     ndk::ScopedAStatus getPublicKey(::std::vector<uint8_t>* aidl_return) {
691         auto status = mOpaqueKey->getPublicKey(aidl_return);
692         return convertStatus(status);
693     }
694 
getShareableToken(const::std::vector<uint8_t> & sealingDicePolicy,ndk_hwcrypto::types::OpaqueKeyToken * aidl_return)695     ndk::ScopedAStatus getShareableToken(const ::std::vector<uint8_t>& sealingDicePolicy,
696                                          ndk_hwcrypto::types::OpaqueKeyToken* aidl_return) {
697         Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
698         if (aidl_return == nullptr) {
699             LOG(ERROR) << "return value passed to getShareableToken is nullptr";
700             return convertStatus(status);
701         }
702         cpp_hwcrypto::types::OpaqueKeyToken binder_return;
703         status = mOpaqueKey->getShareableToken(sealingDicePolicy, &binder_return);
704         if (status.isOk()) {
705             aidl_return->keyToken = std::move(binder_return.keyToken);
706         }
707         return convertStatus(status);
708     }
709 
setProtectionId(const ndk_hwcrypto::types::ProtectionId,const::std::vector<ndk_hwcrypto::types::OperationType> &)710     ndk::ScopedAStatus setProtectionId(
711             const ndk_hwcrypto::types::ProtectionId /*protectionId*/,
712             const ::std::vector<ndk_hwcrypto::types::OperationType>& /*allowedOperations*/) {
713         return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
714                 ndk_hwcrypto::types::HalErrorCode::UNAUTHORIZED,
715                 "android is not authorized to call setProtectionId");
716     }
717 };
718 
connectToTrusty(const char * tipcDev)719 Result<void> HwCryptoKey::connectToTrusty(const char* tipcDev) {
720     assert(!mSession);
721     auto session_initializer = [](sp<RpcSession>& session) {
722         session->setFileDescriptorTransportMode(RpcSession::FileDescriptorTransportMode::TRUSTY);
723     };
724     mSession =
725             RpcTrustyConnectWithSessionInitializer(tipcDev, HWCRYPTO_KEY_PORT, session_initializer);
726     if (!mSession) {
727         return ErrnoError() << "failed to connect to hwcrypto";
728     }
729     mRoot = mSession->getRootObject();
730     mHwCryptoServer = cpp_hwcrypto::IHwCryptoKey::asInterface(mRoot);
731     return {};
732 }
733 
HwCryptoKey()734 HwCryptoKey::HwCryptoKey() {}
735 
Create(const char * tipcDev)736 std::shared_ptr<HwCryptoKey> HwCryptoKey::Create(const char* tipcDev) {
737     std::shared_ptr<HwCryptoKey> hwCrypto = ndk::SharedRefBase::make<HwCryptoKey>();
738 
739     if (!hwCrypto) {
740         LOG(ERROR) << "failed to allocate HwCryptoKey";
741         return nullptr;
742     }
743 
744     auto ret = hwCrypto->connectToTrusty(tipcDev);
745     if (!ret.ok()) {
746         LOG(ERROR) << "failed to connect HwCryptoKey to Trusty: " << ret.error();
747         return nullptr;
748     }
749 
750     return hwCrypto;
751 }
752 
deriveCurrentDicePolicyBoundKey(const ndk_hwcrypto::IHwCryptoKey::DiceBoundDerivationKey &,ndk_hwcrypto::IHwCryptoKey::DiceCurrentBoundKeyResult *)753 ndk::ScopedAStatus HwCryptoKey::deriveCurrentDicePolicyBoundKey(
754         const ndk_hwcrypto::IHwCryptoKey::DiceBoundDerivationKey& /*derivationKey*/,
755         ndk_hwcrypto::IHwCryptoKey::DiceCurrentBoundKeyResult* /*aidl_return*/) {
756     return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
757             ndk_hwcrypto::types::HalErrorCode::UNAUTHORIZED,
758             "android is not authorized to call deriveCurrentDicePolicyBoundKey");
759 }
760 
deriveDicePolicyBoundKey(const ndk_hwcrypto::IHwCryptoKey::DiceBoundDerivationKey &,const::std::vector<uint8_t> &,ndk_hwcrypto::IHwCryptoKey::DiceBoundKeyResult *)761 ndk::ScopedAStatus HwCryptoKey::deriveDicePolicyBoundKey(
762         const ndk_hwcrypto::IHwCryptoKey::DiceBoundDerivationKey& /*derivationKey*/,
763         const ::std::vector<uint8_t>& /*dicePolicyForKeyVersion*/,
764         ndk_hwcrypto::IHwCryptoKey::DiceBoundKeyResult* /*aidl_return*/) {
765     return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
766             ndk_hwcrypto::types::HalErrorCode::UNAUTHORIZED,
767             "android is not authorized to call deriveDicePolicyBoundKey");
768 }
769 
deriveKey(const ndk_hwcrypto::IHwCryptoKey::DerivedKeyParameters &,ndk_hwcrypto::IHwCryptoKey::DerivedKey *)770 ndk::ScopedAStatus HwCryptoKey::deriveKey(
771         const ndk_hwcrypto::IHwCryptoKey::DerivedKeyParameters& /*parameters*/,
772         ndk_hwcrypto::IHwCryptoKey::DerivedKey* /*aidl_return*/) {
773     return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
774             ndk_hwcrypto::types::HalErrorCode::UNAUTHORIZED,
775             "android is not authorized to call deriveKey");
776 }
777 
getHwCryptoOperations(std::shared_ptr<ndk_hwcrypto::IHwCryptoOperations> * aidl_return)778 ndk::ScopedAStatus HwCryptoKey::getHwCryptoOperations(
779         std::shared_ptr<ndk_hwcrypto::IHwCryptoOperations>* aidl_return) {
780     Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
781     if (aidl_return == nullptr) {
782         LOG(ERROR) << "return value passed to getHwCryptoOperations is nullptr";
783         return convertStatus(status);
784     }
785     sp<cpp_hwcrypto::IHwCryptoOperations> binder_return;
786     status = mHwCryptoServer->getHwCryptoOperations(&binder_return);
787     if (status.isOk()) {
788         std::shared_ptr<ndk_hwcrypto::IHwCryptoOperations> operations =
789                 HwCryptoOperationsNdk::Create(binder_return);
790         *aidl_return = operations;
791     }
792     return convertStatus(status);
793 }
794 
importClearKey(const ndk_hwcrypto::types::ExplicitKeyMaterial & keyMaterial,const ndk_hwcrypto::KeyPolicy & newKeyPolicy,std::shared_ptr<ndk_hwcrypto::IOpaqueKey> * aidl_return)795 ndk::ScopedAStatus HwCryptoKey::importClearKey(
796         const ndk_hwcrypto::types::ExplicitKeyMaterial& keyMaterial,
797         const ndk_hwcrypto::KeyPolicy& newKeyPolicy,
798         std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return) {
799     sp<cpp_hwcrypto::IOpaqueKey> binder_return = nullptr;
800     Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
801     if (aidl_return == nullptr) {
802         LOG(ERROR) << "return value passed to importClearKey is nullptr";
803         return convertStatus(status);
804     }
805     auto cppKeyPolicy =
806             convertKeyPolicy<cpp_hwcrypto::KeyPolicy, ndk_hwcrypto::KeyPolicy>(newKeyPolicy);
807     auto explicitKeyCpp = convertExplicitKeyMaterial(keyMaterial);
808     if (!explicitKeyCpp.has_value()) {
809         LOG(ERROR) << "couldn't convert key material";
810         return convertStatus(status);
811     }
812     status = mHwCryptoServer->importClearKey(explicitKeyCpp.value(), cppKeyPolicy, &binder_return);
813     if (status.isOk()) {
814         if ((binder_return != nullptr)) {
815             insertBinderMapping<cpp_hwcrypto::IOpaqueKey, ndk_hwcrypto::IOpaqueKey, OpaqueKeyNdk,
816                                 keyMapping>(binder_return, aidl_return);
817         } else {
818             *aidl_return = nullptr;
819         }
820     }
821     return convertStatus(status);
822 }
823 
getCurrentDicePolicy(std::vector<uint8_t> * aidl_return)824 ndk::ScopedAStatus HwCryptoKey::getCurrentDicePolicy(std::vector<uint8_t>* aidl_return) {
825     auto status = mHwCryptoServer->getCurrentDicePolicy(aidl_return);
826     return convertStatus(status);
827 }
828 
keyTokenImport(const ndk_hwcrypto::types::OpaqueKeyToken & requestedKey,const::std::vector<uint8_t> & sealingDicePolicy,std::shared_ptr<ndk_hwcrypto::IOpaqueKey> * aidl_return)829 ndk::ScopedAStatus HwCryptoKey::keyTokenImport(
830         const ndk_hwcrypto::types::OpaqueKeyToken& requestedKey,
831         const ::std::vector<uint8_t>& sealingDicePolicy,
832         std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return) {
833     Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
834     if (aidl_return == nullptr) {
835         LOG(ERROR) << "return value passed to keyTokenImport is nullptr";
836         return convertStatus(status);
837     }
838     sp<cpp_hwcrypto::IOpaqueKey> binder_return;
839     cpp_hwcrypto::types::OpaqueKeyToken requestedKeyCpp;
840     // trying first a shallow copy of the vector
841     requestedKeyCpp.keyToken = requestedKey.keyToken;
842     status = mHwCryptoServer->keyTokenImport(requestedKeyCpp, sealingDicePolicy, &binder_return);
843     if (status.isOk()) {
844         std::shared_ptr<ndk_hwcrypto::IOpaqueKey> opaqueKey = OpaqueKeyNdk::Create(binder_return);
845         *aidl_return = opaqueKey;
846     }
847     return convertStatus(status);
848 }
849 
getKeyslotData(ndk_hwcrypto::IHwCryptoKey::KeySlot,std::shared_ptr<ndk_hwcrypto::IOpaqueKey> *)850 ndk::ScopedAStatus HwCryptoKey::getKeyslotData(
851         ndk_hwcrypto::IHwCryptoKey::KeySlot /*slotId*/,
852         std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* /*aidl_return*/) {
853     return ndk::ScopedAStatus::fromServiceSpecificError(
854             ndk_hwcrypto::types::HalErrorCode::UNAUTHORIZED);
855 }
856 
857 }  // namespace hwcryptohalservice
858 }  // namespace trusty
859 }  // namespace android
860