xref: /aosp_15_r20/system/keymaster/contexts/pure_soft_keymaster_context.cpp (revision 789431f29546679ab5188a97751fb38e3018d44d)
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 &params;
654*789431f2SAndroid Build Coastguard Worker }
655*789431f2SAndroid Build Coastguard Worker 
656*789431f2SAndroid Build Coastguard Worker }  // namespace keymaster
657