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