1*789431f2SAndroid Build Coastguard Worker /*
2*789431f2SAndroid Build Coastguard Worker * Copyright 2015 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 <keymaster/contexts/pure_soft_keymaster_context.h>
18*789431f2SAndroid Build Coastguard Worker
19*789431f2SAndroid Build Coastguard Worker #include <assert.h>
20*789431f2SAndroid Build Coastguard Worker #include <memory>
21*789431f2SAndroid Build Coastguard Worker #include <utility>
22*789431f2SAndroid Build Coastguard Worker
23*789431f2SAndroid Build Coastguard Worker #include <openssl/aes.h>
24*789431f2SAndroid Build Coastguard Worker #include <openssl/evp.h>
25*789431f2SAndroid Build Coastguard Worker #include <openssl/hmac.h>
26*789431f2SAndroid Build Coastguard Worker #include <openssl/rand.h>
27*789431f2SAndroid Build Coastguard Worker #include <openssl/sha.h>
28*789431f2SAndroid Build Coastguard Worker #include <openssl/x509v3.h>
29*789431f2SAndroid Build Coastguard Worker
30*789431f2SAndroid Build Coastguard Worker #include <keymaster/android_keymaster_utils.h>
31*789431f2SAndroid Build Coastguard Worker #include <keymaster/key_blob_utils/auth_encrypted_key_blob.h>
32*789431f2SAndroid Build Coastguard Worker #include <keymaster/key_blob_utils/integrity_assured_key_blob.h>
33*789431f2SAndroid Build Coastguard Worker #include <keymaster/key_blob_utils/ocb_utils.h>
34*789431f2SAndroid Build Coastguard Worker #include <keymaster/key_blob_utils/software_keyblobs.h>
35*789431f2SAndroid Build Coastguard Worker #include <keymaster/km_openssl/aes_key.h>
36*789431f2SAndroid Build Coastguard Worker #include <keymaster/km_openssl/asymmetric_key.h>
37*789431f2SAndroid Build Coastguard Worker #include <keymaster/km_openssl/attestation_utils.h>
38*789431f2SAndroid Build Coastguard Worker #include <keymaster/km_openssl/certificate_utils.h>
39*789431f2SAndroid Build Coastguard Worker #include <keymaster/km_openssl/ec_key_factory.h>
40*789431f2SAndroid Build Coastguard Worker #include <keymaster/km_openssl/hmac_key.h>
41*789431f2SAndroid Build Coastguard Worker #include <keymaster/km_openssl/openssl_err.h>
42*789431f2SAndroid Build Coastguard Worker #include <keymaster/km_openssl/openssl_utils.h>
43*789431f2SAndroid Build Coastguard Worker #include <keymaster/km_openssl/rsa_key_factory.h>
44*789431f2SAndroid Build Coastguard Worker #include <keymaster/km_openssl/soft_keymaster_enforcement.h>
45*789431f2SAndroid Build Coastguard Worker #include <keymaster/km_openssl/triple_des_key.h>
46*789431f2SAndroid Build Coastguard Worker #include <keymaster/logger.h>
47*789431f2SAndroid Build Coastguard Worker #include <keymaster/operation.h>
48*789431f2SAndroid Build Coastguard Worker #include <keymaster/wrapped_key.h>
49*789431f2SAndroid Build Coastguard Worker
50*789431f2SAndroid Build Coastguard Worker #include <keymaster/contexts/soft_attestation_cert.h>
51*789431f2SAndroid Build Coastguard Worker
52*789431f2SAndroid Build Coastguard Worker namespace keymaster {
53*789431f2SAndroid Build Coastguard Worker
PureSoftKeymasterContext(KmVersion version,keymaster_security_level_t security_level)54*789431f2SAndroid Build Coastguard Worker PureSoftKeymasterContext::PureSoftKeymasterContext(KmVersion version,
55*789431f2SAndroid Build Coastguard Worker keymaster_security_level_t security_level)
56*789431f2SAndroid Build Coastguard Worker
57*789431f2SAndroid Build Coastguard Worker : SoftAttestationContext(version),
58*789431f2SAndroid Build Coastguard Worker rsa_factory_(new (std::nothrow) RsaKeyFactory(*this /* blob_maker */, *this /* context */)),
59*789431f2SAndroid Build Coastguard Worker ec_factory_(new (std::nothrow) EcKeyFactory(*this /* blob_maker */, *this /* context */)),
60*789431f2SAndroid Build Coastguard Worker aes_factory_(new (std::nothrow)
61*789431f2SAndroid Build Coastguard Worker AesKeyFactory(*this /* blob_maker */, *this /* random_source */)),
62*789431f2SAndroid Build Coastguard Worker tdes_factory_(new (std::nothrow)
63*789431f2SAndroid Build Coastguard Worker TripleDesKeyFactory(*this /* blob_maker */, *this /* random_source */)),
64*789431f2SAndroid Build Coastguard Worker hmac_factory_(new (std::nothrow)
65*789431f2SAndroid Build Coastguard Worker HmacKeyFactory(*this /* blob_maker */, *this /* random_source */)),
66*789431f2SAndroid Build Coastguard Worker os_version_(0), os_patchlevel_(0), soft_keymaster_enforcement_(64, 64),
67*789431f2SAndroid Build Coastguard Worker security_level_(security_level) {
68*789431f2SAndroid Build Coastguard Worker // We're pretending to be some sort of secure hardware which supports secure key storage,
69*789431f2SAndroid Build Coastguard Worker // this must only be used for testing.
70*789431f2SAndroid Build Coastguard Worker if (security_level != KM_SECURITY_LEVEL_SOFTWARE) {
71*789431f2SAndroid Build Coastguard Worker pure_soft_secure_key_storage_ = std::make_unique<PureSoftSecureKeyStorage>(64);
72*789431f2SAndroid Build Coastguard Worker }
73*789431f2SAndroid Build Coastguard Worker if (version >= KmVersion::KEYMINT_1) {
74*789431f2SAndroid Build Coastguard Worker pure_soft_remote_provisioning_context_ =
75*789431f2SAndroid Build Coastguard Worker std::make_unique<PureSoftRemoteProvisioningContext>(security_level_);
76*789431f2SAndroid Build Coastguard Worker }
77*789431f2SAndroid Build Coastguard Worker }
78*789431f2SAndroid Build Coastguard Worker
~PureSoftKeymasterContext()79*789431f2SAndroid Build Coastguard Worker PureSoftKeymasterContext::~PureSoftKeymasterContext() {}
80*789431f2SAndroid Build Coastguard Worker
SetSystemVersion(uint32_t os_version,uint32_t os_patchlevel)81*789431f2SAndroid Build Coastguard Worker keymaster_error_t PureSoftKeymasterContext::SetSystemVersion(uint32_t os_version,
82*789431f2SAndroid Build Coastguard Worker uint32_t os_patchlevel) {
83*789431f2SAndroid Build Coastguard Worker os_version_ = os_version;
84*789431f2SAndroid Build Coastguard Worker os_patchlevel_ = os_patchlevel;
85*789431f2SAndroid Build Coastguard Worker if (pure_soft_remote_provisioning_context_ != nullptr) {
86*789431f2SAndroid Build Coastguard Worker pure_soft_remote_provisioning_context_->SetSystemVersion(os_version, os_patchlevel);
87*789431f2SAndroid Build Coastguard Worker }
88*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
89*789431f2SAndroid Build Coastguard Worker }
90*789431f2SAndroid Build Coastguard Worker
GetSystemVersion(uint32_t * os_version,uint32_t * os_patchlevel) const91*789431f2SAndroid Build Coastguard Worker void PureSoftKeymasterContext::GetSystemVersion(uint32_t* os_version,
92*789431f2SAndroid Build Coastguard Worker uint32_t* os_patchlevel) const {
93*789431f2SAndroid Build Coastguard Worker *os_version = os_version_;
94*789431f2SAndroid Build Coastguard Worker *os_patchlevel = os_patchlevel_;
95*789431f2SAndroid Build Coastguard Worker }
96*789431f2SAndroid Build Coastguard Worker
97*789431f2SAndroid Build Coastguard Worker keymaster_error_t
SetVerifiedBootInfo(std::string_view boot_state,std::string_view bootloader_state,const std::vector<uint8_t> & vbmeta_digest)98*789431f2SAndroid Build Coastguard Worker PureSoftKeymasterContext::SetVerifiedBootInfo(std::string_view boot_state,
99*789431f2SAndroid Build Coastguard Worker std::string_view bootloader_state,
100*789431f2SAndroid Build Coastguard Worker const std::vector<uint8_t>& vbmeta_digest) {
101*789431f2SAndroid Build Coastguard Worker if (verified_boot_state_.has_value() && boot_state != verified_boot_state_.value()) {
102*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_ARGUMENT;
103*789431f2SAndroid Build Coastguard Worker }
104*789431f2SAndroid Build Coastguard Worker if (bootloader_state_.has_value() && bootloader_state != bootloader_state_.value()) {
105*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_ARGUMENT;
106*789431f2SAndroid Build Coastguard Worker }
107*789431f2SAndroid Build Coastguard Worker if (vbmeta_digest_.has_value() && vbmeta_digest != vbmeta_digest_.value()) {
108*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_ARGUMENT;
109*789431f2SAndroid Build Coastguard Worker }
110*789431f2SAndroid Build Coastguard Worker verified_boot_state_ = boot_state;
111*789431f2SAndroid Build Coastguard Worker bootloader_state_ = bootloader_state;
112*789431f2SAndroid Build Coastguard Worker vbmeta_digest_ = vbmeta_digest;
113*789431f2SAndroid Build Coastguard Worker if (pure_soft_remote_provisioning_context_ != nullptr) {
114*789431f2SAndroid Build Coastguard Worker pure_soft_remote_provisioning_context_->SetVerifiedBootInfo(boot_state, bootloader_state,
115*789431f2SAndroid Build Coastguard Worker vbmeta_digest);
116*789431f2SAndroid Build Coastguard Worker }
117*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
118*789431f2SAndroid Build Coastguard Worker }
119*789431f2SAndroid Build Coastguard Worker
SetVendorPatchlevel(uint32_t vendor_patchlevel)120*789431f2SAndroid Build Coastguard Worker keymaster_error_t PureSoftKeymasterContext::SetVendorPatchlevel(uint32_t vendor_patchlevel) {
121*789431f2SAndroid Build Coastguard Worker if (vendor_patchlevel_.has_value() && vendor_patchlevel != vendor_patchlevel_.value()) {
122*789431f2SAndroid Build Coastguard Worker // Can't set patchlevel to a different value.
123*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_ARGUMENT;
124*789431f2SAndroid Build Coastguard Worker }
125*789431f2SAndroid Build Coastguard Worker vendor_patchlevel_ = vendor_patchlevel;
126*789431f2SAndroid Build Coastguard Worker if (pure_soft_remote_provisioning_context_ != nullptr) {
127*789431f2SAndroid Build Coastguard Worker pure_soft_remote_provisioning_context_->SetVendorPatchlevel(vendor_patchlevel);
128*789431f2SAndroid Build Coastguard Worker }
129*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
130*789431f2SAndroid Build Coastguard Worker }
131*789431f2SAndroid Build Coastguard Worker
SetBootPatchlevel(uint32_t boot_patchlevel)132*789431f2SAndroid Build Coastguard Worker keymaster_error_t PureSoftKeymasterContext::SetBootPatchlevel(uint32_t boot_patchlevel) {
133*789431f2SAndroid Build Coastguard Worker if (boot_patchlevel_.has_value() && boot_patchlevel != boot_patchlevel_.value()) {
134*789431f2SAndroid Build Coastguard Worker // Can't set patchlevel to a different value.
135*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_ARGUMENT;
136*789431f2SAndroid Build Coastguard Worker }
137*789431f2SAndroid Build Coastguard Worker boot_patchlevel_ = boot_patchlevel;
138*789431f2SAndroid Build Coastguard Worker if (pure_soft_remote_provisioning_context_ != nullptr) {
139*789431f2SAndroid Build Coastguard Worker pure_soft_remote_provisioning_context_->SetBootPatchlevel(boot_patchlevel);
140*789431f2SAndroid Build Coastguard Worker }
141*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
142*789431f2SAndroid Build Coastguard Worker }
143*789431f2SAndroid Build Coastguard Worker
SetModuleHash(const keymaster_blob_t & mod_hash)144*789431f2SAndroid Build Coastguard Worker keymaster_error_t PureSoftKeymasterContext::SetModuleHash(const keymaster_blob_t& mod_hash) {
145*789431f2SAndroid Build Coastguard Worker std::vector<uint8_t> module_hash(mod_hash.data, mod_hash.data + mod_hash.data_length);
146*789431f2SAndroid Build Coastguard Worker if (module_hash_.has_value()) {
147*789431f2SAndroid Build Coastguard Worker if (module_hash != module_hash_.value()) {
148*789431f2SAndroid Build Coastguard Worker // Can't set module hash to a different value.
149*789431f2SAndroid Build Coastguard Worker return KM_ERROR_MODULE_HASH_ALREADY_SET;
150*789431f2SAndroid Build Coastguard Worker } else {
151*789431f2SAndroid Build Coastguard Worker LOG_I("module hash already set, ignoring repeated attempt to set same info");
152*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
153*789431f2SAndroid Build Coastguard Worker }
154*789431f2SAndroid Build Coastguard Worker } else {
155*789431f2SAndroid Build Coastguard Worker module_hash_ = module_hash;
156*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
157*789431f2SAndroid Build Coastguard Worker }
158*789431f2SAndroid Build Coastguard Worker }
159*789431f2SAndroid Build Coastguard Worker
GetKeyFactory(keymaster_algorithm_t algorithm) const160*789431f2SAndroid Build Coastguard Worker KeyFactory* PureSoftKeymasterContext::GetKeyFactory(keymaster_algorithm_t algorithm) const {
161*789431f2SAndroid Build Coastguard Worker switch (algorithm) {
162*789431f2SAndroid Build Coastguard Worker case KM_ALGORITHM_RSA:
163*789431f2SAndroid Build Coastguard Worker return rsa_factory_.get();
164*789431f2SAndroid Build Coastguard Worker case KM_ALGORITHM_EC:
165*789431f2SAndroid Build Coastguard Worker return ec_factory_.get();
166*789431f2SAndroid Build Coastguard Worker case KM_ALGORITHM_AES:
167*789431f2SAndroid Build Coastguard Worker return aes_factory_.get();
168*789431f2SAndroid Build Coastguard Worker case KM_ALGORITHM_TRIPLE_DES:
169*789431f2SAndroid Build Coastguard Worker return tdes_factory_.get();
170*789431f2SAndroid Build Coastguard Worker case KM_ALGORITHM_HMAC:
171*789431f2SAndroid Build Coastguard Worker return hmac_factory_.get();
172*789431f2SAndroid Build Coastguard Worker default:
173*789431f2SAndroid Build Coastguard Worker return nullptr;
174*789431f2SAndroid Build Coastguard Worker }
175*789431f2SAndroid Build Coastguard Worker }
176*789431f2SAndroid Build Coastguard Worker
177*789431f2SAndroid Build Coastguard Worker static keymaster_algorithm_t supported_algorithms[] = {KM_ALGORITHM_RSA, KM_ALGORITHM_EC,
178*789431f2SAndroid Build Coastguard Worker KM_ALGORITHM_AES, KM_ALGORITHM_HMAC};
179*789431f2SAndroid Build Coastguard Worker
180*789431f2SAndroid Build Coastguard Worker const keymaster_algorithm_t*
GetSupportedAlgorithms(size_t * algorithms_count) const181*789431f2SAndroid Build Coastguard Worker PureSoftKeymasterContext::GetSupportedAlgorithms(size_t* algorithms_count) const {
182*789431f2SAndroid Build Coastguard Worker *algorithms_count = array_length(supported_algorithms);
183*789431f2SAndroid Build Coastguard Worker return supported_algorithms;
184*789431f2SAndroid Build Coastguard Worker }
185*789431f2SAndroid Build Coastguard Worker
GetOperationFactory(keymaster_algorithm_t algorithm,keymaster_purpose_t purpose) const186*789431f2SAndroid Build Coastguard Worker OperationFactory* PureSoftKeymasterContext::GetOperationFactory(keymaster_algorithm_t algorithm,
187*789431f2SAndroid Build Coastguard Worker keymaster_purpose_t purpose) const {
188*789431f2SAndroid Build Coastguard Worker KeyFactory* key_factory = GetKeyFactory(algorithm);
189*789431f2SAndroid Build Coastguard Worker if (!key_factory) return nullptr;
190*789431f2SAndroid Build Coastguard Worker return key_factory->GetOperationFactory(purpose);
191*789431f2SAndroid Build Coastguard Worker }
192*789431f2SAndroid Build Coastguard Worker
CreateKeyBlob(const AuthorizationSet & key_description,const keymaster_key_origin_t origin,const KeymasterKeyBlob & key_material,KeymasterKeyBlob * blob,AuthorizationSet * hw_enforced,AuthorizationSet * sw_enforced) const193*789431f2SAndroid Build Coastguard Worker keymaster_error_t PureSoftKeymasterContext::CreateKeyBlob(const AuthorizationSet& key_description,
194*789431f2SAndroid Build Coastguard Worker const keymaster_key_origin_t origin,
195*789431f2SAndroid Build Coastguard Worker const KeymasterKeyBlob& key_material,
196*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob* blob,
197*789431f2SAndroid Build Coastguard Worker AuthorizationSet* hw_enforced,
198*789431f2SAndroid Build Coastguard Worker AuthorizationSet* sw_enforced) const {
199*789431f2SAndroid Build Coastguard Worker // Check whether the key blob can be securely stored by pure software secure key storage.
200*789431f2SAndroid Build Coastguard Worker bool canStoreBySecureKeyStorageIfRequired = false;
201*789431f2SAndroid Build Coastguard Worker if (GetSecurityLevel() != KM_SECURITY_LEVEL_SOFTWARE &&
202*789431f2SAndroid Build Coastguard Worker pure_soft_secure_key_storage_ != nullptr) {
203*789431f2SAndroid Build Coastguard Worker pure_soft_secure_key_storage_->HasSlot(&canStoreBySecureKeyStorageIfRequired);
204*789431f2SAndroid Build Coastguard Worker }
205*789431f2SAndroid Build Coastguard Worker
206*789431f2SAndroid Build Coastguard Worker bool needStoreBySecureKeyStorage = false;
207*789431f2SAndroid Build Coastguard Worker if (key_description.GetTagValue(TAG_ROLLBACK_RESISTANCE)) {
208*789431f2SAndroid Build Coastguard Worker needStoreBySecureKeyStorage = true;
209*789431f2SAndroid Build Coastguard Worker if (!canStoreBySecureKeyStorageIfRequired) return KM_ERROR_ROLLBACK_RESISTANCE_UNAVAILABLE;
210*789431f2SAndroid Build Coastguard Worker }
211*789431f2SAndroid Build Coastguard Worker
212*789431f2SAndroid Build Coastguard Worker if (GetSecurityLevel() != KM_SECURITY_LEVEL_SOFTWARE) {
213*789431f2SAndroid Build Coastguard Worker // We're pretending to be some sort of secure hardware. Put relevant tags in hw_enforced.
214*789431f2SAndroid Build Coastguard Worker for (auto& entry : key_description) {
215*789431f2SAndroid Build Coastguard Worker switch (entry.tag) {
216*789431f2SAndroid Build Coastguard Worker case KM_TAG_PURPOSE:
217*789431f2SAndroid Build Coastguard Worker case KM_TAG_ALGORITHM:
218*789431f2SAndroid Build Coastguard Worker case KM_TAG_KEY_SIZE:
219*789431f2SAndroid Build Coastguard Worker case KM_TAG_RSA_PUBLIC_EXPONENT:
220*789431f2SAndroid Build Coastguard Worker case KM_TAG_BLOB_USAGE_REQUIREMENTS:
221*789431f2SAndroid Build Coastguard Worker case KM_TAG_DIGEST:
222*789431f2SAndroid Build Coastguard Worker case KM_TAG_PADDING:
223*789431f2SAndroid Build Coastguard Worker case KM_TAG_BLOCK_MODE:
224*789431f2SAndroid Build Coastguard Worker case KM_TAG_MIN_SECONDS_BETWEEN_OPS:
225*789431f2SAndroid Build Coastguard Worker case KM_TAG_MAX_USES_PER_BOOT:
226*789431f2SAndroid Build Coastguard Worker case KM_TAG_USER_SECURE_ID:
227*789431f2SAndroid Build Coastguard Worker case KM_TAG_NO_AUTH_REQUIRED:
228*789431f2SAndroid Build Coastguard Worker case KM_TAG_AUTH_TIMEOUT:
229*789431f2SAndroid Build Coastguard Worker case KM_TAG_CALLER_NONCE:
230*789431f2SAndroid Build Coastguard Worker case KM_TAG_MIN_MAC_LENGTH:
231*789431f2SAndroid Build Coastguard Worker case KM_TAG_KDF:
232*789431f2SAndroid Build Coastguard Worker case KM_TAG_EC_CURVE:
233*789431f2SAndroid Build Coastguard Worker case KM_TAG_ECIES_SINGLE_HASH_MODE:
234*789431f2SAndroid Build Coastguard Worker case KM_TAG_USER_AUTH_TYPE:
235*789431f2SAndroid Build Coastguard Worker case KM_TAG_ORIGIN:
236*789431f2SAndroid Build Coastguard Worker case KM_TAG_OS_VERSION:
237*789431f2SAndroid Build Coastguard Worker case KM_TAG_OS_PATCHLEVEL:
238*789431f2SAndroid Build Coastguard Worker case KM_TAG_EARLY_BOOT_ONLY:
239*789431f2SAndroid Build Coastguard Worker case KM_TAG_UNLOCKED_DEVICE_REQUIRED:
240*789431f2SAndroid Build Coastguard Worker case KM_TAG_RSA_OAEP_MGF_DIGEST:
241*789431f2SAndroid Build Coastguard Worker case KM_TAG_ROLLBACK_RESISTANCE:
242*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(entry);
243*789431f2SAndroid Build Coastguard Worker break;
244*789431f2SAndroid Build Coastguard Worker case KM_TAG_USAGE_COUNT_LIMIT:
245*789431f2SAndroid Build Coastguard Worker // Enforce single use key with usage count limit = 1 into secure key storage.
246*789431f2SAndroid Build Coastguard Worker if (canStoreBySecureKeyStorageIfRequired && entry.integer == 1) {
247*789431f2SAndroid Build Coastguard Worker needStoreBySecureKeyStorage = true;
248*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(entry);
249*789431f2SAndroid Build Coastguard Worker }
250*789431f2SAndroid Build Coastguard Worker break;
251*789431f2SAndroid Build Coastguard Worker default:
252*789431f2SAndroid Build Coastguard Worker break;
253*789431f2SAndroid Build Coastguard Worker }
254*789431f2SAndroid Build Coastguard Worker }
255*789431f2SAndroid Build Coastguard Worker }
256*789431f2SAndroid Build Coastguard Worker
257*789431f2SAndroid Build Coastguard Worker keymaster_error_t error =
258*789431f2SAndroid Build Coastguard Worker SetKeyBlobAuthorizations(key_description, origin, os_version_, os_patchlevel_, hw_enforced,
259*789431f2SAndroid Build Coastguard Worker sw_enforced, GetKmVersion());
260*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
261*789431f2SAndroid Build Coastguard Worker error =
262*789431f2SAndroid Build Coastguard Worker ExtendKeyBlobAuthorizations(hw_enforced, sw_enforced, vendor_patchlevel_, boot_patchlevel_);
263*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
264*789431f2SAndroid Build Coastguard Worker if (module_hash_.has_value()) {
265*789431f2SAndroid Build Coastguard Worker keymaster_blob_t mod_hash = {module_hash_.value().data(), module_hash_.value().size()};
266*789431f2SAndroid Build Coastguard Worker sw_enforced->push_back(TAG_MODULE_HASH, mod_hash);
267*789431f2SAndroid Build Coastguard Worker }
268*789431f2SAndroid Build Coastguard Worker
269*789431f2SAndroid Build Coastguard Worker AuthorizationSet hidden;
270*789431f2SAndroid Build Coastguard Worker error = BuildHiddenAuthorizations(key_description, &hidden, softwareRootOfTrust);
271*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
272*789431f2SAndroid Build Coastguard Worker
273*789431f2SAndroid Build Coastguard Worker error = SerializeIntegrityAssuredBlob(key_material, hidden, *hw_enforced, *sw_enforced, blob);
274*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
275*789431f2SAndroid Build Coastguard Worker
276*789431f2SAndroid Build Coastguard Worker // Pretend to be some sort of secure hardware that can securely store the key blob.
277*789431f2SAndroid Build Coastguard Worker if (!needStoreBySecureKeyStorage) return KM_ERROR_OK;
278*789431f2SAndroid Build Coastguard Worker km_id_t keyid;
279*789431f2SAndroid Build Coastguard Worker if (!soft_keymaster_enforcement_.CreateKeyId(*blob, &keyid)) return KM_ERROR_UNKNOWN_ERROR;
280*789431f2SAndroid Build Coastguard Worker assert(needStoreBySecureKeyStorage && canStoreBySecureKeyStorageIfRequired);
281*789431f2SAndroid Build Coastguard Worker return pure_soft_secure_key_storage_->WriteKey(keyid, *blob);
282*789431f2SAndroid Build Coastguard Worker }
283*789431f2SAndroid Build Coastguard Worker
UpgradeKeyBlob(const KeymasterKeyBlob & key_to_upgrade,const AuthorizationSet & upgrade_params,KeymasterKeyBlob * upgraded_key) const284*789431f2SAndroid Build Coastguard Worker keymaster_error_t PureSoftKeymasterContext::UpgradeKeyBlob(const KeymasterKeyBlob& key_to_upgrade,
285*789431f2SAndroid Build Coastguard Worker const AuthorizationSet& upgrade_params,
286*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob* upgraded_key) const {
287*789431f2SAndroid Build Coastguard Worker UniquePtr<Key> key;
288*789431f2SAndroid Build Coastguard Worker keymaster_error_t error = ParseKeyBlob(key_to_upgrade, upgrade_params, &key);
289*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
290*789431f2SAndroid Build Coastguard Worker
291*789431f2SAndroid Build Coastguard Worker return FullUpgradeSoftKeyBlob(key, os_version_, os_patchlevel_, vendor_patchlevel_,
292*789431f2SAndroid Build Coastguard Worker boot_patchlevel_, upgrade_params, upgraded_key);
293*789431f2SAndroid Build Coastguard Worker }
294*789431f2SAndroid Build Coastguard Worker
ParseKeyBlob(const KeymasterKeyBlob & blob,const AuthorizationSet & additional_params,UniquePtr<Key> * key) const295*789431f2SAndroid Build Coastguard Worker keymaster_error_t PureSoftKeymasterContext::ParseKeyBlob(const KeymasterKeyBlob& blob,
296*789431f2SAndroid Build Coastguard Worker const AuthorizationSet& additional_params,
297*789431f2SAndroid Build Coastguard Worker UniquePtr<Key>* key) const {
298*789431f2SAndroid Build Coastguard Worker // This is a little bit complicated.
299*789431f2SAndroid Build Coastguard Worker //
300*789431f2SAndroid Build Coastguard Worker // The SoftKeymasterContext has to handle a lot of different kinds of key blobs.
301*789431f2SAndroid Build Coastguard Worker //
302*789431f2SAndroid Build Coastguard Worker // 1. New keymaster1 software key blobs. These are integrity-assured but not encrypted. The
303*789431f2SAndroid Build Coastguard Worker // raw key material and auth sets should be extracted and returned. This is the kind
304*789431f2SAndroid Build Coastguard Worker // produced by this context when the KeyFactory doesn't use keymaster0 to back the keys.
305*789431f2SAndroid Build Coastguard Worker //
306*789431f2SAndroid Build Coastguard Worker // 2. Old keymaster1 software key blobs. These are OCB-encrypted with an all-zero master key.
307*789431f2SAndroid Build Coastguard Worker // They should be decrypted and the key material and auth sets extracted and returned.
308*789431f2SAndroid Build Coastguard Worker //
309*789431f2SAndroid Build Coastguard Worker // 3. Old keymaster0 software key blobs. These are raw key material with a small header tacked
310*789431f2SAndroid Build Coastguard Worker // on the front. They don't have auth sets, so reasonable defaults are generated and
311*789431f2SAndroid Build Coastguard Worker // returned along with the raw key material.
312*789431f2SAndroid Build Coastguard Worker //
313*789431f2SAndroid Build Coastguard Worker // Determining what kind of blob has arrived is somewhat tricky. What helps is that
314*789431f2SAndroid Build Coastguard Worker // integrity-assured and OCB-encrypted blobs are self-consistent and effectively impossible to
315*789431f2SAndroid Build Coastguard Worker // parse as anything else. Old keymaster0 software key blobs have a header. It's reasonably
316*789431f2SAndroid Build Coastguard Worker // unlikely that hardware keys would have the same header. So anything that is neither
317*789431f2SAndroid Build Coastguard Worker // integrity-assured nor OCB-encrypted and lacks the old software key header is assumed to be
318*789431f2SAndroid Build Coastguard Worker // keymaster0 hardware.
319*789431f2SAndroid Build Coastguard Worker
320*789431f2SAndroid Build Coastguard Worker AuthorizationSet hw_enforced;
321*789431f2SAndroid Build Coastguard Worker AuthorizationSet sw_enforced;
322*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob key_material;
323*789431f2SAndroid Build Coastguard Worker keymaster_error_t error;
324*789431f2SAndroid Build Coastguard Worker
325*789431f2SAndroid Build Coastguard Worker auto constructKey = [&, this]() mutable -> keymaster_error_t {
326*789431f2SAndroid Build Coastguard Worker // GetKeyFactory
327*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
328*789431f2SAndroid Build Coastguard Worker keymaster_algorithm_t algorithm;
329*789431f2SAndroid Build Coastguard Worker if (!hw_enforced.GetTagValue(TAG_ALGORITHM, &algorithm) &&
330*789431f2SAndroid Build Coastguard Worker !sw_enforced.GetTagValue(TAG_ALGORITHM, &algorithm)) {
331*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_ARGUMENT;
332*789431f2SAndroid Build Coastguard Worker }
333*789431f2SAndroid Build Coastguard Worker
334*789431f2SAndroid Build Coastguard Worker // Pretend to be some sort of secure hardware that can securely store
335*789431f2SAndroid Build Coastguard Worker // the key blob. Check the key blob is still securely stored now.
336*789431f2SAndroid Build Coastguard Worker if (hw_enforced.Contains(KM_TAG_ROLLBACK_RESISTANCE) ||
337*789431f2SAndroid Build Coastguard Worker hw_enforced.Contains(KM_TAG_USAGE_COUNT_LIMIT)) {
338*789431f2SAndroid Build Coastguard Worker if (pure_soft_secure_key_storage_ == nullptr) return KM_ERROR_INVALID_KEY_BLOB;
339*789431f2SAndroid Build Coastguard Worker km_id_t keyid;
340*789431f2SAndroid Build Coastguard Worker bool exists;
341*789431f2SAndroid Build Coastguard Worker if (!soft_keymaster_enforcement_.CreateKeyId(blob, &keyid))
342*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_KEY_BLOB;
343*789431f2SAndroid Build Coastguard Worker error = pure_soft_secure_key_storage_->KeyExists(keyid, &exists);
344*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK || !exists) return KM_ERROR_INVALID_KEY_BLOB;
345*789431f2SAndroid Build Coastguard Worker }
346*789431f2SAndroid Build Coastguard Worker
347*789431f2SAndroid Build Coastguard Worker auto factory = GetKeyFactory(algorithm);
348*789431f2SAndroid Build Coastguard Worker return factory->LoadKey(std::move(key_material), additional_params, std::move(hw_enforced),
349*789431f2SAndroid Build Coastguard Worker std::move(sw_enforced), key);
350*789431f2SAndroid Build Coastguard Worker };
351*789431f2SAndroid Build Coastguard Worker
352*789431f2SAndroid Build Coastguard Worker AuthorizationSet hidden;
353*789431f2SAndroid Build Coastguard Worker error = BuildHiddenAuthorizations(additional_params, &hidden, softwareRootOfTrust);
354*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
355*789431f2SAndroid Build Coastguard Worker
356*789431f2SAndroid Build Coastguard Worker // Assume it's an integrity-assured blob (new software-only blob, or new keymaster0-backed
357*789431f2SAndroid Build Coastguard Worker // blob).
358*789431f2SAndroid Build Coastguard Worker error =
359*789431f2SAndroid Build Coastguard Worker DeserializeIntegrityAssuredBlob(blob, hidden, &key_material, &hw_enforced, &sw_enforced);
360*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_INVALID_KEY_BLOB) return constructKey();
361*789431f2SAndroid Build Coastguard Worker
362*789431f2SAndroid Build Coastguard Worker // Wasn't an integrity-assured blob. Maybe it's an auth-encrypted blob.
363*789431f2SAndroid Build Coastguard Worker error = ParseAuthEncryptedBlob(blob, hidden, &key_material, &hw_enforced, &sw_enforced);
364*789431f2SAndroid Build Coastguard Worker if (error == KM_ERROR_OK) LOG_D("Parsed an old keymaster1 software key");
365*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_INVALID_KEY_BLOB) return constructKey();
366*789431f2SAndroid Build Coastguard Worker
367*789431f2SAndroid Build Coastguard Worker // Wasn't an auth-encrypted blob. Maybe it's an old softkeymaster blob.
368*789431f2SAndroid Build Coastguard Worker error = ParseOldSoftkeymasterBlob(blob, &key_material, &hw_enforced, &sw_enforced);
369*789431f2SAndroid Build Coastguard Worker if (error == KM_ERROR_OK) LOG_D("Parsed an old sofkeymaster key");
370*789431f2SAndroid Build Coastguard Worker
371*789431f2SAndroid Build Coastguard Worker return constructKey();
372*789431f2SAndroid Build Coastguard Worker }
373*789431f2SAndroid Build Coastguard Worker
DeleteKey(const KeymasterKeyBlob & blob) const374*789431f2SAndroid Build Coastguard Worker keymaster_error_t PureSoftKeymasterContext::DeleteKey(const KeymasterKeyBlob& blob) const {
375*789431f2SAndroid Build Coastguard Worker // Pretend to be some secure hardware with secure storage.
376*789431f2SAndroid Build Coastguard Worker if (GetSecurityLevel() != KM_SECURITY_LEVEL_SOFTWARE &&
377*789431f2SAndroid Build Coastguard Worker pure_soft_secure_key_storage_ != nullptr) {
378*789431f2SAndroid Build Coastguard Worker km_id_t keyid;
379*789431f2SAndroid Build Coastguard Worker if (!soft_keymaster_enforcement_.CreateKeyId(blob, &keyid)) return KM_ERROR_UNKNOWN_ERROR;
380*789431f2SAndroid Build Coastguard Worker return pure_soft_secure_key_storage_->DeleteKey(keyid);
381*789431f2SAndroid Build Coastguard Worker }
382*789431f2SAndroid Build Coastguard Worker
383*789431f2SAndroid Build Coastguard Worker // Otherwise, nothing to do for software-only contexts.
384*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
385*789431f2SAndroid Build Coastguard Worker }
386*789431f2SAndroid Build Coastguard Worker
DeleteAllKeys() const387*789431f2SAndroid Build Coastguard Worker keymaster_error_t PureSoftKeymasterContext::DeleteAllKeys() const {
388*789431f2SAndroid Build Coastguard Worker // Pretend to be some secure hardware with secure storage.
389*789431f2SAndroid Build Coastguard Worker if (GetSecurityLevel() != KM_SECURITY_LEVEL_SOFTWARE &&
390*789431f2SAndroid Build Coastguard Worker pure_soft_secure_key_storage_ != nullptr) {
391*789431f2SAndroid Build Coastguard Worker return pure_soft_secure_key_storage_->DeleteAllKeys();
392*789431f2SAndroid Build Coastguard Worker }
393*789431f2SAndroid Build Coastguard Worker
394*789431f2SAndroid Build Coastguard Worker // Otherwise, nothing to do for software-only contexts.
395*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
396*789431f2SAndroid Build Coastguard Worker }
397*789431f2SAndroid Build Coastguard Worker
AddRngEntropy(const uint8_t * buf,size_t length) const398*789431f2SAndroid Build Coastguard Worker keymaster_error_t PureSoftKeymasterContext::AddRngEntropy(const uint8_t* buf, size_t length) const {
399*789431f2SAndroid Build Coastguard Worker if (length > 2 * 1024) {
400*789431f2SAndroid Build Coastguard Worker // At most 2KiB is allowed to be added at once.
401*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_INPUT_LENGTH;
402*789431f2SAndroid Build Coastguard Worker }
403*789431f2SAndroid Build Coastguard Worker // XXX TODO according to boringssl openssl/rand.h RAND_add is deprecated and does
404*789431f2SAndroid Build Coastguard Worker // nothing
405*789431f2SAndroid Build Coastguard Worker RAND_add(buf, length, 0 /* Don't assume any entropy is added to the pool. */);
406*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
407*789431f2SAndroid Build Coastguard Worker }
408*789431f2SAndroid Build Coastguard Worker
409*789431f2SAndroid Build Coastguard Worker CertificateChain
GenerateAttestation(const Key & key,const AuthorizationSet & attest_params,UniquePtr<Key> attest_key,const KeymasterBlob & issuer_subject,keymaster_error_t * error) const410*789431f2SAndroid Build Coastguard Worker PureSoftKeymasterContext::GenerateAttestation(const Key& key, //
411*789431f2SAndroid Build Coastguard Worker const AuthorizationSet& attest_params, //
412*789431f2SAndroid Build Coastguard Worker UniquePtr<Key> attest_key,
413*789431f2SAndroid Build Coastguard Worker const KeymasterBlob& issuer_subject,
414*789431f2SAndroid Build Coastguard Worker keymaster_error_t* error) const {
415*789431f2SAndroid Build Coastguard Worker if (!error) return {};
416*789431f2SAndroid Build Coastguard Worker *error = KM_ERROR_OK;
417*789431f2SAndroid Build Coastguard Worker
418*789431f2SAndroid Build Coastguard Worker keymaster_algorithm_t key_algorithm;
419*789431f2SAndroid Build Coastguard Worker if (!key.authorizations().GetTagValue(TAG_ALGORITHM, &key_algorithm)) {
420*789431f2SAndroid Build Coastguard Worker *error = KM_ERROR_UNKNOWN_ERROR;
421*789431f2SAndroid Build Coastguard Worker return {};
422*789431f2SAndroid Build Coastguard Worker }
423*789431f2SAndroid Build Coastguard Worker
424*789431f2SAndroid Build Coastguard Worker if ((key_algorithm != KM_ALGORITHM_RSA && key_algorithm != KM_ALGORITHM_EC)) {
425*789431f2SAndroid Build Coastguard Worker *error = KM_ERROR_INCOMPATIBLE_ALGORITHM;
426*789431f2SAndroid Build Coastguard Worker return {};
427*789431f2SAndroid Build Coastguard Worker }
428*789431f2SAndroid Build Coastguard Worker
429*789431f2SAndroid Build Coastguard Worker if (attest_params.GetTagValue(TAG_DEVICE_UNIQUE_ATTESTATION)) {
430*789431f2SAndroid Build Coastguard Worker *error = KM_ERROR_UNIMPLEMENTED;
431*789431f2SAndroid Build Coastguard Worker return {};
432*789431f2SAndroid Build Coastguard Worker }
433*789431f2SAndroid Build Coastguard Worker // We have established that the given key has the correct algorithm, and because this is the
434*789431f2SAndroid Build Coastguard Worker // SoftKeymasterContext we can assume that the Key is an AsymmetricKey. So we can downcast.
435*789431f2SAndroid Build Coastguard Worker const AsymmetricKey& asymmetric_key = static_cast<const AsymmetricKey&>(key);
436*789431f2SAndroid Build Coastguard Worker
437*789431f2SAndroid Build Coastguard Worker AttestKeyInfo attest_key_info(attest_key, &issuer_subject, error);
438*789431f2SAndroid Build Coastguard Worker if (*error != KM_ERROR_OK) return {};
439*789431f2SAndroid Build Coastguard Worker
440*789431f2SAndroid Build Coastguard Worker return generate_attestation(asymmetric_key, attest_params, std::move(attest_key_info), *this,
441*789431f2SAndroid Build Coastguard Worker error);
442*789431f2SAndroid Build Coastguard Worker }
443*789431f2SAndroid Build Coastguard Worker
GenerateSelfSignedCertificate(const Key & key,const AuthorizationSet & cert_params,bool fake_signature,keymaster_error_t * error) const444*789431f2SAndroid Build Coastguard Worker CertificateChain PureSoftKeymasterContext::GenerateSelfSignedCertificate(
445*789431f2SAndroid Build Coastguard Worker const Key& key, const AuthorizationSet& cert_params, bool fake_signature,
446*789431f2SAndroid Build Coastguard Worker keymaster_error_t* error) const {
447*789431f2SAndroid Build Coastguard Worker keymaster_algorithm_t key_algorithm;
448*789431f2SAndroid Build Coastguard Worker if (!key.authorizations().GetTagValue(TAG_ALGORITHM, &key_algorithm)) {
449*789431f2SAndroid Build Coastguard Worker *error = KM_ERROR_UNKNOWN_ERROR;
450*789431f2SAndroid Build Coastguard Worker return {};
451*789431f2SAndroid Build Coastguard Worker }
452*789431f2SAndroid Build Coastguard Worker
453*789431f2SAndroid Build Coastguard Worker if ((key_algorithm != KM_ALGORITHM_RSA && key_algorithm != KM_ALGORITHM_EC)) {
454*789431f2SAndroid Build Coastguard Worker *error = KM_ERROR_INCOMPATIBLE_ALGORITHM;
455*789431f2SAndroid Build Coastguard Worker return {};
456*789431f2SAndroid Build Coastguard Worker }
457*789431f2SAndroid Build Coastguard Worker
458*789431f2SAndroid Build Coastguard Worker // We have established that the given key has the correct algorithm, and because this is the
459*789431f2SAndroid Build Coastguard Worker // SoftKeymasterContext we can assume that the Key is an AsymmetricKey. So we can downcast.
460*789431f2SAndroid Build Coastguard Worker const AsymmetricKey& asymmetric_key = static_cast<const AsymmetricKey&>(key);
461*789431f2SAndroid Build Coastguard Worker
462*789431f2SAndroid Build Coastguard Worker return generate_self_signed_cert(asymmetric_key, cert_params, fake_signature, error);
463*789431f2SAndroid Build Coastguard Worker }
464*789431f2SAndroid Build Coastguard Worker
GenerateUniqueId(uint64_t creation_date_time,const keymaster_blob_t & application_id,bool reset_since_rotation,keymaster_error_t * error) const465*789431f2SAndroid Build Coastguard Worker keymaster::Buffer PureSoftKeymasterContext::GenerateUniqueId(uint64_t creation_date_time,
466*789431f2SAndroid Build Coastguard Worker const keymaster_blob_t& application_id,
467*789431f2SAndroid Build Coastguard Worker bool reset_since_rotation,
468*789431f2SAndroid Build Coastguard Worker keymaster_error_t* error) const {
469*789431f2SAndroid Build Coastguard Worker *error = KM_ERROR_OK;
470*789431f2SAndroid Build Coastguard Worker // The default implementation fakes the hardware bound key with an arbitrary 128-bit value.
471*789431f2SAndroid Build Coastguard Worker // Any real implementation must follow the guidance from the interface definition
472*789431f2SAndroid Build Coastguard Worker // hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl:
473*789431f2SAndroid Build Coastguard Worker // "..a unique hardware-bound secret known to the secure environment and never revealed by it.
474*789431f2SAndroid Build Coastguard Worker // The secret must contain at least 128 bits of entropy and be unique to the individual device"
475*789431f2SAndroid Build Coastguard Worker const std::vector<uint8_t> fake_hbk = {'M', 'u', 's', 't', 'B', 'e', 'R', 'a',
476*789431f2SAndroid Build Coastguard Worker 'n', 'd', 'o', 'm', 'B', 'i', 't', 's'};
477*789431f2SAndroid Build Coastguard Worker Buffer unique_id;
478*789431f2SAndroid Build Coastguard Worker *error = keymaster::generate_unique_id(fake_hbk, creation_date_time, application_id,
479*789431f2SAndroid Build Coastguard Worker reset_since_rotation, &unique_id);
480*789431f2SAndroid Build Coastguard Worker return unique_id;
481*789431f2SAndroid Build Coastguard Worker }
482*789431f2SAndroid Build Coastguard Worker
TranslateAuthorizationSetError(AuthorizationSet::Error err)483*789431f2SAndroid Build Coastguard Worker static keymaster_error_t TranslateAuthorizationSetError(AuthorizationSet::Error err) {
484*789431f2SAndroid Build Coastguard Worker switch (err) {
485*789431f2SAndroid Build Coastguard Worker case AuthorizationSet::OK:
486*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
487*789431f2SAndroid Build Coastguard Worker case AuthorizationSet::ALLOCATION_FAILURE:
488*789431f2SAndroid Build Coastguard Worker return KM_ERROR_MEMORY_ALLOCATION_FAILED;
489*789431f2SAndroid Build Coastguard Worker case AuthorizationSet::MALFORMED_DATA:
490*789431f2SAndroid Build Coastguard Worker return KM_ERROR_UNKNOWN_ERROR;
491*789431f2SAndroid Build Coastguard Worker }
492*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
493*789431f2SAndroid Build Coastguard Worker }
494*789431f2SAndroid Build Coastguard Worker
UnwrapKey(const KeymasterKeyBlob & wrapped_key_blob,const KeymasterKeyBlob & wrapping_key_blob,const AuthorizationSet &,const KeymasterKeyBlob & masking_key,AuthorizationSet * wrapped_key_params,keymaster_key_format_t * wrapped_key_format,KeymasterKeyBlob * wrapped_key_material) const495*789431f2SAndroid Build Coastguard Worker keymaster_error_t PureSoftKeymasterContext::UnwrapKey(
496*789431f2SAndroid Build Coastguard Worker const KeymasterKeyBlob& wrapped_key_blob, const KeymasterKeyBlob& wrapping_key_blob,
497*789431f2SAndroid Build Coastguard Worker const AuthorizationSet& /* wrapping_key_params */, const KeymasterKeyBlob& masking_key,
498*789431f2SAndroid Build Coastguard Worker AuthorizationSet* wrapped_key_params, keymaster_key_format_t* wrapped_key_format,
499*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob* wrapped_key_material) const {
500*789431f2SAndroid Build Coastguard Worker keymaster_error_t error = KM_ERROR_OK;
501*789431f2SAndroid Build Coastguard Worker
502*789431f2SAndroid Build Coastguard Worker if (!wrapped_key_material) return KM_ERROR_UNEXPECTED_NULL_POINTER;
503*789431f2SAndroid Build Coastguard Worker
504*789431f2SAndroid Build Coastguard Worker // Parse wrapped key data
505*789431f2SAndroid Build Coastguard Worker KeymasterBlob iv;
506*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob transit_key;
507*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob secure_key;
508*789431f2SAndroid Build Coastguard Worker KeymasterBlob tag;
509*789431f2SAndroid Build Coastguard Worker KeymasterBlob wrapped_key_description;
510*789431f2SAndroid Build Coastguard Worker error = parse_wrapped_key(wrapped_key_blob, &iv, &transit_key, &secure_key, &tag,
511*789431f2SAndroid Build Coastguard Worker wrapped_key_params, wrapped_key_format, &wrapped_key_description);
512*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
513*789431f2SAndroid Build Coastguard Worker
514*789431f2SAndroid Build Coastguard Worker UniquePtr<Key> key;
515*789431f2SAndroid Build Coastguard Worker auto wrapping_key_params = AuthorizationSetBuilder()
516*789431f2SAndroid Build Coastguard Worker .RsaEncryptionKey(2048, 65537)
517*789431f2SAndroid Build Coastguard Worker .Digest(KM_DIGEST_SHA_2_256)
518*789431f2SAndroid Build Coastguard Worker .Padding(KM_PAD_RSA_OAEP)
519*789431f2SAndroid Build Coastguard Worker .Authorization(TAG_PURPOSE, KM_PURPOSE_WRAP)
520*789431f2SAndroid Build Coastguard Worker .build();
521*789431f2SAndroid Build Coastguard Worker error = ParseKeyBlob(wrapping_key_blob, wrapping_key_params, &key);
522*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
523*789431f2SAndroid Build Coastguard Worker
524*789431f2SAndroid Build Coastguard Worker // Ensure the wrapping key has the right purpose
525*789431f2SAndroid Build Coastguard Worker if (!key->hw_enforced().Contains(TAG_PURPOSE, KM_PURPOSE_WRAP) &&
526*789431f2SAndroid Build Coastguard Worker !key->sw_enforced().Contains(TAG_PURPOSE, KM_PURPOSE_WRAP)) {
527*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INCOMPATIBLE_PURPOSE;
528*789431f2SAndroid Build Coastguard Worker }
529*789431f2SAndroid Build Coastguard Worker
530*789431f2SAndroid Build Coastguard Worker auto operation_factory = GetOperationFactory(KM_ALGORITHM_RSA, KM_PURPOSE_DECRYPT);
531*789431f2SAndroid Build Coastguard Worker if (!operation_factory) return KM_ERROR_UNKNOWN_ERROR;
532*789431f2SAndroid Build Coastguard Worker
533*789431f2SAndroid Build Coastguard Worker AuthorizationSet out_params;
534*789431f2SAndroid Build Coastguard Worker OperationPtr operation(
535*789431f2SAndroid Build Coastguard Worker operation_factory->CreateOperation(std::move(*key), wrapping_key_params, &error));
536*789431f2SAndroid Build Coastguard Worker if (!operation.get()) return error;
537*789431f2SAndroid Build Coastguard Worker
538*789431f2SAndroid Build Coastguard Worker error = operation->Begin(wrapping_key_params, &out_params);
539*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
540*789431f2SAndroid Build Coastguard Worker
541*789431f2SAndroid Build Coastguard Worker Buffer input;
542*789431f2SAndroid Build Coastguard Worker Buffer output;
543*789431f2SAndroid Build Coastguard Worker if (!input.Reinitialize(transit_key.key_material, transit_key.key_material_size)) {
544*789431f2SAndroid Build Coastguard Worker return KM_ERROR_MEMORY_ALLOCATION_FAILED;
545*789431f2SAndroid Build Coastguard Worker }
546*789431f2SAndroid Build Coastguard Worker
547*789431f2SAndroid Build Coastguard Worker error = operation->Finish(wrapping_key_params, input, Buffer() /* signature */, &out_params,
548*789431f2SAndroid Build Coastguard Worker &output);
549*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
550*789431f2SAndroid Build Coastguard Worker
551*789431f2SAndroid Build Coastguard Worker // decrypt the encrypted key material with the transit key
552*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob key_material = {output.peek_read(), output.available_read()};
553*789431f2SAndroid Build Coastguard Worker
554*789431f2SAndroid Build Coastguard Worker // XOR the transit key with the masking key
555*789431f2SAndroid Build Coastguard Worker if (key_material.key_material_size != masking_key.key_material_size) {
556*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_ARGUMENT;
557*789431f2SAndroid Build Coastguard Worker }
558*789431f2SAndroid Build Coastguard Worker for (size_t i = 0; i < key_material.key_material_size; i++) {
559*789431f2SAndroid Build Coastguard Worker key_material.writable_data()[i] ^= masking_key.key_material[i];
560*789431f2SAndroid Build Coastguard Worker }
561*789431f2SAndroid Build Coastguard Worker
562*789431f2SAndroid Build Coastguard Worker auto transit_key_authorizations = AuthorizationSetBuilder()
563*789431f2SAndroid Build Coastguard Worker .AesEncryptionKey(256)
564*789431f2SAndroid Build Coastguard Worker .Padding(KM_PAD_NONE)
565*789431f2SAndroid Build Coastguard Worker .Authorization(TAG_BLOCK_MODE, KM_MODE_GCM)
566*789431f2SAndroid Build Coastguard Worker .Authorization(TAG_NONCE, iv)
567*789431f2SAndroid Build Coastguard Worker .Authorization(TAG_MIN_MAC_LENGTH, 128)
568*789431f2SAndroid Build Coastguard Worker .build();
569*789431f2SAndroid Build Coastguard Worker if (transit_key_authorizations.is_valid() != AuthorizationSet::Error::OK) {
570*789431f2SAndroid Build Coastguard Worker return TranslateAuthorizationSetError(transit_key_authorizations.is_valid());
571*789431f2SAndroid Build Coastguard Worker }
572*789431f2SAndroid Build Coastguard Worker auto gcm_params = AuthorizationSetBuilder()
573*789431f2SAndroid Build Coastguard Worker .Padding(KM_PAD_NONE)
574*789431f2SAndroid Build Coastguard Worker .Authorization(TAG_BLOCK_MODE, KM_MODE_GCM)
575*789431f2SAndroid Build Coastguard Worker .Authorization(TAG_NONCE, iv)
576*789431f2SAndroid Build Coastguard Worker .Authorization(TAG_MAC_LENGTH, 128)
577*789431f2SAndroid Build Coastguard Worker .build();
578*789431f2SAndroid Build Coastguard Worker if (gcm_params.is_valid() != AuthorizationSet::Error::OK) {
579*789431f2SAndroid Build Coastguard Worker return TranslateAuthorizationSetError(transit_key_authorizations.is_valid());
580*789431f2SAndroid Build Coastguard Worker }
581*789431f2SAndroid Build Coastguard Worker
582*789431f2SAndroid Build Coastguard Worker auto aes_factory = GetKeyFactory(KM_ALGORITHM_AES);
583*789431f2SAndroid Build Coastguard Worker if (!aes_factory) return KM_ERROR_UNKNOWN_ERROR;
584*789431f2SAndroid Build Coastguard Worker
585*789431f2SAndroid Build Coastguard Worker UniquePtr<Key> aes_key;
586*789431f2SAndroid Build Coastguard Worker error = aes_factory->LoadKey(std::move(key_material), gcm_params,
587*789431f2SAndroid Build Coastguard Worker std::move(transit_key_authorizations), AuthorizationSet(),
588*789431f2SAndroid Build Coastguard Worker &aes_key);
589*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
590*789431f2SAndroid Build Coastguard Worker
591*789431f2SAndroid Build Coastguard Worker auto aes_operation_factory = GetOperationFactory(KM_ALGORITHM_AES, KM_PURPOSE_DECRYPT);
592*789431f2SAndroid Build Coastguard Worker if (!aes_operation_factory) return KM_ERROR_UNKNOWN_ERROR;
593*789431f2SAndroid Build Coastguard Worker
594*789431f2SAndroid Build Coastguard Worker OperationPtr aes_operation(
595*789431f2SAndroid Build Coastguard Worker aes_operation_factory->CreateOperation(std::move(*aes_key), gcm_params, &error));
596*789431f2SAndroid Build Coastguard Worker if (!aes_operation.get()) return error;
597*789431f2SAndroid Build Coastguard Worker
598*789431f2SAndroid Build Coastguard Worker error = aes_operation->Begin(gcm_params, &out_params);
599*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
600*789431f2SAndroid Build Coastguard Worker
601*789431f2SAndroid Build Coastguard Worker size_t consumed = 0;
602*789431f2SAndroid Build Coastguard Worker Buffer encrypted_key, plaintext;
603*789431f2SAndroid Build Coastguard Worker if (!plaintext.Reinitialize(secure_key.key_material_size + tag.data_length)) {
604*789431f2SAndroid Build Coastguard Worker return KM_ERROR_MEMORY_ALLOCATION_FAILED;
605*789431f2SAndroid Build Coastguard Worker }
606*789431f2SAndroid Build Coastguard Worker if (!encrypted_key.Reinitialize(secure_key.key_material_size + tag.data_length)) {
607*789431f2SAndroid Build Coastguard Worker return KM_ERROR_MEMORY_ALLOCATION_FAILED;
608*789431f2SAndroid Build Coastguard Worker }
609*789431f2SAndroid Build Coastguard Worker if (!encrypted_key.write(secure_key.key_material, secure_key.key_material_size)) {
610*789431f2SAndroid Build Coastguard Worker return KM_ERROR_UNKNOWN_ERROR;
611*789431f2SAndroid Build Coastguard Worker }
612*789431f2SAndroid Build Coastguard Worker if (!encrypted_key.write(tag.data, tag.data_length)) {
613*789431f2SAndroid Build Coastguard Worker return KM_ERROR_UNKNOWN_ERROR;
614*789431f2SAndroid Build Coastguard Worker }
615*789431f2SAndroid Build Coastguard Worker
616*789431f2SAndroid Build Coastguard Worker AuthorizationSet update_outparams;
617*789431f2SAndroid Build Coastguard Worker auto update_params = AuthorizationSetBuilder()
618*789431f2SAndroid Build Coastguard Worker .Authorization(TAG_ASSOCIATED_DATA, wrapped_key_description.data,
619*789431f2SAndroid Build Coastguard Worker wrapped_key_description.data_length)
620*789431f2SAndroid Build Coastguard Worker .build();
621*789431f2SAndroid Build Coastguard Worker if (update_params.is_valid() != AuthorizationSet::Error::OK) {
622*789431f2SAndroid Build Coastguard Worker return TranslateAuthorizationSetError(update_params.is_valid());
623*789431f2SAndroid Build Coastguard Worker }
624*789431f2SAndroid Build Coastguard Worker
625*789431f2SAndroid Build Coastguard Worker error = aes_operation->Update(update_params, encrypted_key, &update_outparams, &plaintext,
626*789431f2SAndroid Build Coastguard Worker &consumed);
627*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
628*789431f2SAndroid Build Coastguard Worker
629*789431f2SAndroid Build Coastguard Worker AuthorizationSet finish_params, finish_out_params;
630*789431f2SAndroid Build Coastguard Worker Buffer finish_input;
631*789431f2SAndroid Build Coastguard Worker error = aes_operation->Finish(finish_params, finish_input, Buffer() /* signature */,
632*789431f2SAndroid Build Coastguard Worker &finish_out_params, &plaintext);
633*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
634*789431f2SAndroid Build Coastguard Worker
635*789431f2SAndroid Build Coastguard Worker *wrapped_key_material = {plaintext.peek_read(), plaintext.available_read()};
636*789431f2SAndroid Build Coastguard Worker if (!wrapped_key_material->key_material && plaintext.peek_read()) {
637*789431f2SAndroid Build Coastguard Worker return KM_ERROR_MEMORY_ALLOCATION_FAILED;
638*789431f2SAndroid Build Coastguard Worker }
639*789431f2SAndroid Build Coastguard Worker
640*789431f2SAndroid Build Coastguard Worker return error;
641*789431f2SAndroid Build Coastguard Worker }
642*789431f2SAndroid Build Coastguard Worker
643*789431f2SAndroid Build Coastguard Worker const AttestationContext::VerifiedBootParams*
GetVerifiedBootParams(keymaster_error_t * error) const644*789431f2SAndroid Build Coastguard Worker PureSoftKeymasterContext::GetVerifiedBootParams(keymaster_error_t* error) const {
645*789431f2SAndroid Build Coastguard Worker static VerifiedBootParams params;
646*789431f2SAndroid Build Coastguard Worker static std::string fake_vb_key(32, 0);
647*789431f2SAndroid Build Coastguard Worker params.verified_boot_key = {reinterpret_cast<uint8_t*>(fake_vb_key.data()), fake_vb_key.size()};
648*789431f2SAndroid Build Coastguard Worker params.verified_boot_hash = {reinterpret_cast<uint8_t*>(fake_vb_key.data()),
649*789431f2SAndroid Build Coastguard Worker fake_vb_key.size()};
650*789431f2SAndroid Build Coastguard Worker params.verified_boot_state = KM_VERIFIED_BOOT_UNVERIFIED;
651*789431f2SAndroid Build Coastguard Worker params.device_locked = false;
652*789431f2SAndroid Build Coastguard Worker *error = KM_ERROR_OK;
653*789431f2SAndroid Build Coastguard Worker return ¶ms;
654*789431f2SAndroid Build Coastguard Worker }
655*789431f2SAndroid Build Coastguard Worker
656*789431f2SAndroid Build Coastguard Worker } // namespace keymaster
657