1*789431f2SAndroid Build Coastguard Worker /*
2*789431f2SAndroid Build Coastguard Worker **
3*789431f2SAndroid Build Coastguard Worker ** Copyright 2017, The Android Open Source Project
4*789431f2SAndroid Build Coastguard Worker **
5*789431f2SAndroid Build Coastguard Worker ** Licensed under the Apache License, Version 2.0 (the "License");
6*789431f2SAndroid Build Coastguard Worker ** you may not use this file except in compliance with the License.
7*789431f2SAndroid Build Coastguard Worker ** You may obtain a copy of the License at
8*789431f2SAndroid Build Coastguard Worker **
9*789431f2SAndroid Build Coastguard Worker ** http://www.apache.org/licenses/LICENSE-2.0
10*789431f2SAndroid Build Coastguard Worker **
11*789431f2SAndroid Build Coastguard Worker ** Unless required by applicable law or agreed to in writing, software
12*789431f2SAndroid Build Coastguard Worker ** distributed under the License is distributed on an "AS IS" BASIS,
13*789431f2SAndroid Build Coastguard Worker ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*789431f2SAndroid Build Coastguard Worker ** See the License for the specific language governing permissions and
15*789431f2SAndroid Build Coastguard Worker ** limitations under the License.
16*789431f2SAndroid Build Coastguard Worker */
17*789431f2SAndroid Build Coastguard Worker
18*789431f2SAndroid Build Coastguard Worker #include <keymaster/key_blob_utils/software_keyblobs.h>
19*789431f2SAndroid Build Coastguard Worker
20*789431f2SAndroid Build Coastguard Worker #include <stdint.h>
21*789431f2SAndroid Build Coastguard Worker
22*789431f2SAndroid Build Coastguard Worker #include <hardware/keymaster_defs.h>
23*789431f2SAndroid Build Coastguard Worker
24*789431f2SAndroid Build Coastguard Worker #include <keymaster/UniquePtr.h>
25*789431f2SAndroid Build Coastguard Worker #include <keymaster/android_keymaster_utils.h>
26*789431f2SAndroid Build Coastguard Worker #include <keymaster/authorization_set.h>
27*789431f2SAndroid Build Coastguard Worker #include <keymaster/key.h>
28*789431f2SAndroid Build Coastguard Worker #include <keymaster/key_blob_utils/auth_encrypted_key_blob.h>
29*789431f2SAndroid Build Coastguard Worker #include <keymaster/key_blob_utils/integrity_assured_key_blob.h>
30*789431f2SAndroid Build Coastguard Worker #include <keymaster/key_blob_utils/ocb_utils.h>
31*789431f2SAndroid Build Coastguard Worker #include <keymaster/km_openssl/openssl_err.h>
32*789431f2SAndroid Build Coastguard Worker #include <keymaster/km_openssl/openssl_utils.h>
33*789431f2SAndroid Build Coastguard Worker #include <keymaster/logger.h>
34*789431f2SAndroid Build Coastguard Worker
35*789431f2SAndroid Build Coastguard Worker #include <openssl/aes.h>
36*789431f2SAndroid Build Coastguard Worker
37*789431f2SAndroid Build Coastguard Worker namespace keymaster {
38*789431f2SAndroid Build Coastguard Worker
39*789431f2SAndroid Build Coastguard Worker static uint8_t SWROT[2] = {'S', 'W'};
40*789431f2SAndroid Build Coastguard Worker KeymasterBlob softwareRootOfTrust(SWROT);
41*789431f2SAndroid Build Coastguard Worker
42*789431f2SAndroid Build Coastguard Worker namespace {
43*789431f2SAndroid Build Coastguard Worker
UpgradeIntegerTag(keymaster_tag_t tag,uint32_t value,AuthorizationSet * set,bool * set_changed)44*789431f2SAndroid Build Coastguard Worker bool UpgradeIntegerTag(keymaster_tag_t tag, uint32_t value, AuthorizationSet* set,
45*789431f2SAndroid Build Coastguard Worker bool* set_changed) {
46*789431f2SAndroid Build Coastguard Worker int index = set->find(tag);
47*789431f2SAndroid Build Coastguard Worker if (index == -1) {
48*789431f2SAndroid Build Coastguard Worker keymaster_key_param_t param;
49*789431f2SAndroid Build Coastguard Worker param.tag = tag;
50*789431f2SAndroid Build Coastguard Worker param.integer = value;
51*789431f2SAndroid Build Coastguard Worker set->push_back(param);
52*789431f2SAndroid Build Coastguard Worker *set_changed = true;
53*789431f2SAndroid Build Coastguard Worker return true;
54*789431f2SAndroid Build Coastguard Worker }
55*789431f2SAndroid Build Coastguard Worker
56*789431f2SAndroid Build Coastguard Worker if (set->params[index].integer > value) return false;
57*789431f2SAndroid Build Coastguard Worker
58*789431f2SAndroid Build Coastguard Worker if (set->params[index].integer != value) {
59*789431f2SAndroid Build Coastguard Worker set->params[index].integer = value;
60*789431f2SAndroid Build Coastguard Worker *set_changed = true;
61*789431f2SAndroid Build Coastguard Worker }
62*789431f2SAndroid Build Coastguard Worker return true;
63*789431f2SAndroid Build Coastguard Worker }
64*789431f2SAndroid Build Coastguard Worker
TranslateAuthorizationSetError(AuthorizationSet::Error err)65*789431f2SAndroid Build Coastguard Worker keymaster_error_t TranslateAuthorizationSetError(AuthorizationSet::Error err) {
66*789431f2SAndroid Build Coastguard Worker switch (err) {
67*789431f2SAndroid Build Coastguard Worker case AuthorizationSet::OK:
68*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
69*789431f2SAndroid Build Coastguard Worker case AuthorizationSet::ALLOCATION_FAILURE:
70*789431f2SAndroid Build Coastguard Worker return KM_ERROR_MEMORY_ALLOCATION_FAILED;
71*789431f2SAndroid Build Coastguard Worker case AuthorizationSet::MALFORMED_DATA:
72*789431f2SAndroid Build Coastguard Worker return KM_ERROR_UNKNOWN_ERROR;
73*789431f2SAndroid Build Coastguard Worker }
74*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
75*789431f2SAndroid Build Coastguard Worker }
76*789431f2SAndroid Build Coastguard Worker
77*789431f2SAndroid Build Coastguard Worker } // anonymous namespace
78*789431f2SAndroid Build Coastguard Worker
BuildHiddenAuthorizations(const AuthorizationSet & input_set,AuthorizationSet * hidden,const KeymasterBlob & root_of_trust)79*789431f2SAndroid Build Coastguard Worker keymaster_error_t BuildHiddenAuthorizations(const AuthorizationSet& input_set,
80*789431f2SAndroid Build Coastguard Worker AuthorizationSet* hidden,
81*789431f2SAndroid Build Coastguard Worker const KeymasterBlob& root_of_trust) {
82*789431f2SAndroid Build Coastguard Worker keymaster_blob_t entry;
83*789431f2SAndroid Build Coastguard Worker if (input_set.GetTagValue(TAG_APPLICATION_ID, &entry))
84*789431f2SAndroid Build Coastguard Worker hidden->push_back(TAG_APPLICATION_ID, entry.data, entry.data_length);
85*789431f2SAndroid Build Coastguard Worker if (input_set.GetTagValue(TAG_APPLICATION_DATA, &entry))
86*789431f2SAndroid Build Coastguard Worker hidden->push_back(TAG_APPLICATION_DATA, entry.data, entry.data_length);
87*789431f2SAndroid Build Coastguard Worker
88*789431f2SAndroid Build Coastguard Worker hidden->push_back(TAG_ROOT_OF_TRUST, root_of_trust);
89*789431f2SAndroid Build Coastguard Worker
90*789431f2SAndroid Build Coastguard Worker return TranslateAuthorizationSetError(hidden->is_valid());
91*789431f2SAndroid Build Coastguard Worker }
92*789431f2SAndroid Build Coastguard Worker
FakeKeyAuthorizations(EVP_PKEY * pubkey,AuthorizationSet * hw_enforced,AuthorizationSet * sw_enforced)93*789431f2SAndroid Build Coastguard Worker keymaster_error_t FakeKeyAuthorizations(EVP_PKEY* pubkey, AuthorizationSet* hw_enforced,
94*789431f2SAndroid Build Coastguard Worker AuthorizationSet* sw_enforced) {
95*789431f2SAndroid Build Coastguard Worker hw_enforced->Clear();
96*789431f2SAndroid Build Coastguard Worker sw_enforced->Clear();
97*789431f2SAndroid Build Coastguard Worker
98*789431f2SAndroid Build Coastguard Worker switch (EVP_PKEY_id(pubkey)) {
99*789431f2SAndroid Build Coastguard Worker case EVP_PKEY_RSA: {
100*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
101*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_NONE);
102*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_MD5);
103*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA1);
104*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_224);
105*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256);
106*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_384);
107*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_512);
108*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_PADDING, KM_PAD_NONE);
109*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN);
110*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
111*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_PADDING, KM_PAD_RSA_PSS);
112*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_PADDING, KM_PAD_RSA_OAEP);
113*789431f2SAndroid Build Coastguard Worker
114*789431f2SAndroid Build Coastguard Worker sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_SIGN);
115*789431f2SAndroid Build Coastguard Worker sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_VERIFY);
116*789431f2SAndroid Build Coastguard Worker sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_ENCRYPT);
117*789431f2SAndroid Build Coastguard Worker sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_DECRYPT);
118*789431f2SAndroid Build Coastguard Worker
119*789431f2SAndroid Build Coastguard Worker RSA_Ptr rsa(EVP_PKEY_get1_RSA(pubkey));
120*789431f2SAndroid Build Coastguard Worker if (!rsa) return TranslateLastOpenSslError();
121*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_KEY_SIZE, RSA_size(rsa.get()) * 8);
122*789431f2SAndroid Build Coastguard Worker uint64_t public_exponent;
123*789431f2SAndroid Build Coastguard Worker if (!BN_get_u64(RSA_get0_e(rsa.get()), &public_exponent)) return KM_ERROR_INVALID_KEY_BLOB;
124*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
125*789431f2SAndroid Build Coastguard Worker break;
126*789431f2SAndroid Build Coastguard Worker }
127*789431f2SAndroid Build Coastguard Worker
128*789431f2SAndroid Build Coastguard Worker case EVP_PKEY_EC: {
129*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
130*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_NONE);
131*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_MD5);
132*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA1);
133*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_224);
134*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256);
135*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_384);
136*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_512);
137*789431f2SAndroid Build Coastguard Worker
138*789431f2SAndroid Build Coastguard Worker sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_SIGN);
139*789431f2SAndroid Build Coastguard Worker sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_VERIFY);
140*789431f2SAndroid Build Coastguard Worker
141*789431f2SAndroid Build Coastguard Worker UniquePtr<EC_KEY, EC_KEY_Delete> ec_key(EVP_PKEY_get1_EC_KEY(pubkey));
142*789431f2SAndroid Build Coastguard Worker if (!ec_key.get()) return TranslateLastOpenSslError();
143*789431f2SAndroid Build Coastguard Worker size_t key_size_bits;
144*789431f2SAndroid Build Coastguard Worker keymaster_error_t error =
145*789431f2SAndroid Build Coastguard Worker ec_get_group_size(EC_KEY_get0_group(ec_key.get()), &key_size_bits);
146*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
147*789431f2SAndroid Build Coastguard Worker hw_enforced->push_back(TAG_KEY_SIZE, key_size_bits);
148*789431f2SAndroid Build Coastguard Worker break;
149*789431f2SAndroid Build Coastguard Worker }
150*789431f2SAndroid Build Coastguard Worker
151*789431f2SAndroid Build Coastguard Worker default:
152*789431f2SAndroid Build Coastguard Worker return KM_ERROR_UNSUPPORTED_ALGORITHM;
153*789431f2SAndroid Build Coastguard Worker }
154*789431f2SAndroid Build Coastguard Worker
155*789431f2SAndroid Build Coastguard Worker sw_enforced->push_back(TAG_ALL_USERS);
156*789431f2SAndroid Build Coastguard Worker sw_enforced->push_back(TAG_NO_AUTH_REQUIRED);
157*789431f2SAndroid Build Coastguard Worker
158*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
159*789431f2SAndroid Build Coastguard Worker }
160*789431f2SAndroid Build Coastguard Worker
161*789431f2SAndroid Build Coastguard Worker // Note: This parsing code in below is from system/security/softkeymaster/keymaster_openssl.cpp's
162*789431f2SAndroid Build Coastguard Worker // unwrap_key function, modified for the preferred function signature and formatting. It does some
163*789431f2SAndroid Build Coastguard Worker // odd things, but they have been left unchanged to avoid breaking compatibility.
164*789431f2SAndroid Build Coastguard Worker static const uint8_t SOFT_KEY_MAGIC[] = {'P', 'K', '#', '8'};
ParseOldSoftkeymasterBlob(const KeymasterKeyBlob & blob,KeymasterKeyBlob * key_material,AuthorizationSet * hw_enforced,AuthorizationSet * sw_enforced)165*789431f2SAndroid Build Coastguard Worker keymaster_error_t ParseOldSoftkeymasterBlob(const KeymasterKeyBlob& blob,
166*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob* key_material,
167*789431f2SAndroid Build Coastguard Worker AuthorizationSet* hw_enforced,
168*789431f2SAndroid Build Coastguard Worker AuthorizationSet* sw_enforced) {
169*789431f2SAndroid Build Coastguard Worker long publicLen = 0; // NOLINT(google-runtime-int)
170*789431f2SAndroid Build Coastguard Worker long privateLen = 0; // NOLINT(google-runtime-int)
171*789431f2SAndroid Build Coastguard Worker const uint8_t* p = blob.key_material;
172*789431f2SAndroid Build Coastguard Worker const uint8_t* end = blob.key_material + blob.key_material_size;
173*789431f2SAndroid Build Coastguard Worker
174*789431f2SAndroid Build Coastguard Worker int type = 0;
175*789431f2SAndroid Build Coastguard Worker ptrdiff_t min_size =
176*789431f2SAndroid Build Coastguard Worker sizeof(SOFT_KEY_MAGIC) + sizeof(type) + sizeof(publicLen) + 1 + sizeof(privateLen) + 1;
177*789431f2SAndroid Build Coastguard Worker if (end - p < min_size) {
178*789431f2SAndroid Build Coastguard Worker LOG_W("key blob appears to be truncated (if an old SW key)");
179*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_KEY_BLOB;
180*789431f2SAndroid Build Coastguard Worker }
181*789431f2SAndroid Build Coastguard Worker
182*789431f2SAndroid Build Coastguard Worker if (memcmp(p, SOFT_KEY_MAGIC, sizeof(SOFT_KEY_MAGIC)) != 0) return KM_ERROR_INVALID_KEY_BLOB;
183*789431f2SAndroid Build Coastguard Worker p += sizeof(SOFT_KEY_MAGIC);
184*789431f2SAndroid Build Coastguard Worker
185*789431f2SAndroid Build Coastguard Worker for (size_t i = 0; i < sizeof(type); i++) {
186*789431f2SAndroid Build Coastguard Worker type = (type << 8) | *p++;
187*789431f2SAndroid Build Coastguard Worker }
188*789431f2SAndroid Build Coastguard Worker
189*789431f2SAndroid Build Coastguard Worker for (size_t i = 0; i < sizeof(type); i++) {
190*789431f2SAndroid Build Coastguard Worker publicLen = (publicLen << 8) | *p++;
191*789431f2SAndroid Build Coastguard Worker }
192*789431f2SAndroid Build Coastguard Worker
193*789431f2SAndroid Build Coastguard Worker if (p + publicLen > end) {
194*789431f2SAndroid Build Coastguard Worker LOG_W("public key length encoding error: size=%ld, end=%td", publicLen, end - p);
195*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_KEY_BLOB;
196*789431f2SAndroid Build Coastguard Worker }
197*789431f2SAndroid Build Coastguard Worker p += publicLen;
198*789431f2SAndroid Build Coastguard Worker
199*789431f2SAndroid Build Coastguard Worker if (end - p < sizeof(type)) {
200*789431f2SAndroid Build Coastguard Worker LOG_W("key blob appears to be truncated (if an old SW key)");
201*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_KEY_BLOB;
202*789431f2SAndroid Build Coastguard Worker }
203*789431f2SAndroid Build Coastguard Worker
204*789431f2SAndroid Build Coastguard Worker for (size_t i = 0; i < sizeof(type); i++)
205*789431f2SAndroid Build Coastguard Worker privateLen = (privateLen << 8) | *p++;
206*789431f2SAndroid Build Coastguard Worker
207*789431f2SAndroid Build Coastguard Worker if (p + privateLen > end) {
208*789431f2SAndroid Build Coastguard Worker LOG_W("private key length encoding error: size=%ld, end=%td", privateLen, end - p);
209*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_KEY_BLOB;
210*789431f2SAndroid Build Coastguard Worker }
211*789431f2SAndroid Build Coastguard Worker
212*789431f2SAndroid Build Coastguard Worker // Just to be sure, make sure that the ASN.1 structure parses correctly. We don't actually use
213*789431f2SAndroid Build Coastguard Worker // the EVP_PKEY here.
214*789431f2SAndroid Build Coastguard Worker const uint8_t* key_start = p;
215*789431f2SAndroid Build Coastguard Worker EVP_PKEY_Ptr pkey(d2i_PrivateKey(type, nullptr, &p, privateLen));
216*789431f2SAndroid Build Coastguard Worker if (pkey.get() == nullptr) {
217*789431f2SAndroid Build Coastguard Worker LOG_W("Failed to parse PKCS#8 key material (if old SW key)");
218*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_KEY_BLOB;
219*789431f2SAndroid Build Coastguard Worker }
220*789431f2SAndroid Build Coastguard Worker
221*789431f2SAndroid Build Coastguard Worker // All auths go into sw_enforced, including those that would be HW-enforced if we were faking
222*789431f2SAndroid Build Coastguard Worker // auths for a HW-backed key.
223*789431f2SAndroid Build Coastguard Worker hw_enforced->Clear();
224*789431f2SAndroid Build Coastguard Worker keymaster_error_t error = FakeKeyAuthorizations(pkey.get(), sw_enforced, sw_enforced);
225*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
226*789431f2SAndroid Build Coastguard Worker
227*789431f2SAndroid Build Coastguard Worker if (!key_material->Reset(privateLen)) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
228*789431f2SAndroid Build Coastguard Worker memcpy(key_material->writable_data(), key_start, privateLen);
229*789431f2SAndroid Build Coastguard Worker
230*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
231*789431f2SAndroid Build Coastguard Worker }
232*789431f2SAndroid Build Coastguard Worker
233*789431f2SAndroid Build Coastguard Worker static uint8_t master_key_bytes[AES_BLOCK_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
234*789431f2SAndroid Build Coastguard Worker const KeymasterKeyBlob MASTER_KEY(master_key_bytes, array_length(master_key_bytes));
235*789431f2SAndroid Build Coastguard Worker
ParseAuthEncryptedBlob(const KeymasterKeyBlob & blob,const AuthorizationSet & hidden,KeymasterKeyBlob * key_material,AuthorizationSet * hw_enforced,AuthorizationSet * sw_enforced)236*789431f2SAndroid Build Coastguard Worker keymaster_error_t ParseAuthEncryptedBlob(const KeymasterKeyBlob& blob,
237*789431f2SAndroid Build Coastguard Worker const AuthorizationSet& hidden,
238*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob* key_material,
239*789431f2SAndroid Build Coastguard Worker AuthorizationSet* hw_enforced,
240*789431f2SAndroid Build Coastguard Worker AuthorizationSet* sw_enforced) {
241*789431f2SAndroid Build Coastguard Worker KmErrorOr<DeserializedKey> key = DeserializeAuthEncryptedBlob(blob);
242*789431f2SAndroid Build Coastguard Worker if (!key) return key.error();
243*789431f2SAndroid Build Coastguard Worker
244*789431f2SAndroid Build Coastguard Worker KmErrorOr<KeymasterKeyBlob> decrypted =
245*789431f2SAndroid Build Coastguard Worker DecryptKey(*key, hidden, SecureDeletionData(), MASTER_KEY);
246*789431f2SAndroid Build Coastguard Worker if (!decrypted) return decrypted.error();
247*789431f2SAndroid Build Coastguard Worker
248*789431f2SAndroid Build Coastguard Worker *key_material = std::move(*decrypted);
249*789431f2SAndroid Build Coastguard Worker *hw_enforced = std::move(key->hw_enforced);
250*789431f2SAndroid Build Coastguard Worker *sw_enforced = std::move(key->sw_enforced);
251*789431f2SAndroid Build Coastguard Worker
252*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
253*789431f2SAndroid Build Coastguard Worker }
254*789431f2SAndroid Build Coastguard Worker
SetKeyBlobAuthorizations(const AuthorizationSet & key_description,keymaster_key_origin_t origin,uint32_t os_version,uint32_t os_patchlevel,AuthorizationSet * hw_enforced,AuthorizationSet * sw_enforced,KmVersion version)255*789431f2SAndroid Build Coastguard Worker keymaster_error_t SetKeyBlobAuthorizations(const AuthorizationSet& key_description,
256*789431f2SAndroid Build Coastguard Worker keymaster_key_origin_t origin, uint32_t os_version,
257*789431f2SAndroid Build Coastguard Worker uint32_t os_patchlevel, AuthorizationSet* hw_enforced,
258*789431f2SAndroid Build Coastguard Worker AuthorizationSet* sw_enforced, KmVersion version) {
259*789431f2SAndroid Build Coastguard Worker sw_enforced->Clear();
260*789431f2SAndroid Build Coastguard Worker
261*789431f2SAndroid Build Coastguard Worker for (auto& entry : key_description) {
262*789431f2SAndroid Build Coastguard Worker switch (entry.tag) {
263*789431f2SAndroid Build Coastguard Worker // These cannot be specified by the client.
264*789431f2SAndroid Build Coastguard Worker case KM_TAG_BOOT_PATCHLEVEL:
265*789431f2SAndroid Build Coastguard Worker case KM_TAG_ORIGIN:
266*789431f2SAndroid Build Coastguard Worker case KM_TAG_OS_PATCHLEVEL:
267*789431f2SAndroid Build Coastguard Worker case KM_TAG_OS_VERSION:
268*789431f2SAndroid Build Coastguard Worker case KM_TAG_ROOT_OF_TRUST:
269*789431f2SAndroid Build Coastguard Worker case KM_TAG_VENDOR_PATCHLEVEL:
270*789431f2SAndroid Build Coastguard Worker LOG_E("Root of trust and origin tags may not be specified");
271*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_TAG;
272*789431f2SAndroid Build Coastguard Worker
273*789431f2SAndroid Build Coastguard Worker case KM_TAG_ALLOW_WHILE_ON_BODY:
274*789431f2SAndroid Build Coastguard Worker // Not supported, but is specified to noop in that case (vs error).
275*789431f2SAndroid Build Coastguard Worker LOG_W("No on-body detection supported, skipping tag %d", entry.tag);
276*789431f2SAndroid Build Coastguard Worker break;
277*789431f2SAndroid Build Coastguard Worker
278*789431f2SAndroid Build Coastguard Worker // These aren't supported by SoftKeymaster.
279*789431f2SAndroid Build Coastguard Worker case KM_TAG_DEVICE_UNIQUE_ATTESTATION:
280*789431f2SAndroid Build Coastguard Worker case KM_TAG_ECIES_SINGLE_HASH_MODE:
281*789431f2SAndroid Build Coastguard Worker case KM_TAG_EXPORTABLE:
282*789431f2SAndroid Build Coastguard Worker case KM_TAG_IDENTITY_CREDENTIAL_KEY:
283*789431f2SAndroid Build Coastguard Worker case KM_TAG_KDF:
284*789431f2SAndroid Build Coastguard Worker case KM_TAG_ROLLBACK_RESISTANT:
285*789431f2SAndroid Build Coastguard Worker case KM_TAG_STORAGE_KEY:
286*789431f2SAndroid Build Coastguard Worker LOG_E("Tag %d not supported by SoftKeymaster", entry.tag);
287*789431f2SAndroid Build Coastguard Worker return KM_ERROR_UNSUPPORTED_TAG;
288*789431f2SAndroid Build Coastguard Worker
289*789431f2SAndroid Build Coastguard Worker // If the hardware enforce list contains this tag, means we are
290*789431f2SAndroid Build Coastguard Worker // pretending to be some secure hardware which has secure storage.
291*789431f2SAndroid Build Coastguard Worker case KM_TAG_ROLLBACK_RESISTANCE:
292*789431f2SAndroid Build Coastguard Worker if (hw_enforced->GetTagCount(entry.tag) != 0)
293*789431f2SAndroid Build Coastguard Worker break;
294*789431f2SAndroid Build Coastguard Worker else {
295*789431f2SAndroid Build Coastguard Worker LOG_E("Tag %d not supported by SoftKeymaster", entry.tag);
296*789431f2SAndroid Build Coastguard Worker return KM_ERROR_UNSUPPORTED_TAG;
297*789431f2SAndroid Build Coastguard Worker }
298*789431f2SAndroid Build Coastguard Worker
299*789431f2SAndroid Build Coastguard Worker // These are hidden.
300*789431f2SAndroid Build Coastguard Worker case KM_TAG_APPLICATION_DATA:
301*789431f2SAndroid Build Coastguard Worker case KM_TAG_APPLICATION_ID:
302*789431f2SAndroid Build Coastguard Worker break;
303*789431f2SAndroid Build Coastguard Worker
304*789431f2SAndroid Build Coastguard Worker // These should not be in key descriptions because they're for operation parameters.
305*789431f2SAndroid Build Coastguard Worker case KM_TAG_ASSOCIATED_DATA:
306*789431f2SAndroid Build Coastguard Worker case KM_TAG_AUTH_TOKEN:
307*789431f2SAndroid Build Coastguard Worker case KM_TAG_CONFIRMATION_TOKEN:
308*789431f2SAndroid Build Coastguard Worker case KM_TAG_INVALID:
309*789431f2SAndroid Build Coastguard Worker case KM_TAG_MAC_LENGTH:
310*789431f2SAndroid Build Coastguard Worker case KM_TAG_NONCE:
311*789431f2SAndroid Build Coastguard Worker LOG_E("Tag %d not allowed in key generation/import", entry.tag);
312*789431f2SAndroid Build Coastguard Worker break;
313*789431f2SAndroid Build Coastguard Worker
314*789431f2SAndroid Build Coastguard Worker // These are provided to support attestation key generation, but should not be included in
315*789431f2SAndroid Build Coastguard Worker // the key characteristics.
316*789431f2SAndroid Build Coastguard Worker case KM_TAG_ATTESTATION_APPLICATION_ID:
317*789431f2SAndroid Build Coastguard Worker case KM_TAG_ATTESTATION_CHALLENGE:
318*789431f2SAndroid Build Coastguard Worker case KM_TAG_ATTESTATION_ID_BRAND:
319*789431f2SAndroid Build Coastguard Worker case KM_TAG_ATTESTATION_ID_DEVICE:
320*789431f2SAndroid Build Coastguard Worker case KM_TAG_ATTESTATION_ID_IMEI:
321*789431f2SAndroid Build Coastguard Worker case KM_TAG_ATTESTATION_ID_SECOND_IMEI:
322*789431f2SAndroid Build Coastguard Worker case KM_TAG_ATTESTATION_ID_MANUFACTURER:
323*789431f2SAndroid Build Coastguard Worker case KM_TAG_ATTESTATION_ID_MEID:
324*789431f2SAndroid Build Coastguard Worker case KM_TAG_ATTESTATION_ID_MODEL:
325*789431f2SAndroid Build Coastguard Worker case KM_TAG_ATTESTATION_ID_PRODUCT:
326*789431f2SAndroid Build Coastguard Worker case KM_TAG_ATTESTATION_ID_SERIAL:
327*789431f2SAndroid Build Coastguard Worker case KM_TAG_CERTIFICATE_SERIAL:
328*789431f2SAndroid Build Coastguard Worker case KM_TAG_CERTIFICATE_SUBJECT:
329*789431f2SAndroid Build Coastguard Worker case KM_TAG_CERTIFICATE_NOT_BEFORE:
330*789431f2SAndroid Build Coastguard Worker case KM_TAG_CERTIFICATE_NOT_AFTER:
331*789431f2SAndroid Build Coastguard Worker case KM_TAG_INCLUDE_UNIQUE_ID:
332*789431f2SAndroid Build Coastguard Worker case KM_TAG_RESET_SINCE_ID_ROTATION:
333*789431f2SAndroid Build Coastguard Worker case KM_TAG_MODULE_HASH:
334*789431f2SAndroid Build Coastguard Worker break;
335*789431f2SAndroid Build Coastguard Worker
336*789431f2SAndroid Build Coastguard Worker // Everything else we just copy into sw_enforced, unless the KeyFactory has placed it in
337*789431f2SAndroid Build Coastguard Worker // hw_enforced, in which case we defer to its decision.
338*789431f2SAndroid Build Coastguard Worker case KM_TAG_ACTIVE_DATETIME:
339*789431f2SAndroid Build Coastguard Worker case KM_TAG_ALGORITHM:
340*789431f2SAndroid Build Coastguard Worker case KM_TAG_ALL_APPLICATIONS:
341*789431f2SAndroid Build Coastguard Worker case KM_TAG_ALL_USERS:
342*789431f2SAndroid Build Coastguard Worker case KM_TAG_AUTH_TIMEOUT:
343*789431f2SAndroid Build Coastguard Worker case KM_TAG_BLOB_USAGE_REQUIREMENTS:
344*789431f2SAndroid Build Coastguard Worker case KM_TAG_BLOCK_MODE:
345*789431f2SAndroid Build Coastguard Worker case KM_TAG_BOOTLOADER_ONLY:
346*789431f2SAndroid Build Coastguard Worker case KM_TAG_CALLER_NONCE:
347*789431f2SAndroid Build Coastguard Worker case KM_TAG_CREATION_DATETIME:
348*789431f2SAndroid Build Coastguard Worker case KM_TAG_DIGEST:
349*789431f2SAndroid Build Coastguard Worker case KM_TAG_EARLY_BOOT_ONLY:
350*789431f2SAndroid Build Coastguard Worker case KM_TAG_EC_CURVE:
351*789431f2SAndroid Build Coastguard Worker case KM_TAG_KEY_SIZE:
352*789431f2SAndroid Build Coastguard Worker case KM_TAG_MAX_BOOT_LEVEL:
353*789431f2SAndroid Build Coastguard Worker case KM_TAG_MAX_USES_PER_BOOT:
354*789431f2SAndroid Build Coastguard Worker case KM_TAG_MIN_MAC_LENGTH:
355*789431f2SAndroid Build Coastguard Worker case KM_TAG_MIN_SECONDS_BETWEEN_OPS:
356*789431f2SAndroid Build Coastguard Worker case KM_TAG_NO_AUTH_REQUIRED:
357*789431f2SAndroid Build Coastguard Worker case KM_TAG_ORIGINATION_EXPIRE_DATETIME:
358*789431f2SAndroid Build Coastguard Worker case KM_TAG_PADDING:
359*789431f2SAndroid Build Coastguard Worker case KM_TAG_PURPOSE:
360*789431f2SAndroid Build Coastguard Worker case KM_TAG_RSA_OAEP_MGF_DIGEST:
361*789431f2SAndroid Build Coastguard Worker case KM_TAG_RSA_PUBLIC_EXPONENT:
362*789431f2SAndroid Build Coastguard Worker case KM_TAG_TRUSTED_CONFIRMATION_REQUIRED:
363*789431f2SAndroid Build Coastguard Worker case KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED:
364*789431f2SAndroid Build Coastguard Worker case KM_TAG_UNIQUE_ID:
365*789431f2SAndroid Build Coastguard Worker case KM_TAG_UNLOCKED_DEVICE_REQUIRED:
366*789431f2SAndroid Build Coastguard Worker case KM_TAG_USAGE_COUNT_LIMIT:
367*789431f2SAndroid Build Coastguard Worker case KM_TAG_USAGE_EXPIRE_DATETIME:
368*789431f2SAndroid Build Coastguard Worker case KM_TAG_USER_AUTH_TYPE:
369*789431f2SAndroid Build Coastguard Worker case KM_TAG_USER_ID:
370*789431f2SAndroid Build Coastguard Worker case KM_TAG_USER_SECURE_ID:
371*789431f2SAndroid Build Coastguard Worker if (hw_enforced->GetTagCount(entry.tag) == 0) sw_enforced->push_back(entry);
372*789431f2SAndroid Build Coastguard Worker break;
373*789431f2SAndroid Build Coastguard Worker }
374*789431f2SAndroid Build Coastguard Worker }
375*789431f2SAndroid Build Coastguard Worker
376*789431f2SAndroid Build Coastguard Worker // If hw_enforced is non-empty, we're pretending to be some sort of secure hardware.
377*789431f2SAndroid Build Coastguard Worker AuthorizationSet* pseudo_hw_enforced = (hw_enforced->empty()) ? sw_enforced : hw_enforced;
378*789431f2SAndroid Build Coastguard Worker pseudo_hw_enforced->push_back(TAG_ORIGIN, origin);
379*789431f2SAndroid Build Coastguard Worker pseudo_hw_enforced->push_back(TAG_OS_VERSION, os_version);
380*789431f2SAndroid Build Coastguard Worker pseudo_hw_enforced->push_back(TAG_OS_PATCHLEVEL, os_patchlevel);
381*789431f2SAndroid Build Coastguard Worker
382*789431f2SAndroid Build Coastguard Worker // For KeyMaster implementations (but not KeyMint implementations), we need to add a
383*789431f2SAndroid Build Coastguard Worker // CREATION_DATETIME into software-enforced if one was not provided.
384*789431f2SAndroid Build Coastguard Worker if (version < KmVersion::KEYMINT_1 && !sw_enforced->Contains(TAG_CREATION_DATETIME)) {
385*789431f2SAndroid Build Coastguard Worker sw_enforced->push_back(TAG_CREATION_DATETIME, java_time(time(nullptr)));
386*789431f2SAndroid Build Coastguard Worker }
387*789431f2SAndroid Build Coastguard Worker
388*789431f2SAndroid Build Coastguard Worker return TranslateAuthorizationSetError(sw_enforced->is_valid());
389*789431f2SAndroid Build Coastguard Worker }
390*789431f2SAndroid Build Coastguard Worker
ExtendKeyBlobAuthorizations(AuthorizationSet * hw_enforced,AuthorizationSet * sw_enforced,std::optional<uint32_t> vendor_patchlevel,std::optional<uint32_t> boot_patchlevel)391*789431f2SAndroid Build Coastguard Worker keymaster_error_t ExtendKeyBlobAuthorizations(AuthorizationSet* hw_enforced,
392*789431f2SAndroid Build Coastguard Worker AuthorizationSet* sw_enforced,
393*789431f2SAndroid Build Coastguard Worker std::optional<uint32_t> vendor_patchlevel,
394*789431f2SAndroid Build Coastguard Worker std::optional<uint32_t> boot_patchlevel) {
395*789431f2SAndroid Build Coastguard Worker // If hw_enforced is non-empty, we're pretending to be some sort of secure hardware.
396*789431f2SAndroid Build Coastguard Worker AuthorizationSet* pseudo_hw_enforced = (hw_enforced->empty()) ? sw_enforced : hw_enforced;
397*789431f2SAndroid Build Coastguard Worker if (vendor_patchlevel.has_value()) {
398*789431f2SAndroid Build Coastguard Worker pseudo_hw_enforced->push_back(TAG_VENDOR_PATCHLEVEL, vendor_patchlevel.value());
399*789431f2SAndroid Build Coastguard Worker }
400*789431f2SAndroid Build Coastguard Worker if (boot_patchlevel.has_value()) {
401*789431f2SAndroid Build Coastguard Worker pseudo_hw_enforced->push_back(TAG_BOOT_PATCHLEVEL, boot_patchlevel.value());
402*789431f2SAndroid Build Coastguard Worker }
403*789431f2SAndroid Build Coastguard Worker return TranslateAuthorizationSetError(sw_enforced->is_valid());
404*789431f2SAndroid Build Coastguard Worker }
405*789431f2SAndroid Build Coastguard Worker
UpgradeSoftKeyBlob(const UniquePtr<Key> & key,const uint32_t os_version,const uint32_t os_patchlevel,const AuthorizationSet & upgrade_params,KeymasterKeyBlob * upgraded_key)406*789431f2SAndroid Build Coastguard Worker keymaster_error_t UpgradeSoftKeyBlob(const UniquePtr<Key>& key, const uint32_t os_version,
407*789431f2SAndroid Build Coastguard Worker const uint32_t os_patchlevel,
408*789431f2SAndroid Build Coastguard Worker const AuthorizationSet& upgrade_params,
409*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob* upgraded_key) {
410*789431f2SAndroid Build Coastguard Worker return FullUpgradeSoftKeyBlob(key, os_version, os_patchlevel,
411*789431f2SAndroid Build Coastguard Worker /* vendor_patchlevel= */ std::nullopt,
412*789431f2SAndroid Build Coastguard Worker /* boot_patchlevel= */ std::nullopt, //
413*789431f2SAndroid Build Coastguard Worker upgrade_params, upgraded_key);
414*789431f2SAndroid Build Coastguard Worker }
415*789431f2SAndroid Build Coastguard Worker
FullUpgradeSoftKeyBlob(const UniquePtr<Key> & key,const uint32_t os_version,uint32_t os_patchlevel,std::optional<uint32_t> vendor_patchlevel,std::optional<uint32_t> boot_patchlevel,const AuthorizationSet & upgrade_params,KeymasterKeyBlob * upgraded_key)416*789431f2SAndroid Build Coastguard Worker keymaster_error_t FullUpgradeSoftKeyBlob(const UniquePtr<Key>& key, const uint32_t os_version,
417*789431f2SAndroid Build Coastguard Worker uint32_t os_patchlevel,
418*789431f2SAndroid Build Coastguard Worker std::optional<uint32_t> vendor_patchlevel,
419*789431f2SAndroid Build Coastguard Worker std::optional<uint32_t> boot_patchlevel,
420*789431f2SAndroid Build Coastguard Worker const AuthorizationSet& upgrade_params,
421*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob* upgraded_key) {
422*789431f2SAndroid Build Coastguard Worker bool set_changed = false;
423*789431f2SAndroid Build Coastguard Worker
424*789431f2SAndroid Build Coastguard Worker if (os_version == 0) {
425*789431f2SAndroid Build Coastguard Worker // We need to allow "upgrading" OS version to zero, to support upgrading from proper
426*789431f2SAndroid Build Coastguard Worker // numbered releases to unnumbered development and preview releases.
427*789431f2SAndroid Build Coastguard Worker
428*789431f2SAndroid Build Coastguard Worker int key_os_version_pos = key->sw_enforced().find(TAG_OS_VERSION);
429*789431f2SAndroid Build Coastguard Worker if (key_os_version_pos != -1) {
430*789431f2SAndroid Build Coastguard Worker uint32_t key_os_version = key->sw_enforced()[key_os_version_pos].integer;
431*789431f2SAndroid Build Coastguard Worker if (key_os_version != 0) {
432*789431f2SAndroid Build Coastguard Worker key->sw_enforced()[key_os_version_pos].integer = os_version;
433*789431f2SAndroid Build Coastguard Worker set_changed = true;
434*789431f2SAndroid Build Coastguard Worker }
435*789431f2SAndroid Build Coastguard Worker }
436*789431f2SAndroid Build Coastguard Worker }
437*789431f2SAndroid Build Coastguard Worker
438*789431f2SAndroid Build Coastguard Worker if (!UpgradeIntegerTag(TAG_OS_VERSION, os_version, &key->sw_enforced(), &set_changed) ||
439*789431f2SAndroid Build Coastguard Worker !UpgradeIntegerTag(TAG_OS_PATCHLEVEL, os_patchlevel, &key->sw_enforced(), &set_changed) ||
440*789431f2SAndroid Build Coastguard Worker (vendor_patchlevel.has_value() &&
441*789431f2SAndroid Build Coastguard Worker !UpgradeIntegerTag(TAG_VENDOR_PATCHLEVEL, vendor_patchlevel.value(), &key->sw_enforced(),
442*789431f2SAndroid Build Coastguard Worker &set_changed)) ||
443*789431f2SAndroid Build Coastguard Worker (boot_patchlevel.has_value() &&
444*789431f2SAndroid Build Coastguard Worker !UpgradeIntegerTag(TAG_BOOT_PATCHLEVEL, boot_patchlevel.value(), &key->sw_enforced(),
445*789431f2SAndroid Build Coastguard Worker &set_changed))) {
446*789431f2SAndroid Build Coastguard Worker // One of the version fields would have been a downgrade. Not allowed.
447*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_ARGUMENT;
448*789431f2SAndroid Build Coastguard Worker }
449*789431f2SAndroid Build Coastguard Worker
450*789431f2SAndroid Build Coastguard Worker if (!set_changed) {
451*789431f2SAndroid Build Coastguard Worker // Dont' need an upgrade.
452*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
453*789431f2SAndroid Build Coastguard Worker }
454*789431f2SAndroid Build Coastguard Worker
455*789431f2SAndroid Build Coastguard Worker AuthorizationSet hidden;
456*789431f2SAndroid Build Coastguard Worker auto error = BuildHiddenAuthorizations(upgrade_params, &hidden, softwareRootOfTrust);
457*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
458*789431f2SAndroid Build Coastguard Worker return SerializeIntegrityAssuredBlob(key->key_material(), hidden, key->hw_enforced(),
459*789431f2SAndroid Build Coastguard Worker key->sw_enforced(), upgraded_key);
460*789431f2SAndroid Build Coastguard Worker }
461*789431f2SAndroid Build Coastguard Worker
462*789431f2SAndroid Build Coastguard Worker } // namespace keymaster
463