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