xref: /aosp_15_r20/system/keymaster/ng/AndroidRemotelyProvisionedComponentDevice.cpp (revision 789431f29546679ab5188a97751fb38e3018d44d)
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