• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "trusty_remote_provisioning_context.h"
18 
19 #include <assert.h>
20 #include <keymaster/cppcose/cppcose.h>
21 #include <keymaster/logger.h>
22 #include <lib/hwbcc/client/hwbcc.h>
23 #include <lib/hwkey/hwkey.h>
24 #include <lib/system_state/system_state.h>
25 #include <openssl/bn.h>
26 #include <openssl/ec.h>
27 #include <openssl/hkdf.h>
28 #include <openssl/rand.h>
29 #include <algorithm>
30 #include <cstdint>
31 
32 #include "keymaster_attributes.pb.h"
33 #include "secure_storage_manager.h"
34 
35 namespace keymaster {
36 
37 using cppcose::ALGORITHM;
38 using cppcose::constructCoseSign1;
39 using cppcose::CoseKey;
40 using cppcose::ED25519;
41 using cppcose::EDDSA;
42 using cppcose::ErrMsgOr;
43 using cppcose::OCTET_KEY_PAIR;
44 using cppcose::VERIFY;
45 
46 constexpr uint32_t kMacKeyLength = 32;
47 constexpr uint32_t kRkpVersion = TRUSTY_KM_RKP_VERSION;
48 
49 static const uint8_t kMasterKeyDerivationData[kMacKeyLength] =
50         "RemoteKeyProvisioningMasterKey";
51 
DeriveBytesFromHbk(const std::string & context,size_t num_bytes) const52 std::vector<uint8_t> TrustyRemoteProvisioningContext::DeriveBytesFromHbk(
53         const std::string& context,
54         size_t num_bytes) const {
55     long rc = hwkey_open();
56     if (rc < 0) {
57         LOG_S("Couldn't open hwkey session: %ld", rc);
58         return {};
59     }
60 
61     hwkey_session_t session = static_cast<hwkey_session_t>(rc);
62     std::array<uint8_t, kMacKeyLength> hw_backed_key;
63 
64     uint32_t kdf_version = HWKEY_KDF_VERSION_1;
65     rc = hwkey_derive(session, &kdf_version, kMasterKeyDerivationData,
66                       hw_backed_key.data(), kMacKeyLength);
67 
68     if (rc < 0) {
69         LOG_S("Error deriving master key: %ld", rc);
70         return {};
71     }
72 
73     hwkey_close(session);
74 
75     std::vector<uint8_t> result(num_bytes);
76 
77     // TODO: Figure out if HKDF can fail.  It doesn't seem like it should be
78     // able to, but the function does return an error code.
79     HKDF(result.data(), num_bytes,                    //
80          EVP_sha256(),                                //
81          hw_backed_key.data(), hw_backed_key.size(),  //
82          nullptr /* salt */, 0 /* salt len */,        //
83          reinterpret_cast<const uint8_t*>(context.data()), context.size());
84 
85     return result;
86 }
87 
ReadAttestationIds(AttestationIds * ids)88 keymaster_error_t ReadAttestationIds(AttestationIds* ids) {
89     SecureStorageManager* ss_manager = SecureStorageManager::get_instance();
90     if (ss_manager == nullptr) {
91         LOG_E("Failed to open secure storage session.");
92         return KM_ERROR_SECURE_HW_BUSY;
93     }
94 
95     auto err = ss_manager->ReadAttestationIds(ids);
96     if (err != KM_ERROR_OK) {
97         LOG_E("Failed to read attestation IDs");
98         return err;
99     }
100     return KM_ERROR_OK;
101 }
102 
103 #define ADD_ID_FIELD(array, proto, field_name)                              \
104     if ((proto).size > 0) {                                                 \
105         (array)->add(                                                       \
106                 (field_name),                                               \
107                 cppbor::Tstr((proto).bytes, (proto).bytes + (proto).size)); \
108     }
109 
CreateDeviceInfo(uint32_t csrVersion) const110 std::unique_ptr<cppbor::Map> TrustyRemoteProvisioningContext::CreateDeviceInfo(
111         uint32_t csrVersion) const {
112     auto result = std::make_unique<cppbor::Map>();
113     AttestationIds ids;
114     if (ReadAttestationIds(&ids) != KM_ERROR_OK) {
115         return result;
116     }
117     ADD_ID_FIELD(result, ids.brand, "brand")
118     ADD_ID_FIELD(result, ids.manufacturer, "manufacturer")
119     ADD_ID_FIELD(result, ids.product, "product")
120     ADD_ID_FIELD(result, ids.model, "model")
121     ADD_ID_FIELD(result, ids.device, "device")
122     if (bootParams_) {
123         // KM validated device_locked and verified_boot_state combinations, so
124         // there is no need to re-validate here.
125         switch (bootParams_->verified_boot_state) {
126         case KM_VERIFIED_BOOT_VERIFIED:
127             result->add("vb_state", "green");
128             break;
129         case KM_VERIFIED_BOOT_SELF_SIGNED:
130             result->add("vb_state", "yellow");
131             break;
132         case KM_VERIFIED_BOOT_UNVERIFIED:
133             result->add("vb_state", "orange");
134             break;
135         default:
136             break;
137         }
138         result->add("bootloader_state",
139                     bootParams_->device_locked ? "locked" : "unlocked");
140         result->add("vbmeta_digest",
141                     cppbor::Bstr(bootParams_->verified_boot_hash.begin(),
142                                  bootParams_->verified_boot_hash.end()));
143         result->add("os_version", std::to_string(bootParams_->boot_os_version));
144         result->add("system_patch_level",
145                     cppbor::Uint(bootParams_->boot_os_patchlevel));
146         result->add("boot_patch_level", cppbor::Uint(boot_patchlevel_));
147         result->add("vendor_patch_level", cppbor::Uint(vendor_patchlevel_));
148         result->add("fused", system_state_get_flag_default(
149                                      SYSTEM_STATE_FLAG_APP_LOADING_UNLOCKED,
150                                      0 /* default */)
151                                      ? 0
152                                      : 1);
153         result->add("security_level", "tee");
154         // "version" field was removed from DeviceInfo in CSR v3.
155         if (csrVersion < 3) {
156             result->add("version", csrVersion);
157         }
158     }
159 
160     result->canonicalize();
161     return result;
162 }
163 
164 cppcose::ErrMsgOr<std::vector<uint8_t>>
BuildProtectedDataPayload(bool testMode,const std::vector<uint8_t> & macKey,const std::vector<uint8_t> & aad) const165 TrustyRemoteProvisioningContext::BuildProtectedDataPayload(
166         bool testMode,
167         const std::vector<uint8_t>& macKey,
168         const std::vector<uint8_t>& aad) const {
169     std::vector<uint8_t> signedOutput(HWBCC_MAX_RESP_PAYLOAD_SIZE);
170     std::vector<uint8_t> bcc(HWBCC_MAX_RESP_PAYLOAD_SIZE);
171     size_t actualBccSize = 0;
172     size_t actualSignedMacKeySize = 0;
173     int rc = hwbcc_get_protected_data(
174             testMode, EDDSA, macKey.data(), macKey.size(), aad.data(),
175             aad.size(), signedOutput.data(), signedOutput.size(),
176             &actualSignedMacKeySize, bcc.data(), bcc.size(), &actualBccSize);
177     if (rc != 0) {
178         LOG_E("Error: [%d] Failed to sign the MAC key on WHI", rc);
179         return "Failed to sign the MAC key on WHI";
180     }
181     signedOutput.resize(actualSignedMacKeySize);
182     bcc.resize(actualBccSize);
183     return cppbor::Array()
184             .add(cppbor::EncodedItem(std::move(signedOutput)))
185             .add(cppbor::EncodedItem(std::move(bcc)))
186             .encode();
187 }
188 
189 std::optional<cppcose::HmacSha256>
GenerateHmacSha256(const cppcose::bytevec & input) const190 TrustyRemoteProvisioningContext::GenerateHmacSha256(
191         const cppcose::bytevec& input) const {
192     auto key = DeriveBytesFromHbk("Key to MAC public keys", kMacKeyLength);
193     auto result = cppcose::generateHmacSha256(key, input);
194     if (!result) {
195         LOG_E("Error signing MAC: %s", result.message().c_str());
196         return std::nullopt;
197     }
198     return *result;
199 }
200 
GetHwInfo(GetHwInfoResponse * hwInfo) const201 void TrustyRemoteProvisioningContext::GetHwInfo(
202         GetHwInfoResponse* hwInfo) const {
203     hwInfo->version = kRkpVersion;
204     hwInfo->rpcAuthorName = "Google";
205     hwInfo->supportedEekCurve =
206             kRkpVersion >= 3 ? 0 /* CURVE_NONE */ : 2 /* CURVE_25519 */;
207     hwInfo->uniqueId = "Google Trusty Implementation";
208     hwInfo->supportedNumKeysInCsr = 20;
209 }
210 
BuildCsr(const std::vector<uint8_t> & challenge,cppbor::Array keysToSign) const211 cppcose::ErrMsgOr<cppbor::Array> TrustyRemoteProvisioningContext::BuildCsr(
212         const std::vector<uint8_t>& challenge,
213         cppbor::Array keysToSign) const {
214     uint32_t csrVersion = 3;
215     auto deviceInfo = std::move(*CreateDeviceInfo(csrVersion));
216     auto csrPayload = cppbor::Array()
217                               .add(csrVersion)
218                               .add("keymint" /* CertificateType */)
219                               .add(std::move(deviceInfo))
220                               .add(std::move(keysToSign))
221                               .encode();
222     auto signedDataPayload = cppbor::Array()
223                                      .add(challenge)
224                                      .add(cppbor::Bstr(csrPayload))
225                                      .encode();
226 
227     std::vector<uint8_t> signedData(HWBCC_MAX_RESP_PAYLOAD_SIZE);
228     std::vector<uint8_t> bcc(HWBCC_MAX_RESP_PAYLOAD_SIZE);
229     size_t actualSignedDataSize = 0;
230     size_t actualBccSize = 0;
231 
232     int rc = hwbcc_get_protected_data(
233             false /* test_mode */, EDDSA, signedDataPayload.data(),
234             signedDataPayload.size(), NULL, 0, signedData.data(),
235             signedData.size(), &actualSignedDataSize, bcc.data(), bcc.size(),
236             &actualBccSize);
237     if (rc != 0) {
238         LOG_E("Error: [%d] Failed hwbcc_get_protected_data()", rc);
239         return "Failed hwbcc_get_protected_data";
240     }
241     signedData.resize(actualSignedDataSize);
242     bcc.resize(actualBccSize);
243 
244     return cppbor::Array()
245             .add(1 /* version */)
246             .add(cppbor::Map() /* UdsCerts */)
247             .add(cppbor::EncodedItem(std::move(bcc)))
248             .add(cppbor::EncodedItem(std::move(signedData)));
249 }
250 
SetBootParams(const BootParams * bootParams)251 void TrustyRemoteProvisioningContext::SetBootParams(
252         const BootParams* bootParams) {
253     if (bootParamsSet_) {
254         LOG_E("Boot parameters are already set in the remote provisioning context");
255     }
256     bootParamsSet_ = true;
257     bootParams_ = bootParams;
258 }
259 
260 }  // namespace keymaster
261