1 /*
2 * Copyright (C) 2021 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/keymint/RpcHardwareInfo.h>
18 #include <cppbor.h>
19 #include <cppbor_parse.h>
20 #include <keymaster/cppcose/cppcose.h>
21 #include <keymaster/keymaster_configuration.h>
22 #include <openssl/bn.h>
23 #include <openssl/ec.h>
24 #include <openssl/rand.h>
25 #include <openssl/x509.h>
26
27 #include <variant>
28
29 #include "KeyMintUtils.h"
30 #include "android/binder_auto_utils.h"
31 #include "remote_remotely_provisioned_component.h"
32
33 namespace aidl::android::hardware::security::keymint {
34 namespace {
35 using namespace cppcose;
36 using namespace keymaster;
37
38 using ::aidl::android::hardware::security::keymint::km_utils::kmBlob2vector;
39 using ::ndk::ScopedAStatus;
40
41 // Error codes from the provisioning stack are negated.
toKeymasterError(const KeymasterResponse & response)42 ndk::ScopedAStatus toKeymasterError(const KeymasterResponse& response) {
43 auto error =
44 static_cast<keymaster_error_t>(-static_cast<int32_t>(response.error));
45 return ::aidl::android::hardware::security::keymint::km_utils::
46 kmError2ScopedAStatus(error);
47 }
48
49 } // namespace
50
RemoteRemotelyProvisionedComponent(keymaster::RemoteKeymaster & impl)51 RemoteRemotelyProvisionedComponent::RemoteRemotelyProvisionedComponent(
52 keymaster::RemoteKeymaster& impl)
53 : impl_(impl) {}
54
getHardwareInfo(RpcHardwareInfo * info)55 ScopedAStatus RemoteRemotelyProvisionedComponent::getHardwareInfo(
56 RpcHardwareInfo* info) {
57 info->versionNumber = 2;
58 info->rpcAuthorName = "Google";
59 info->supportedEekCurve = RpcHardwareInfo::CURVE_25519;
60 info->uniqueId = "remote keymint";
61 return ScopedAStatus::ok();
62 }
63
generateEcdsaP256KeyPair(bool testMode,MacedPublicKey * macedPublicKey,std::vector<uint8_t> * privateKeyHandle)64 ScopedAStatus RemoteRemotelyProvisionedComponent::generateEcdsaP256KeyPair(
65 bool testMode, MacedPublicKey* macedPublicKey,
66 std::vector<uint8_t>* privateKeyHandle) {
67 GenerateRkpKeyRequest request(impl_.message_version());
68 request.test_mode = testMode;
69 GenerateRkpKeyResponse response(impl_.message_version());
70 impl_.GenerateRkpKey(request, &response);
71 if (response.error != KM_ERROR_OK) {
72 return toKeymasterError(response);
73 }
74
75 macedPublicKey->macedKey = km_utils::kmBlob2vector(response.maced_public_key);
76 *privateKeyHandle = km_utils::kmBlob2vector(response.key_blob);
77 return ScopedAStatus::ok();
78 }
79
generateCertificateRequest(bool testMode,const std::vector<MacedPublicKey> & keysToSign,const std::vector<uint8_t> & endpointEncCertChain,const std::vector<uint8_t> & challenge,DeviceInfo * deviceInfo,ProtectedData * protectedData,std::vector<uint8_t> * keysToSignMac)80 ScopedAStatus RemoteRemotelyProvisionedComponent::generateCertificateRequest(
81 bool testMode, const std::vector<MacedPublicKey>& keysToSign,
82 const std::vector<uint8_t>& endpointEncCertChain,
83 const std::vector<uint8_t>& challenge, DeviceInfo* deviceInfo,
84 ProtectedData* protectedData, std::vector<uint8_t>* keysToSignMac) {
85 GenerateCsrRequest request(impl_.message_version());
86 request.test_mode = testMode;
87 request.num_keys = keysToSign.size();
88 request.keys_to_sign_array = new KeymasterBlob[keysToSign.size()];
89 for (size_t i = 0; i < keysToSign.size(); i++) {
90 request.SetKeyToSign(i, keysToSign[i].macedKey.data(),
91 keysToSign[i].macedKey.size());
92 }
93 request.SetEndpointEncCertChain(endpointEncCertChain.data(),
94 endpointEncCertChain.size());
95 request.SetChallenge(challenge.data(), challenge.size());
96 GenerateCsrResponse response(impl_.message_version());
97 impl_.GenerateCsr(request, &response);
98
99 if (response.error != KM_ERROR_OK) {
100 return toKeymasterError(response);
101 }
102 deviceInfo->deviceInfo = km_utils::kmBlob2vector(response.device_info_blob);
103 protectedData->protectedData =
104 km_utils::kmBlob2vector(response.protected_data_blob);
105 *keysToSignMac = km_utils::kmBlob2vector(response.keys_to_sign_mac);
106 return ScopedAStatus::ok();
107 }
108
109 } // namespace aidl::android::hardware::security::keymint
110