1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2023 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker *
4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker *
8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker *
10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker */
16*ec779b8eSAndroid Build Coastguard Worker
17*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "DrmRemotelyProvisionedComponent"
18*ec779b8eSAndroid Build Coastguard Worker #include "DrmRemotelyProvisionedComponent.h"
19*ec779b8eSAndroid Build Coastguard Worker
20*ec779b8eSAndroid Build Coastguard Worker #include <android-base/properties.h>
21*ec779b8eSAndroid Build Coastguard Worker #include <cppbor.h>
22*ec779b8eSAndroid Build Coastguard Worker #include <cppbor_parse.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <log/log.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <map>
25*ec779b8eSAndroid Build Coastguard Worker #include <string>
26*ec779b8eSAndroid Build Coastguard Worker
27*ec779b8eSAndroid Build Coastguard Worker namespace android::mediadrm {
DrmRemotelyProvisionedComponent(std::shared_ptr<IDrmPlugin> drm,std::string drmVendor,std::string drmDesc,std::vector<uint8_t> bcc,std::vector<uint8_t> bcc_signature)28*ec779b8eSAndroid Build Coastguard Worker DrmRemotelyProvisionedComponent::DrmRemotelyProvisionedComponent(std::shared_ptr<IDrmPlugin> drm,
29*ec779b8eSAndroid Build Coastguard Worker std::string drmVendor,
30*ec779b8eSAndroid Build Coastguard Worker std::string drmDesc,
31*ec779b8eSAndroid Build Coastguard Worker std::vector<uint8_t> bcc,
32*ec779b8eSAndroid Build Coastguard Worker std::vector<uint8_t> bcc_signature)
33*ec779b8eSAndroid Build Coastguard Worker : mDrm(std::move(drm)),
34*ec779b8eSAndroid Build Coastguard Worker mDrmVendor(std::move(drmVendor)),
35*ec779b8eSAndroid Build Coastguard Worker mDrmDesc(std::move(drmDesc)),
36*ec779b8eSAndroid Build Coastguard Worker mBcc(std::move(bcc)),
37*ec779b8eSAndroid Build Coastguard Worker mBccSignature(std::move(bcc_signature)) {}
38*ec779b8eSAndroid Build Coastguard Worker
getHardwareInfo(RpcHardwareInfo * info)39*ec779b8eSAndroid Build Coastguard Worker ScopedAStatus DrmRemotelyProvisionedComponent::getHardwareInfo(RpcHardwareInfo* info) {
40*ec779b8eSAndroid Build Coastguard Worker info->versionNumber = 3;
41*ec779b8eSAndroid Build Coastguard Worker info->rpcAuthorName = mDrmVendor;
42*ec779b8eSAndroid Build Coastguard Worker info->supportedEekCurve = RpcHardwareInfo::CURVE_NONE;
43*ec779b8eSAndroid Build Coastguard Worker info->supportedNumKeysInCsr = RpcHardwareInfo::MIN_SUPPORTED_NUM_KEYS_IN_CSR;
44*ec779b8eSAndroid Build Coastguard Worker info->uniqueId = mDrmDesc;
45*ec779b8eSAndroid Build Coastguard Worker return ScopedAStatus::ok();
46*ec779b8eSAndroid Build Coastguard Worker }
47*ec779b8eSAndroid Build Coastguard Worker
generateEcdsaP256KeyPair(bool,MacedPublicKey *,std::vector<uint8_t> *)48*ec779b8eSAndroid Build Coastguard Worker ScopedAStatus DrmRemotelyProvisionedComponent::generateEcdsaP256KeyPair(bool, MacedPublicKey*,
49*ec779b8eSAndroid Build Coastguard Worker std::vector<uint8_t>*) {
50*ec779b8eSAndroid Build Coastguard Worker return ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
51*ec779b8eSAndroid Build Coastguard Worker IRemotelyProvisionedComponent::STATUS_REMOVED,
52*ec779b8eSAndroid Build Coastguard Worker "generateEcdsaP256KeyPair not supported."));
53*ec779b8eSAndroid Build Coastguard Worker }
54*ec779b8eSAndroid Build Coastguard Worker
generateCertificateRequest(bool,const std::vector<MacedPublicKey> &,const std::vector<uint8_t> &,const std::vector<uint8_t> &,DeviceInfo *,ProtectedData *,std::vector<uint8_t> *)55*ec779b8eSAndroid Build Coastguard Worker ScopedAStatus DrmRemotelyProvisionedComponent::generateCertificateRequest(
56*ec779b8eSAndroid Build Coastguard Worker bool, const std::vector<MacedPublicKey>&, const std::vector<uint8_t>&,
57*ec779b8eSAndroid Build Coastguard Worker const std::vector<uint8_t>&, DeviceInfo*, ProtectedData*, std::vector<uint8_t>*) {
58*ec779b8eSAndroid Build Coastguard Worker return ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
59*ec779b8eSAndroid Build Coastguard Worker IRemotelyProvisionedComponent::STATUS_REMOVED,
60*ec779b8eSAndroid Build Coastguard Worker "generateCertificateRequest not supported."));
61*ec779b8eSAndroid Build Coastguard Worker }
62*ec779b8eSAndroid Build Coastguard Worker
getVerifiedDeviceInfo(cppbor::Map & deviceInfoMap)63*ec779b8eSAndroid Build Coastguard Worker ScopedAStatus DrmRemotelyProvisionedComponent::getVerifiedDeviceInfo(cppbor::Map& deviceInfoMap) {
64*ec779b8eSAndroid Build Coastguard Worker std::vector<uint8_t> verifiedDeviceInfo;
65*ec779b8eSAndroid Build Coastguard Worker auto status = mDrm->getPropertyByteArray("verifiedDeviceInfo", &verifiedDeviceInfo);
66*ec779b8eSAndroid Build Coastguard Worker if (!status.isOk()) {
67*ec779b8eSAndroid Build Coastguard Worker ALOGE("getPropertyByteArray verifiedDeviceInfo failed. Details: [%s].",
68*ec779b8eSAndroid Build Coastguard Worker status.getDescription().c_str());
69*ec779b8eSAndroid Build Coastguard Worker return status;
70*ec779b8eSAndroid Build Coastguard Worker }
71*ec779b8eSAndroid Build Coastguard Worker
72*ec779b8eSAndroid Build Coastguard Worker auto [parsed, _, err] = cppbor::parse(
73*ec779b8eSAndroid Build Coastguard Worker reinterpret_cast<const uint8_t*>(verifiedDeviceInfo.data()), verifiedDeviceInfo.size());
74*ec779b8eSAndroid Build Coastguard Worker
75*ec779b8eSAndroid Build Coastguard Worker if (!parsed || !parsed->asMap()) {
76*ec779b8eSAndroid Build Coastguard Worker ALOGE("Failed to parse the verified device info cbor: %s", err.c_str());
77*ec779b8eSAndroid Build Coastguard Worker return ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
78*ec779b8eSAndroid Build Coastguard Worker IRemotelyProvisionedComponent::STATUS_FAILED,
79*ec779b8eSAndroid Build Coastguard Worker "Failed to parse the verified device info cbor."));
80*ec779b8eSAndroid Build Coastguard Worker }
81*ec779b8eSAndroid Build Coastguard Worker
82*ec779b8eSAndroid Build Coastguard Worker const cppbor::Map* verifiedDeviceInfoMap = parsed->asMap();
83*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < verifiedDeviceInfoMap->size(); i++) {
84*ec779b8eSAndroid Build Coastguard Worker auto& [keyItem, valueItem] = (*verifiedDeviceInfoMap)[i];
85*ec779b8eSAndroid Build Coastguard Worker ALOGI("Found device info %s", keyItem->asTstr()->value().data());
86*ec779b8eSAndroid Build Coastguard Worker if (valueItem != nullptr && valueItem->asTstr() != nullptr &&
87*ec779b8eSAndroid Build Coastguard Worker valueItem->asTstr()->value().empty()) {
88*ec779b8eSAndroid Build Coastguard Worker ALOGI("Value is empty. Skip");
89*ec779b8eSAndroid Build Coastguard Worker continue;
90*ec779b8eSAndroid Build Coastguard Worker }
91*ec779b8eSAndroid Build Coastguard Worker deviceInfoMap.add(keyItem->clone(), valueItem->clone());
92*ec779b8eSAndroid Build Coastguard Worker }
93*ec779b8eSAndroid Build Coastguard Worker
94*ec779b8eSAndroid Build Coastguard Worker return ScopedAStatus::ok();
95*ec779b8eSAndroid Build Coastguard Worker }
96*ec779b8eSAndroid Build Coastguard Worker
getDeviceInfo(std::vector<uint8_t> * deviceInfo)97*ec779b8eSAndroid Build Coastguard Worker ScopedAStatus DrmRemotelyProvisionedComponent::getDeviceInfo(std::vector<uint8_t>* deviceInfo) {
98*ec779b8eSAndroid Build Coastguard Worker auto deviceInfoMap = cppbor::Map();
99*ec779b8eSAndroid Build Coastguard Worker auto status = getVerifiedDeviceInfo(deviceInfoMap);
100*ec779b8eSAndroid Build Coastguard Worker if (!status.isOk()) {
101*ec779b8eSAndroid Build Coastguard Worker ALOGE("getVerifiedDeviceInfo failed. Details: [%s].", status.getDescription().c_str());
102*ec779b8eSAndroid Build Coastguard Worker return status;
103*ec779b8eSAndroid Build Coastguard Worker }
104*ec779b8eSAndroid Build Coastguard Worker const std::map<std::string, std::string> keyToProp{{"brand", "ro.product.brand"},
105*ec779b8eSAndroid Build Coastguard Worker {"manufacturer", "ro.product.manufacturer"},
106*ec779b8eSAndroid Build Coastguard Worker {"model", "ro.product.model"},
107*ec779b8eSAndroid Build Coastguard Worker {"device", "ro.product.device"},
108*ec779b8eSAndroid Build Coastguard Worker {"product", "ro.product.name"}};
109*ec779b8eSAndroid Build Coastguard Worker for (auto i : keyToProp) {
110*ec779b8eSAndroid Build Coastguard Worker auto key = i.first;
111*ec779b8eSAndroid Build Coastguard Worker auto prop = i.second;
112*ec779b8eSAndroid Build Coastguard Worker const auto& val = deviceInfoMap.get(key);
113*ec779b8eSAndroid Build Coastguard Worker if (val == nullptr || val->asTstr()->value().empty()) {
114*ec779b8eSAndroid Build Coastguard Worker std::string propValue = android::base::GetProperty(prop, "");
115*ec779b8eSAndroid Build Coastguard Worker if (propValue.empty()) {
116*ec779b8eSAndroid Build Coastguard Worker ALOGE("Failed to get OS property %s", prop.c_str());
117*ec779b8eSAndroid Build Coastguard Worker return ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
118*ec779b8eSAndroid Build Coastguard Worker IRemotelyProvisionedComponent::STATUS_FAILED,
119*ec779b8eSAndroid Build Coastguard Worker "Failed to get OS property."));
120*ec779b8eSAndroid Build Coastguard Worker }
121*ec779b8eSAndroid Build Coastguard Worker deviceInfoMap.add(cppbor::Tstr(key), cppbor::Tstr(propValue));
122*ec779b8eSAndroid Build Coastguard Worker ALOGI("use OS property %s: %s", prop.c_str(), propValue.c_str());
123*ec779b8eSAndroid Build Coastguard Worker } else {
124*ec779b8eSAndroid Build Coastguard Worker ALOGI("use verified key %s: %s", key.c_str(), val->asTstr()->value().data());
125*ec779b8eSAndroid Build Coastguard Worker }
126*ec779b8eSAndroid Build Coastguard Worker }
127*ec779b8eSAndroid Build Coastguard Worker deviceInfoMap.canonicalize();
128*ec779b8eSAndroid Build Coastguard Worker *deviceInfo = deviceInfoMap.encode();
129*ec779b8eSAndroid Build Coastguard Worker return ScopedAStatus::ok();
130*ec779b8eSAndroid Build Coastguard Worker }
131*ec779b8eSAndroid Build Coastguard Worker
generateCertificateRequestV2(const std::vector<MacedPublicKey> &,const std::vector<uint8_t> & challenge,std::vector<uint8_t> * out)132*ec779b8eSAndroid Build Coastguard Worker ScopedAStatus DrmRemotelyProvisionedComponent::generateCertificateRequestV2(
133*ec779b8eSAndroid Build Coastguard Worker const std::vector<MacedPublicKey>&, const std::vector<uint8_t>& challenge,
134*ec779b8eSAndroid Build Coastguard Worker std::vector<uint8_t>* out) {
135*ec779b8eSAndroid Build Coastguard Worker // access csr input/output via setPropertyByteArray/getPropertyByteArray
136*ec779b8eSAndroid Build Coastguard Worker auto status = mDrm->setPropertyByteArray("certificateSigningRequestChallenge", challenge);
137*ec779b8eSAndroid Build Coastguard Worker if (!status.isOk()) {
138*ec779b8eSAndroid Build Coastguard Worker ALOGE("setPropertyByteArray certificateSigningRequestChallenge failed. Details: [%s].",
139*ec779b8eSAndroid Build Coastguard Worker status.getDescription().c_str());
140*ec779b8eSAndroid Build Coastguard Worker return status;
141*ec779b8eSAndroid Build Coastguard Worker }
142*ec779b8eSAndroid Build Coastguard Worker
143*ec779b8eSAndroid Build Coastguard Worker std::vector<uint8_t> deviceInfo;
144*ec779b8eSAndroid Build Coastguard Worker status = getDeviceInfo(&deviceInfo);
145*ec779b8eSAndroid Build Coastguard Worker if (!status.isOk()) {
146*ec779b8eSAndroid Build Coastguard Worker ALOGE("getDeviceInfo failed. Details: [%s].", status.getDescription().c_str());
147*ec779b8eSAndroid Build Coastguard Worker return status;
148*ec779b8eSAndroid Build Coastguard Worker }
149*ec779b8eSAndroid Build Coastguard Worker
150*ec779b8eSAndroid Build Coastguard Worker status = mDrm->setPropertyByteArray("deviceInfo", deviceInfo);
151*ec779b8eSAndroid Build Coastguard Worker if (!status.isOk()) {
152*ec779b8eSAndroid Build Coastguard Worker ALOGE("setPropertyByteArray deviceInfo failed. Details: [%s].",
153*ec779b8eSAndroid Build Coastguard Worker status.getDescription().c_str());
154*ec779b8eSAndroid Build Coastguard Worker return status;
155*ec779b8eSAndroid Build Coastguard Worker }
156*ec779b8eSAndroid Build Coastguard Worker
157*ec779b8eSAndroid Build Coastguard Worker std::vector<uint8_t> deviceSignedCsrPayload;
158*ec779b8eSAndroid Build Coastguard Worker status = mDrm->getPropertyByteArray("deviceSignedCsrPayload", &deviceSignedCsrPayload);
159*ec779b8eSAndroid Build Coastguard Worker if (!status.isOk()) {
160*ec779b8eSAndroid Build Coastguard Worker ALOGE("getPropertyByteArray deviceSignedCsrPayload failed. Details: [%s].",
161*ec779b8eSAndroid Build Coastguard Worker status.getDescription().c_str());
162*ec779b8eSAndroid Build Coastguard Worker return status;
163*ec779b8eSAndroid Build Coastguard Worker }
164*ec779b8eSAndroid Build Coastguard Worker
165*ec779b8eSAndroid Build Coastguard Worker // assemble AuthenticatedRequest (definition in IRemotelyProvisionedComponent.aidl)
166*ec779b8eSAndroid Build Coastguard Worker cppbor::Array request_array = cppbor::Array().add(1 /* version */);
167*ec779b8eSAndroid Build Coastguard Worker if (!mBccSignature.empty()) {
168*ec779b8eSAndroid Build Coastguard Worker request_array.add(cppbor::EncodedItem(mBccSignature) /* UdsCerts */);
169*ec779b8eSAndroid Build Coastguard Worker } else {
170*ec779b8eSAndroid Build Coastguard Worker request_array.add(cppbor::Map() /* empty UdsCerts */);
171*ec779b8eSAndroid Build Coastguard Worker }
172*ec779b8eSAndroid Build Coastguard Worker request_array.add(cppbor::EncodedItem(mBcc))
173*ec779b8eSAndroid Build Coastguard Worker .add(cppbor::EncodedItem(std::move(deviceSignedCsrPayload)));
174*ec779b8eSAndroid Build Coastguard Worker *out = request_array.encode();
175*ec779b8eSAndroid Build Coastguard Worker
176*ec779b8eSAndroid Build Coastguard Worker return ScopedAStatus::ok();
177*ec779b8eSAndroid Build Coastguard Worker }
178*ec779b8eSAndroid Build Coastguard Worker } // namespace android::mediadrm