1*789431f2SAndroid Build Coastguard Worker /*
2*789431f2SAndroid Build Coastguard Worker * Copyright (C) 2021 The Android Open Source Project
3*789431f2SAndroid Build Coastguard Worker *
4*789431f2SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*789431f2SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*789431f2SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*789431f2SAndroid Build Coastguard Worker *
8*789431f2SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*789431f2SAndroid Build Coastguard Worker *
10*789431f2SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*789431f2SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*789431f2SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*789431f2SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*789431f2SAndroid Build Coastguard Worker * limitations under the License.
15*789431f2SAndroid Build Coastguard Worker */
16*789431f2SAndroid Build Coastguard Worker
17*789431f2SAndroid Build Coastguard Worker #include "AndroidRemotelyProvisionedComponentDevice.h"
18*789431f2SAndroid Build Coastguard Worker
19*789431f2SAndroid Build Coastguard Worker #include <assert.h>
20*789431f2SAndroid Build Coastguard Worker #include <variant>
21*789431f2SAndroid Build Coastguard Worker
22*789431f2SAndroid Build Coastguard Worker #include <cppbor.h>
23*789431f2SAndroid Build Coastguard Worker #include <cppbor_parse.h>
24*789431f2SAndroid Build Coastguard Worker
25*789431f2SAndroid Build Coastguard Worker #include <KeyMintUtils.h>
26*789431f2SAndroid Build Coastguard Worker #include <keymaster/cppcose/cppcose.h>
27*789431f2SAndroid Build Coastguard Worker #include <keymaster/keymaster_configuration.h>
28*789431f2SAndroid Build Coastguard Worker
29*789431f2SAndroid Build Coastguard Worker #include <openssl/bn.h>
30*789431f2SAndroid Build Coastguard Worker #include <openssl/ec.h>
31*789431f2SAndroid Build Coastguard Worker #include <openssl/rand.h>
32*789431f2SAndroid Build Coastguard Worker #include <openssl/x509.h>
33*789431f2SAndroid Build Coastguard Worker
34*789431f2SAndroid Build Coastguard Worker namespace aidl::android::hardware::security::keymint {
35*789431f2SAndroid Build Coastguard Worker
36*789431f2SAndroid Build Coastguard Worker using keymaster::GenerateCsrRequest;
37*789431f2SAndroid Build Coastguard Worker using keymaster::GenerateCsrResponse;
38*789431f2SAndroid Build Coastguard Worker using keymaster::GenerateCsrV2Request;
39*789431f2SAndroid Build Coastguard Worker using keymaster::GenerateCsrV2Response;
40*789431f2SAndroid Build Coastguard Worker using keymaster::GenerateRkpKeyRequest;
41*789431f2SAndroid Build Coastguard Worker using keymaster::GenerateRkpKeyResponse;
42*789431f2SAndroid Build Coastguard Worker using keymaster::GetHwInfoRequest;
43*789431f2SAndroid Build Coastguard Worker using keymaster::GetHwInfoResponse;
44*789431f2SAndroid Build Coastguard Worker using keymaster::KeymasterBlob;
45*789431f2SAndroid Build Coastguard Worker using ::std::string;
46*789431f2SAndroid Build Coastguard Worker using ::std::unique_ptr;
47*789431f2SAndroid Build Coastguard Worker using ::std::vector;
48*789431f2SAndroid Build Coastguard Worker using bytevec = ::std::vector<uint8_t>;
49*789431f2SAndroid Build Coastguard Worker
50*789431f2SAndroid Build Coastguard Worker namespace {
51*789431f2SAndroid Build Coastguard Worker
52*789431f2SAndroid Build Coastguard Worker constexpr auto STATUS_FAILED = IRemotelyProvisionedComponent::STATUS_FAILED;
53*789431f2SAndroid Build Coastguard Worker
54*789431f2SAndroid Build Coastguard Worker struct AStatusDeleter {
operator ()aidl::android::hardware::security::keymint::__anonacea8c290111::AStatusDeleter55*789431f2SAndroid Build Coastguard Worker void operator()(AStatus* p) { AStatus_delete(p); }
56*789431f2SAndroid Build Coastguard Worker };
57*789431f2SAndroid Build Coastguard Worker
58*789431f2SAndroid Build Coastguard Worker class Status {
59*789431f2SAndroid Build Coastguard Worker public:
Status()60*789431f2SAndroid Build Coastguard Worker Status() : status_(AStatus_newOk()) {}
Status(int32_t errCode,const std::string & errMsg)61*789431f2SAndroid Build Coastguard Worker Status(int32_t errCode, const std::string& errMsg)
62*789431f2SAndroid Build Coastguard Worker : status_(AStatus_fromServiceSpecificErrorWithMessage(errCode, errMsg.c_str())) {}
Status(const std::string & errMsg)63*789431f2SAndroid Build Coastguard Worker explicit Status(const std::string& errMsg)
64*789431f2SAndroid Build Coastguard Worker : status_(AStatus_fromServiceSpecificErrorWithMessage(STATUS_FAILED, errMsg.c_str())) {}
Status(AStatus * status)65*789431f2SAndroid Build Coastguard Worker explicit Status(AStatus* status) : status_(status ? status : AStatus_newOk()) {}
66*789431f2SAndroid Build Coastguard Worker
67*789431f2SAndroid Build Coastguard Worker Status(Status&&) = default;
68*789431f2SAndroid Build Coastguard Worker Status(const Status&) = delete;
69*789431f2SAndroid Build Coastguard Worker
operator ::ndk::ScopedAStatus()70*789431f2SAndroid Build Coastguard Worker operator ::ndk::ScopedAStatus() && { // NOLINT(google-explicit-constructor)
71*789431f2SAndroid Build Coastguard Worker return ndk::ScopedAStatus(status_.release());
72*789431f2SAndroid Build Coastguard Worker }
73*789431f2SAndroid Build Coastguard Worker
isOk() const74*789431f2SAndroid Build Coastguard Worker bool isOk() const { return AStatus_isOk(status_.get()); }
75*789431f2SAndroid Build Coastguard Worker
getMessage() const76*789431f2SAndroid Build Coastguard Worker const char* getMessage() const { return AStatus_getMessage(status_.get()); }
77*789431f2SAndroid Build Coastguard Worker
78*789431f2SAndroid Build Coastguard Worker private:
79*789431f2SAndroid Build Coastguard Worker std::unique_ptr<AStatus, AStatusDeleter> status_;
80*789431f2SAndroid Build Coastguard Worker };
81*789431f2SAndroid Build Coastguard Worker
82*789431f2SAndroid Build Coastguard Worker } // namespace
83*789431f2SAndroid Build Coastguard Worker
AndroidRemotelyProvisionedComponentDevice(const std::shared_ptr<AndroidKeyMintDevice> & keymint)84*789431f2SAndroid Build Coastguard Worker AndroidRemotelyProvisionedComponentDevice::AndroidRemotelyProvisionedComponentDevice(
85*789431f2SAndroid Build Coastguard Worker const std::shared_ptr<AndroidKeyMintDevice>& keymint) {
86*789431f2SAndroid Build Coastguard Worker impl_ = keymint->getKeymasterImpl();
87*789431f2SAndroid Build Coastguard Worker }
88*789431f2SAndroid Build Coastguard Worker
getHardwareInfo(RpcHardwareInfo * info)89*789431f2SAndroid Build Coastguard Worker ScopedAStatus AndroidRemotelyProvisionedComponentDevice::getHardwareInfo(RpcHardwareInfo* info) {
90*789431f2SAndroid Build Coastguard Worker GetHwInfoResponse response = impl_->GetHwInfo();
91*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) {
92*789431f2SAndroid Build Coastguard Worker return Status(-static_cast<int32_t>(response.error), "Failed to get hardware info.");
93*789431f2SAndroid Build Coastguard Worker }
94*789431f2SAndroid Build Coastguard Worker
95*789431f2SAndroid Build Coastguard Worker info->versionNumber = response.version;
96*789431f2SAndroid Build Coastguard Worker info->rpcAuthorName = response.rpcAuthorName;
97*789431f2SAndroid Build Coastguard Worker info->supportedEekCurve = response.supportedEekCurve;
98*789431f2SAndroid Build Coastguard Worker info->uniqueId = response.uniqueId;
99*789431f2SAndroid Build Coastguard Worker info->supportedNumKeysInCsr = response.supportedNumKeysInCsr;
100*789431f2SAndroid Build Coastguard Worker return ScopedAStatus::ok();
101*789431f2SAndroid Build Coastguard Worker }
102*789431f2SAndroid Build Coastguard Worker
generateEcdsaP256KeyPair(bool testMode,MacedPublicKey * macedPublicKey,bytevec * privateKeyHandle)103*789431f2SAndroid Build Coastguard Worker ScopedAStatus AndroidRemotelyProvisionedComponentDevice::generateEcdsaP256KeyPair(
104*789431f2SAndroid Build Coastguard Worker bool testMode, MacedPublicKey* macedPublicKey, bytevec* privateKeyHandle) {
105*789431f2SAndroid Build Coastguard Worker GenerateRkpKeyRequest request(impl_->message_version());
106*789431f2SAndroid Build Coastguard Worker request.test_mode = testMode;
107*789431f2SAndroid Build Coastguard Worker GenerateRkpKeyResponse response(impl_->message_version());
108*789431f2SAndroid Build Coastguard Worker impl_->GenerateRkpKey(request, &response);
109*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) {
110*789431f2SAndroid Build Coastguard Worker return Status(-static_cast<int32_t>(response.error), "Failure in key generation.");
111*789431f2SAndroid Build Coastguard Worker }
112*789431f2SAndroid Build Coastguard Worker
113*789431f2SAndroid Build Coastguard Worker macedPublicKey->macedKey = km_utils::kmBlob2vector(response.maced_public_key);
114*789431f2SAndroid Build Coastguard Worker *privateKeyHandle = km_utils::kmBlob2vector(response.key_blob);
115*789431f2SAndroid Build Coastguard Worker return ScopedAStatus::ok();
116*789431f2SAndroid Build Coastguard Worker }
117*789431f2SAndroid Build Coastguard Worker
generateCertificateRequest(bool testMode,const vector<MacedPublicKey> & keysToSign,const bytevec & endpointEncCertChain,const bytevec & challenge,DeviceInfo * deviceInfo,ProtectedData * protectedData,bytevec * keysToSignMac)118*789431f2SAndroid Build Coastguard Worker ScopedAStatus AndroidRemotelyProvisionedComponentDevice::generateCertificateRequest(
119*789431f2SAndroid Build Coastguard Worker bool testMode, const vector<MacedPublicKey>& keysToSign, const bytevec& endpointEncCertChain,
120*789431f2SAndroid Build Coastguard Worker const bytevec& challenge, DeviceInfo* deviceInfo, ProtectedData* protectedData,
121*789431f2SAndroid Build Coastguard Worker bytevec* keysToSignMac) {
122*789431f2SAndroid Build Coastguard Worker GenerateCsrRequest request(impl_->message_version());
123*789431f2SAndroid Build Coastguard Worker request.test_mode = testMode;
124*789431f2SAndroid Build Coastguard Worker request.num_keys = keysToSign.size();
125*789431f2SAndroid Build Coastguard Worker request.keys_to_sign_array = new (std::nothrow) KeymasterBlob[keysToSign.size()];
126*789431f2SAndroid Build Coastguard Worker if (request.keys_to_sign_array == nullptr) {
127*789431f2SAndroid Build Coastguard Worker return km_utils::kmError2ScopedAStatus(KM_ERROR_MEMORY_ALLOCATION_FAILED);
128*789431f2SAndroid Build Coastguard Worker }
129*789431f2SAndroid Build Coastguard Worker for (size_t i = 0; i < keysToSign.size(); i++) {
130*789431f2SAndroid Build Coastguard Worker request.SetKeyToSign(i, keysToSign[i].macedKey.data(), keysToSign[i].macedKey.size());
131*789431f2SAndroid Build Coastguard Worker }
132*789431f2SAndroid Build Coastguard Worker request.SetEndpointEncCertChain(endpointEncCertChain.data(), endpointEncCertChain.size());
133*789431f2SAndroid Build Coastguard Worker request.SetChallenge(challenge.data(), challenge.size());
134*789431f2SAndroid Build Coastguard Worker GenerateCsrResponse response(impl_->message_version());
135*789431f2SAndroid Build Coastguard Worker impl_->GenerateCsr(request, &response);
136*789431f2SAndroid Build Coastguard Worker
137*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) {
138*789431f2SAndroid Build Coastguard Worker return Status(-static_cast<int32_t>(response.error), "Failure in CSR Generation.");
139*789431f2SAndroid Build Coastguard Worker }
140*789431f2SAndroid Build Coastguard Worker deviceInfo->deviceInfo = km_utils::kmBlob2vector(response.device_info_blob);
141*789431f2SAndroid Build Coastguard Worker protectedData->protectedData = km_utils::kmBlob2vector(response.protected_data_blob);
142*789431f2SAndroid Build Coastguard Worker *keysToSignMac = km_utils::kmBlob2vector(response.keys_to_sign_mac);
143*789431f2SAndroid Build Coastguard Worker return ScopedAStatus::ok();
144*789431f2SAndroid Build Coastguard Worker }
145*789431f2SAndroid Build Coastguard Worker
generateCertificateRequestV2(const std::vector<MacedPublicKey> & keysToSign,const std::vector<uint8_t> & challenge,std::vector<uint8_t> * csr)146*789431f2SAndroid Build Coastguard Worker ScopedAStatus AndroidRemotelyProvisionedComponentDevice::generateCertificateRequestV2(
147*789431f2SAndroid Build Coastguard Worker const std::vector<MacedPublicKey>& keysToSign, const std::vector<uint8_t>& challenge,
148*789431f2SAndroid Build Coastguard Worker std::vector<uint8_t>* csr) {
149*789431f2SAndroid Build Coastguard Worker GenerateCsrV2Request request(impl_->message_version());
150*789431f2SAndroid Build Coastguard Worker if (!request.InitKeysToSign(keysToSign.size())) {
151*789431f2SAndroid Build Coastguard Worker return km_utils::kmError2ScopedAStatus(static_cast<keymaster_error_t>(STATUS_FAILED));
152*789431f2SAndroid Build Coastguard Worker }
153*789431f2SAndroid Build Coastguard Worker for (size_t i = 0; i < keysToSign.size(); i++) {
154*789431f2SAndroid Build Coastguard Worker request.SetKeyToSign(i, keysToSign[i].macedKey.data(), keysToSign[i].macedKey.size());
155*789431f2SAndroid Build Coastguard Worker }
156*789431f2SAndroid Build Coastguard Worker request.SetChallenge(challenge.data(), challenge.size());
157*789431f2SAndroid Build Coastguard Worker GenerateCsrV2Response response(impl_->message_version());
158*789431f2SAndroid Build Coastguard Worker impl_->GenerateCsrV2(request, &response);
159*789431f2SAndroid Build Coastguard Worker
160*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) {
161*789431f2SAndroid Build Coastguard Worker return Status(-static_cast<int32_t>(response.error), "Failure in CSR v2 generation.");
162*789431f2SAndroid Build Coastguard Worker }
163*789431f2SAndroid Build Coastguard Worker *csr = km_utils::kmBlob2vector(response.csr);
164*789431f2SAndroid Build Coastguard Worker return ScopedAStatus::ok();
165*789431f2SAndroid Build Coastguard Worker }
166*789431f2SAndroid Build Coastguard Worker
167*789431f2SAndroid Build Coastguard Worker } // namespace aidl::android::hardware::security::keymint
168