1 /*
2 * Copyright 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 #define LOG_TAG "javacard.keymint.device.rkp.strongbox-impl"
18
19 #include "JavacardRemotelyProvisionedComponentDevice.h"
20
21 #include <aidl/android/hardware/security/keymint/MacedPublicKey.h>
22
23 #include <KeyMintUtils.h>
24 #include <android-base/logging.h>
25 #include <keymaster/cppcose/cppcose.h>
26 #include <keymaster/remote_provisioning_utils.h>
27
28 namespace aidl::android::hardware::security::keymint {
29 using cppbor::Array;
30 using cppbor::EncodedItem;
31 using cppcose::kCoseMac0EntryCount;
32 using cppcose::kCoseMac0Payload;
33 using ::keymint::javacard::Instruction;
34 using std::string;
35
36 // RKP error codes defined in keymint applet.
37 constexpr int32_t kStatusFailed = 32000;
38 constexpr int32_t kStatusInvalidMac = 32001;
39 constexpr int32_t kStatusProductionKeyInTestRequest = 32002;
40 constexpr int32_t kStatusTestKeyInProductionRequest = 32003;
41 constexpr int32_t kStatusInvalidEek = 32004;
42 constexpr int32_t kStatusInvalidState = 32005;
43
44 namespace {
45
translateRkpErrorCode(keymaster_error_t error)46 keymaster_error_t translateRkpErrorCode(keymaster_error_t error) {
47 switch (static_cast<int32_t>(-error)) {
48 case kStatusFailed:
49 case kStatusInvalidState:
50 return static_cast<keymaster_error_t>(BnRemotelyProvisionedComponent::STATUS_FAILED);
51 case kStatusInvalidMac:
52 return static_cast<keymaster_error_t>(BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
53 case kStatusProductionKeyInTestRequest:
54 return static_cast<keymaster_error_t>(
55 BnRemotelyProvisionedComponent::STATUS_PRODUCTION_KEY_IN_TEST_REQUEST);
56 case kStatusTestKeyInProductionRequest:
57 return static_cast<keymaster_error_t>(
58 BnRemotelyProvisionedComponent::STATUS_TEST_KEY_IN_PRODUCTION_REQUEST);
59 case kStatusInvalidEek:
60 return static_cast<keymaster_error_t>(BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
61 }
62 return error;
63 }
64
defaultHwInfo(RpcHardwareInfo * info)65 ScopedAStatus defaultHwInfo(RpcHardwareInfo* info) {
66 info->versionNumber = 3;
67 info->rpcAuthorName = "Google";
68 info->supportedEekCurve = RpcHardwareInfo::CURVE_NONE;
69 info->uniqueId = "Google Strongbox KeyMint 3";
70 info->supportedNumKeysInCsr = RpcHardwareInfo::MIN_SUPPORTED_NUM_KEYS_IN_CSR;
71 return ScopedAStatus::ok();
72 }
73
coseKeyEncodedSize(const std::vector<MacedPublicKey> & keysToSign)74 uint32_t coseKeyEncodedSize(const std::vector<MacedPublicKey>& keysToSign) {
75 uint32_t size = 0;
76 for (auto& macKey : keysToSign) {
77 auto [macedKeyItem, _, coseMacErrMsg] = cppbor::parse(macKey.macedKey);
78 if (!macedKeyItem || !macedKeyItem->asArray() ||
79 macedKeyItem->asArray()->size() != kCoseMac0EntryCount) {
80 LOG(ERROR) << "Invalid COSE_Mac0 structure";
81 return 0;
82 }
83 auto payload = macedKeyItem->asArray()->get(kCoseMac0Payload)->asBstr();
84 if (!payload) return 0;
85 size += payload->value().size();
86 }
87 return size;
88 }
89
90 } // namespace
91
getHardwareInfo(RpcHardwareInfo * info)92 ScopedAStatus JavacardRemotelyProvisionedComponentDevice::getHardwareInfo(RpcHardwareInfo* info) {
93 auto [item, err] = card_->sendRequest(Instruction::INS_GET_RKP_HARDWARE_INFO);
94 std::optional<uint64_t> optVersionNumber;
95 std::optional<uint64_t> optSupportedEekCurve;
96 std::optional<string> optRpcAuthorName;
97 std::optional<string> optUniqueId;
98 std::optional<uint64_t> optMinSupportedKeysInCsr;
99 if (err != KM_ERROR_OK || !(optVersionNumber = cbor_.getUint64(item, 1)) ||
100 !(optRpcAuthorName = cbor_.getByteArrayStr(item, 2)) ||
101 !(optSupportedEekCurve = cbor_.getUint64(item, 3)) ||
102 !(optUniqueId = cbor_.getByteArrayStr(item, 4)) ||
103 !(optMinSupportedKeysInCsr = cbor_.getUint64(item, 5))) {
104 LOG(ERROR) << "Error in response of getHardwareInfo.";
105 LOG(INFO) << "Returning defaultHwInfo in getHardwareInfo.";
106 return defaultHwInfo(info);
107 }
108 info->rpcAuthorName = std::move(optRpcAuthorName.value());
109 info->versionNumber = static_cast<int32_t>(std::move(optVersionNumber.value()));
110 info->supportedEekCurve = static_cast<int32_t>(std::move(optSupportedEekCurve.value()));
111 info->uniqueId = std::move(optUniqueId.value());
112 info->supportedNumKeysInCsr = static_cast<int32_t>(std::move(optMinSupportedKeysInCsr.value()));
113 return ScopedAStatus::ok();
114 }
115
generateEcdsaP256KeyPair(bool testMode,MacedPublicKey * macedPublicKey,std::vector<uint8_t> * privateKeyHandle)116 ScopedAStatus JavacardRemotelyProvisionedComponentDevice::generateEcdsaP256KeyPair(
117 bool testMode, MacedPublicKey* macedPublicKey, std::vector<uint8_t>* privateKeyHandle) {
118 if (testMode) {
119 return km_utils::kmError2ScopedAStatus(static_cast<keymaster_error_t>(STATUS_REMOVED));
120 }
121 auto [item, err] = card_->sendRequest(Instruction::INS_GENERATE_RKP_KEY_CMD);
122 if (err != KM_ERROR_OK) {
123 LOG(ERROR) << "Error in sending generateEcdsaP256KeyPair.";
124 return km_utils::kmError2ScopedAStatus(translateRkpErrorCode(err));
125 }
126 std::optional<std::vector<uint8_t>> optMacedKey;
127 std::optional<std::vector<uint8_t>> optPKeyHandle;
128 if (!(optMacedKey = cbor_.getByteArrayVec(item, 1)) ||
129 !(optPKeyHandle = cbor_.getByteArrayVec(item, 2))) {
130 LOG(ERROR) << "Error in decoding the response in generateEcdsaP256KeyPair.";
131 return km_utils::kmError2ScopedAStatus(KM_ERROR_UNKNOWN_ERROR);
132 }
133 *privateKeyHandle = std::move(optPKeyHandle.value());
134 macedPublicKey->macedKey = std::move(optMacedKey.value());
135 return ScopedAStatus::ok();
136 }
137
beginSendData(const std::vector<MacedPublicKey> & keysToSign,const std::vector<uint8_t> & challenge,DeviceInfo * deviceInfo,uint32_t * version,std::string * certificateType)138 ScopedAStatus JavacardRemotelyProvisionedComponentDevice::beginSendData(
139 const std::vector<MacedPublicKey>& keysToSign, const std::vector<uint8_t>& challenge,
140 DeviceInfo* deviceInfo, uint32_t* version, std::string* certificateType) {
141 uint32_t totalEncodedSize = coseKeyEncodedSize(keysToSign);
142 cppbor::Array array;
143 array.add(keysToSign.size());
144 array.add(totalEncodedSize);
145 array.add(challenge);
146 auto [item, err] = card_->sendRequest(Instruction::INS_BEGIN_SEND_DATA_CMD, array);
147 if (err != KM_ERROR_OK) {
148 LOG(ERROR) << "Error in beginSendData.";
149 return km_utils::kmError2ScopedAStatus(translateRkpErrorCode(err));
150 }
151 auto optDecodedDeviceInfo = cbor_.getByteArrayVec(item, 1);
152 if (!optDecodedDeviceInfo) {
153 LOG(ERROR) << "Error in decoding deviceInfo response in beginSendData.";
154 return km_utils::kmError2ScopedAStatus(KM_ERROR_UNKNOWN_ERROR);
155 }
156 deviceInfo->deviceInfo = std::move(optDecodedDeviceInfo.value());
157 auto optVersion = cbor_.getUint64(item, 2);
158 if (!optVersion) {
159 LOG(ERROR) << "Error in decoding version in beginSendData.";
160 return km_utils::kmError2ScopedAStatus(KM_ERROR_UNKNOWN_ERROR);
161 }
162 *version = optVersion.value();
163 auto optCertType = cbor_.getTextStr(item, 3);
164 if (!optCertType) {
165 LOG(ERROR) << "Error in decoding cert type in beginSendData.";
166 return km_utils::kmError2ScopedAStatus(KM_ERROR_UNKNOWN_ERROR);
167 }
168 *certificateType = std::move(optCertType.value());
169 return ScopedAStatus::ok();
170 }
171
updateMacedKey(const std::vector<MacedPublicKey> & keysToSign,Array & coseKeys)172 ScopedAStatus JavacardRemotelyProvisionedComponentDevice::updateMacedKey(
173 const std::vector<MacedPublicKey>& keysToSign, Array& coseKeys) {
174 for (auto& macedPublicKey : keysToSign) {
175 cppbor::Array array;
176 array.add(EncodedItem(macedPublicKey.macedKey));
177 auto [item, err] = card_->sendRequest(Instruction::INS_UPDATE_KEY_CMD, array);
178 if (err != KM_ERROR_OK) {
179 LOG(ERROR) << "Error in updateMacedKey.";
180 return km_utils::kmError2ScopedAStatus(translateRkpErrorCode(err));
181 }
182 auto coseKeyData = cbor_.getByteArrayVec(item, 1);
183 coseKeys.add(EncodedItem(coseKeyData.value()));
184 }
185 return ScopedAStatus::ok();
186 }
187
finishSendData(std::vector<uint8_t> & coseEncryptProtectedHeader,std::vector<uint8_t> & signature,uint32_t & version,uint32_t & respFlag)188 ScopedAStatus JavacardRemotelyProvisionedComponentDevice::finishSendData(
189 std::vector<uint8_t>& coseEncryptProtectedHeader, std::vector<uint8_t>& signature,
190 uint32_t& version, uint32_t& respFlag) {
191 auto [item, err] = card_->sendRequest(Instruction::INS_FINISH_SEND_DATA_CMD);
192 if (err != KM_ERROR_OK) {
193 LOG(ERROR) << "Error in finishSendData.";
194 return km_utils::kmError2ScopedAStatus(translateRkpErrorCode(err));
195 }
196 auto optCEncryptProtectedHeader = cbor_.getByteArrayVec(item, 1);
197 auto optSignature = cbor_.getByteArrayVec(item, 2);
198 auto optVersion = cbor_.getUint64(item, 3);
199 auto optRespFlag = cbor_.getUint64(item, 4);
200 if (!optCEncryptProtectedHeader || !optSignature || !optVersion || !optRespFlag) {
201 LOG(ERROR) << "Error in decoding response in finishSendData.";
202 return km_utils::kmError2ScopedAStatus(KM_ERROR_UNKNOWN_ERROR);
203 }
204
205 coseEncryptProtectedHeader = std::move(optCEncryptProtectedHeader.value());
206 signature.insert(signature.end(), optSignature->begin(), optSignature->end());
207 version = std::move(optVersion.value());
208 respFlag = std::move(optRespFlag.value());
209 return ScopedAStatus::ok();
210 }
211
212 ScopedAStatus
getDiceCertChain(std::vector<uint8_t> & diceCertChain)213 JavacardRemotelyProvisionedComponentDevice::getDiceCertChain(std::vector<uint8_t>& diceCertChain) {
214 uint32_t respFlag = 0;
215 do {
216 auto [item, err] = card_->sendRequest(Instruction::INS_GET_DICE_CERT_CHAIN_CMD);
217 if (err != KM_ERROR_OK) {
218 LOG(ERROR) << "Error in getDiceCertChain.";
219 return km_utils::kmError2ScopedAStatus(translateRkpErrorCode(err));
220 }
221 auto optDiceCertChain = cbor_.getByteArrayVec(item, 1);
222 auto optRespFlag = cbor_.getUint64(item, 2);
223 if (!optDiceCertChain || !optRespFlag) {
224 LOG(ERROR) << "Error in decoding response in getDiceCertChain.";
225 return km_utils::kmError2ScopedAStatus(KM_ERROR_UNKNOWN_ERROR);
226 }
227 respFlag = optRespFlag.value();
228 diceCertChain.insert(diceCertChain.end(), optDiceCertChain->begin(),
229 optDiceCertChain->end());
230 } while (respFlag != 0);
231 return ScopedAStatus::ok();
232 }
233
234 ScopedAStatus
getUdsCertsChain(std::vector<uint8_t> & udsCertsChain)235 JavacardRemotelyProvisionedComponentDevice::getUdsCertsChain(std::vector<uint8_t>& udsCertsChain) {
236 uint32_t respFlag = 0;
237 do {
238 auto [item, err] = card_->sendRequest(Instruction::INS_GET_UDS_CERTS_CMD);
239 if (err != KM_ERROR_OK) {
240 LOG(ERROR) << "Error in getUdsCertsChain.";
241 return km_utils::kmError2ScopedAStatus(translateRkpErrorCode(err));
242 }
243 auto optUdsCertData = cbor_.getByteArrayVec(item, 1);
244 auto optRespFlag = cbor_.getUint64(item, 2);
245 if (!optUdsCertData || !optRespFlag) {
246 LOG(ERROR) << "Error in decoding og response in getUdsCertsChain.";
247 return km_utils::kmError2ScopedAStatus(KM_ERROR_UNKNOWN_ERROR);
248 }
249 respFlag = optRespFlag.value();
250 udsCertsChain.insert(udsCertsChain.end(), optUdsCertData->begin(), optUdsCertData->end());
251 } while (respFlag != 0);
252 return ScopedAStatus::ok();
253 }
254
generateCertificateRequest(bool,const std::vector<MacedPublicKey> &,const std::vector<uint8_t> &,const std::vector<uint8_t> &,DeviceInfo *,ProtectedData *,std::vector<uint8_t> *)255 ScopedAStatus JavacardRemotelyProvisionedComponentDevice::generateCertificateRequest(
256 bool, const std::vector<MacedPublicKey>&, const std::vector<uint8_t>&,
257 const std::vector<uint8_t>&, DeviceInfo*, ProtectedData*, std::vector<uint8_t>*) {
258 return km_utils::kmError2ScopedAStatus(static_cast<keymaster_error_t>(STATUS_REMOVED));
259 }
260
generateCertificateRequestV2(const std::vector<MacedPublicKey> & keysToSign,const std::vector<uint8_t> & challenge,std::vector<uint8_t> * csr)261 ScopedAStatus JavacardRemotelyProvisionedComponentDevice::generateCertificateRequestV2(
262 const std::vector<MacedPublicKey>& keysToSign, const std::vector<uint8_t>& challenge,
263 std::vector<uint8_t>* csr) {
264 uint32_t version;
265 uint32_t csrPayloadSchemaVersion;
266 std::string certificateType;
267 uint32_t respFlag;
268 DeviceInfo deviceInfo;
269 Array coseKeys;
270 std::vector<uint8_t> protectedHeader;
271 cppbor::Map coseEncryptUnProtectedHeader;
272 std::vector<uint8_t> signature;
273 std::vector<uint8_t> diceCertChain;
274 std::vector<uint8_t> udsCertChain;
275 cppbor::Array payLoad;
276
277 auto ret = beginSendData(keysToSign, challenge, &deviceInfo, &csrPayloadSchemaVersion,
278 &certificateType);
279 if (!ret.isOk()) return ret;
280
281 ret = updateMacedKey(keysToSign, coseKeys);
282 if (!ret.isOk()) return ret;
283
284 ret = finishSendData(protectedHeader, signature, version, respFlag);
285 if (!ret.isOk()) return ret;
286
287 ret = getUdsCertsChain(udsCertChain);
288 if (!ret.isOk()) return ret;
289
290 ret = getDiceCertChain(diceCertChain);
291 if (!ret.isOk()) return ret;
292
293 auto payload = cppbor::Array()
294 .add(csrPayloadSchemaVersion)
295 .add(certificateType)
296 .add(EncodedItem(deviceInfo.deviceInfo)) // deviceinfo
297 .add(std::move(coseKeys)) // KeysToSign
298 .encode();
299
300 auto signDataPayload = cppbor::Array()
301 .add(challenge) // Challenge
302 .add(std::move(payload))
303 .encode();
304
305 auto signedData = cppbor::Array()
306 .add(std::move(protectedHeader))
307 .add(cppbor::Map() /* unprotected parameters */)
308 .add(std::move(signDataPayload))
309 .add(std::move(signature));
310
311 *csr = cppbor::Array()
312 .add(version)
313 .add(EncodedItem(udsCertChain))
314 .add(EncodedItem(diceCertChain))
315 .add(std::move(signedData))
316 .encode();
317
318 return ScopedAStatus::ok();
319 }
320
321 } // namespace aidl::android::hardware::security::keymint
322