1 // Copyright 2022, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 //! This module implements test utils to generate various types of keys.
16
17 use crate::authorizations::AuthSetBuilder;
18 use crate::ffi_test_utils::{
19 get_os_patchlevel, get_os_version, get_value_from_attest_record, get_vendor_patchlevel,
20 validate_certchain_with_strict_issuer_check,
21 };
22 use crate::SecLevel;
23 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
24 Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve,
25 ErrorCode::ErrorCode, HardwareAuthenticatorType::HardwareAuthenticatorType,
26 KeyOrigin::KeyOrigin, KeyParameter::KeyParameter, KeyParameterValue::KeyParameterValue,
27 KeyPurpose::KeyPurpose, PaddingMode::PaddingMode, SecurityLevel::SecurityLevel, Tag::Tag,
28 };
29 use android_system_keystore2::aidl::android::system::keystore2::{
30 AuthenticatorSpec::AuthenticatorSpec, Authorization::Authorization,
31 CreateOperationResponse::CreateOperationResponse, Domain::Domain, KeyDescriptor::KeyDescriptor,
32 KeyMetadata::KeyMetadata, ResponseCode::ResponseCode,
33 };
34 use android_system_keystore2::binder::{ExceptionCode, Result as BinderResult};
35 use anyhow::Result;
36 use binder::ThreadState;
37 use core::ops::Range;
38 use nix::unistd::getuid;
39 use std::collections::HashSet;
40 use std::fmt::Write;
41 use std::path::PathBuf;
42
43 /// Shell namespace.
44 pub const SELINUX_SHELL_NAMESPACE: i64 = 1;
45 /// Vold namespace.
46 pub const SELINUX_VOLD_NAMESPACE: i64 = 100;
47
48 /// SU context.
49 pub const TARGET_SU_CTX: &str = "u:r:su:s0";
50
51 /// Vold context
52 pub const TARGET_VOLD_CTX: &str = "u:r:vold:s0";
53
54 const TEE_KEYMINT_RKP_ONLY: &str = "remote_provisioning.tee.rkp_only";
55
56 const STRONGBOX_KEYMINT_RKP_ONLY: &str = "remote_provisioning.strongbox.rkp_only";
57
58 /// Allowed tags in generated/imported key authorizations.
59 /// See hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl for the
60 /// list feature tags.
61 /// Note: This list need to be updated whenever a new Tag is introduced and is expected to be added
62 /// in key authorizations.
63 pub const ALLOWED_TAGS_IN_KEY_AUTHS: &[Tag] = &[
64 Tag::ACTIVE_DATETIME,
65 Tag::ALGORITHM,
66 Tag::ALLOW_WHILE_ON_BODY,
67 Tag::AUTH_TIMEOUT,
68 Tag::BLOCK_MODE,
69 Tag::BOOTLOADER_ONLY,
70 Tag::BOOT_PATCHLEVEL,
71 Tag::CALLER_NONCE,
72 Tag::CREATION_DATETIME,
73 Tag::DIGEST,
74 Tag::EARLY_BOOT_ONLY,
75 Tag::EC_CURVE,
76 Tag::IDENTITY_CREDENTIAL_KEY,
77 Tag::INCLUDE_UNIQUE_ID,
78 Tag::KEY_SIZE,
79 Tag::MAX_BOOT_LEVEL,
80 Tag::MAX_USES_PER_BOOT,
81 Tag::MIN_MAC_LENGTH,
82 Tag::NO_AUTH_REQUIRED,
83 Tag::ORIGIN,
84 Tag::ORIGINATION_EXPIRE_DATETIME,
85 Tag::OS_PATCHLEVEL,
86 Tag::OS_VERSION,
87 Tag::PADDING,
88 Tag::PURPOSE,
89 Tag::ROLLBACK_RESISTANCE,
90 Tag::RSA_OAEP_MGF_DIGEST,
91 Tag::RSA_PUBLIC_EXPONENT,
92 Tag::STORAGE_KEY,
93 Tag::TRUSTED_CONFIRMATION_REQUIRED,
94 Tag::TRUSTED_USER_PRESENCE_REQUIRED,
95 Tag::UNLOCKED_DEVICE_REQUIRED,
96 Tag::USAGE_COUNT_LIMIT,
97 Tag::USAGE_EXPIRE_DATETIME,
98 Tag::USER_AUTH_TYPE,
99 Tag::USER_ID,
100 Tag::USER_SECURE_ID,
101 Tag::VENDOR_PATCHLEVEL,
102 ];
103
104 /// Key parameters to generate a key.
105 pub struct KeyParams {
106 /// Key Size.
107 pub key_size: i32,
108 /// Key Purposes.
109 pub purpose: Vec<KeyPurpose>,
110 /// Padding Mode.
111 pub padding: Option<PaddingMode>,
112 /// Digest.
113 pub digest: Option<Digest>,
114 /// MFG Digest.
115 pub mgf_digest: Option<Digest>,
116 /// Block Mode.
117 pub block_mode: Option<BlockMode>,
118 /// Attestation challenge.
119 pub att_challenge: Option<Vec<u8>>,
120 }
121
122 /// DER-encoded PKCS#8 format RSA key. Generated using:
123 /// openssl genrsa 2048 | openssl pkcs8 -topk8 -nocrypt -outform der | hexdump -e '30/1 "%02X" "\n"'
124 pub static RSA_2048_KEY: &[u8] = &[
125 0x30, 0x82, 0x04, 0xBD, 0x02, 0x01, 0x00, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
126 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x04, 0xA7, 0x30, 0x82, 0x04, 0xA3, 0x02, 0x01,
127 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xE5, 0x14, 0xE3, 0xC2, 0x43, 0xF3, 0x0F, 0xCC, 0x22, 0x73,
128 0x9C, 0x84, 0xCC, 0x1B, 0x6C, 0x97, 0x4B, 0xC9, 0xDF, 0x1F, 0xE2, 0xB8, 0x80, 0x85, 0xF9, 0x27,
129 0xAB, 0x97, 0x94, 0x58, 0x4B, 0xC9, 0x40, 0x94, 0x5A, 0xB4, 0xD4, 0xF8, 0xD0, 0x36, 0xC4, 0x86,
130 0x17, 0x7D, 0xA2, 0x48, 0x6D, 0x40, 0xF0, 0xB9, 0x61, 0x4F, 0xCE, 0x65, 0x80, 0x88, 0x81, 0x59,
131 0x95, 0x11, 0x24, 0xF4, 0x36, 0xB7, 0xB7, 0x37, 0x44, 0xF4, 0x6C, 0x1C, 0xEB, 0x04, 0x19, 0x78,
132 0xB2, 0x29, 0x4D, 0x21, 0x44, 0x16, 0x57, 0x58, 0x6D, 0x7D, 0x56, 0xB5, 0x99, 0xDD, 0xD2, 0xAD,
133 0x02, 0x9A, 0x72, 0x16, 0x67, 0xD6, 0x00, 0x9F, 0x69, 0xE0, 0x25, 0xEE, 0x7C, 0x86, 0x54, 0x27,
134 0x4B, 0x50, 0xEF, 0x60, 0x52, 0x60, 0x82, 0xAA, 0x09, 0x15, 0x72, 0xD2, 0xEB, 0x01, 0x52, 0x04,
135 0x39, 0x60, 0xBC, 0x5E, 0x95, 0x07, 0xC8, 0xC2, 0x3A, 0x3A, 0xE2, 0xA4, 0x99, 0x6B, 0x27, 0xE3,
136 0xA3, 0x55, 0x69, 0xC4, 0xB3, 0x2D, 0x19, 0xC4, 0x34, 0x76, 0xFC, 0x27, 0xDA, 0x22, 0xB2, 0x62,
137 0x69, 0x25, 0xDE, 0x0D, 0xE7, 0x54, 0x3C, 0xBB, 0x61, 0xD2, 0x20, 0xDA, 0x7B, 0x6E, 0x63, 0xBD,
138 0x9A, 0x4B, 0xCD, 0x75, 0xC6, 0xA1, 0x5E, 0x1C, 0x3E, 0xD5, 0x63, 0x59, 0x22, 0x7E, 0xE0, 0x6C,
139 0x98, 0x25, 0x63, 0x97, 0x56, 0xDF, 0x71, 0xF5, 0x4C, 0x78, 0xE9, 0xE1, 0xD5, 0xFC, 0xF8, 0x5A,
140 0x5B, 0xF6, 0x1D, 0xFA, 0x5A, 0x99, 0x4C, 0x99, 0x19, 0x21, 0x1D, 0xF5, 0x24, 0x07, 0xEF, 0x8A,
141 0xC9, 0x9F, 0xE7, 0x3F, 0xBB, 0x46, 0x1A, 0x16, 0x96, 0xC6, 0xD6, 0x12, 0x7E, 0xDA, 0xCB, 0xEB,
142 0x2F, 0x1D, 0x3B, 0x31, 0xCC, 0x55, 0x63, 0xA2, 0x6F, 0x8A, 0xDE, 0x35, 0x52, 0x40, 0x04, 0xBF,
143 0xE0, 0x82, 0x32, 0xE1, 0x6D, 0x8B, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x2D,
144 0x1F, 0x71, 0x41, 0x79, 0xBA, 0xED, 0xD8, 0xAA, 0xCC, 0x94, 0xFE, 0xFF, 0x69, 0x43, 0x79, 0x85,
145 0xBF, 0x2C, 0xC9, 0x0E, 0x12, 0x83, 0x96, 0x60, 0x1E, 0x75, 0x49, 0x35, 0x3A, 0x33, 0x2B, 0x60,
146 0x22, 0x18, 0xBF, 0xD7, 0xD7, 0x6E, 0xC3, 0xEA, 0xEF, 0xF2, 0xBE, 0x97, 0x71, 0xA6, 0xBB, 0x8C,
147 0xEF, 0x27, 0x00, 0xDE, 0x49, 0xD6, 0x08, 0x8D, 0x5A, 0x04, 0xE7, 0xCC, 0x9C, 0xA2, 0x0E, 0x8B,
148 0xF3, 0x42, 0x0C, 0xD7, 0x22, 0xD7, 0x14, 0x06, 0xA4, 0x64, 0x8B, 0x88, 0x1A, 0xCE, 0x5B, 0x8C,
149 0x36, 0xE9, 0xD2, 0x2F, 0x7B, 0x33, 0xE4, 0xA2, 0xB3, 0xDB, 0x78, 0x6A, 0x92, 0x89, 0x3F, 0x78,
150 0xFD, 0xED, 0x8F, 0xEE, 0x48, 0xCC, 0x94, 0x75, 0x0D, 0x0C, 0x63, 0xD3, 0xD2, 0xE8, 0x47, 0x04,
151 0x55, 0xD3, 0xD6, 0x3A, 0xB8, 0xDA, 0xFB, 0x76, 0x99, 0x48, 0x68, 0x0A, 0x92, 0xA2, 0xCD, 0xF7,
152 0x45, 0x8B, 0x50, 0xFE, 0xF9, 0x1A, 0x33, 0x24, 0x3C, 0x2E, 0xDE, 0x88, 0xAD, 0xB2, 0x5B, 0x9F,
153 0x44, 0xEA, 0xD1, 0x9F, 0xC7, 0x9F, 0x02, 0x5E, 0x31, 0x61, 0xB3, 0xD6, 0xE2, 0xE1, 0xBC, 0xFB,
154 0x1C, 0xDB, 0xBD, 0xB2, 0x9A, 0xE5, 0xEF, 0xDA, 0xCD, 0x29, 0xA5, 0x45, 0xCC, 0x67, 0x01, 0x8B,
155 0x1C, 0x1D, 0x0E, 0x8F, 0x73, 0x69, 0x4D, 0x4D, 0xF6, 0x9D, 0xA6, 0x6C, 0x9A, 0x1C, 0xF4, 0x5C,
156 0xE4, 0x83, 0x9A, 0x77, 0x12, 0x01, 0xBD, 0xCE, 0x66, 0x3A, 0x4B, 0x3D, 0x6E, 0xE0, 0x6E, 0x82,
157 0x98, 0xDE, 0x74, 0x11, 0x47, 0xEC, 0x7A, 0x3A, 0xA9, 0xD8, 0x48, 0x00, 0x26, 0x64, 0x47, 0x7B,
158 0xAE, 0x55, 0x9D, 0x29, 0x22, 0xB4, 0xB3, 0xB9, 0xB1, 0x64, 0xEA, 0x3B, 0x5A, 0xD3, 0x3F, 0x8D,
159 0x0F, 0x14, 0x7E, 0x4E, 0xB8, 0x1B, 0x06, 0xFC, 0xB1, 0x7E, 0xCD, 0xB9, 0x1A, 0x4E, 0xA1, 0x02,
160 0x81, 0x81, 0x00, 0xF9, 0xDE, 0xEE, 0xED, 0x13, 0x2F, 0xBB, 0xE7, 0xE2, 0xB3, 0x2D, 0x98, 0xD2,
161 0xE8, 0x25, 0x07, 0x5A, 0x1E, 0x51, 0x0A, 0xC8, 0xAD, 0x50, 0x4B, 0x80, 0xC6, 0x22, 0xF5, 0x9B,
162 0x08, 0xE6, 0x3D, 0x01, 0xC6, 0x3E, 0xC8, 0xD2, 0x54, 0x9F, 0x91, 0x77, 0x95, 0xCD, 0xCA, 0xC7,
163 0xE7, 0x47, 0x94, 0xA9, 0x5F, 0x4E, 0xBE, 0x31, 0x3D, 0xB4, 0xAF, 0x43, 0x0F, 0xDC, 0x8D, 0x9C,
164 0x1E, 0x52, 0x7B, 0x72, 0x21, 0x34, 0xB3, 0x96, 0x7C, 0x9C, 0xB8, 0x51, 0x65, 0x60, 0xAC, 0x3D,
165 0x11, 0x32, 0xB8, 0xD6, 0x34, 0x35, 0x66, 0xD0, 0x30, 0xB9, 0xE9, 0x67, 0x2C, 0x87, 0x73, 0x43,
166 0x9C, 0x12, 0x16, 0x7D, 0x4A, 0xD9, 0xA3, 0x4C, 0x24, 0x64, 0x6A, 0x32, 0x8E, 0xC3, 0xD8, 0x00,
167 0x90, 0x5C, 0x4D, 0x65, 0x01, 0x53, 0x8A, 0xD0, 0x87, 0xCE, 0x96, 0xEF, 0xFA, 0x73, 0x03, 0xF1,
168 0xDC, 0x1B, 0x9B, 0x02, 0x81, 0x81, 0x00, 0xEA, 0xB3, 0x69, 0x00, 0x11, 0x0E, 0x50, 0xAA, 0xD3,
169 0x22, 0x51, 0x78, 0x9D, 0xFF, 0x05, 0x62, 0xBC, 0x9A, 0x67, 0x86, 0xE1, 0xC5, 0x02, 0x2D, 0x14,
170 0x11, 0x29, 0x30, 0xE7, 0x90, 0x5D, 0x72, 0x6F, 0xC5, 0x62, 0xEB, 0xD4, 0xB0, 0x3F, 0x3D, 0xDC,
171 0xB9, 0xFC, 0x2B, 0x5C, 0xBD, 0x9E, 0x71, 0x81, 0x5C, 0xC5, 0xFE, 0xDF, 0x69, 0x73, 0x12, 0x66,
172 0x92, 0x06, 0xD4, 0xD5, 0x8F, 0xDF, 0x14, 0x2E, 0x9C, 0xD0, 0x4C, 0xC2, 0x4D, 0x31, 0x2E, 0x47,
173 0xA5, 0xDC, 0x8A, 0x83, 0x7B, 0xE8, 0xA5, 0xC3, 0x03, 0x98, 0xD8, 0xBF, 0xF4, 0x7D, 0x6E, 0x87,
174 0x55, 0xE4, 0x0F, 0x15, 0x10, 0xC8, 0x76, 0x4F, 0xAD, 0x1D, 0x1C, 0x95, 0x41, 0x9D, 0x88, 0xEC,
175 0x8C, 0xDA, 0xBA, 0x90, 0x7F, 0x8D, 0xD9, 0x8B, 0x47, 0x6C, 0x0C, 0xFF, 0xBA, 0x73, 0x00, 0x20,
176 0x1F, 0xF7, 0x7E, 0x5F, 0xF4, 0xEC, 0xD1, 0x02, 0x81, 0x80, 0x16, 0xB7, 0x43, 0xB5, 0x5D, 0xD7,
177 0x2B, 0x18, 0x0B, 0xAE, 0x0A, 0x69, 0x28, 0x53, 0x5E, 0x7A, 0x6A, 0xA0, 0xF2, 0xF1, 0x2E, 0x09,
178 0x43, 0x91, 0x79, 0xA5, 0x89, 0xAC, 0x16, 0x6A, 0x1A, 0xB4, 0x55, 0x22, 0xF6, 0xB6, 0x3F, 0x18,
179 0xDE, 0x60, 0xD5, 0x24, 0x53, 0x4F, 0x2A, 0x19, 0x46, 0x92, 0xA7, 0x4B, 0x38, 0xD7, 0x65, 0x96,
180 0x9C, 0x84, 0x8A, 0x6E, 0x38, 0xB8, 0xCF, 0x06, 0x9A, 0xAD, 0x0A, 0x55, 0x26, 0x7B, 0x65, 0x24,
181 0xF3, 0x02, 0x76, 0xB3, 0xE6, 0xB4, 0x01, 0xE1, 0x3C, 0x61, 0x3D, 0x68, 0x05, 0xAA, 0xD1, 0x26,
182 0x7C, 0xE0, 0x51, 0x36, 0xE5, 0x21, 0x7F, 0x76, 0x02, 0xD6, 0xF4, 0x91, 0x07, 0x74, 0x27, 0x09,
183 0xEF, 0xEF, 0x0F, 0xA5, 0x96, 0xFC, 0x5E, 0x20, 0xC1, 0xA3, 0x6F, 0x99, 0x4D, 0x45, 0x03, 0x6C,
184 0x35, 0x45, 0xD7, 0x8F, 0x47, 0x41, 0x86, 0x8D, 0x62, 0x1D, 0x02, 0x81, 0x81, 0x00, 0xC3, 0x93,
185 0x85, 0xA7, 0xFC, 0x8E, 0x85, 0x42, 0x14, 0x76, 0xC0, 0x95, 0x56, 0x73, 0xB0, 0xB5, 0x3A, 0x9D,
186 0x20, 0x30, 0x11, 0xEA, 0xED, 0x89, 0x4A, 0xF3, 0x91, 0xF3, 0xA2, 0xC3, 0x76, 0x5B, 0x6A, 0x30,
187 0x7D, 0xE2, 0x2F, 0x76, 0x3E, 0xFC, 0xF9, 0xF6, 0x31, 0xE0, 0xA0, 0x83, 0x92, 0x88, 0xDB, 0x57,
188 0xC7, 0xD6, 0x3F, 0xAD, 0xCB, 0xAA, 0x45, 0xB6, 0xE1, 0xE2, 0x71, 0xA4, 0x56, 0x2C, 0xA7, 0x3B,
189 0x1D, 0x89, 0x19, 0x50, 0xE1, 0xEE, 0xC2, 0xDD, 0xC0, 0x0D, 0xDC, 0xCB, 0x60, 0x6E, 0xE1, 0x37,
190 0x1A, 0x23, 0x64, 0xB2, 0x03, 0xE4, 0x1A, 0xFA, 0xC3, 0xF4, 0x9D, 0x85, 0x42, 0xC6, 0xF4, 0x56,
191 0x39, 0xB0, 0x1B, 0xE0, 0x75, 0xBA, 0x28, 0x04, 0xA8, 0x30, 0x57, 0x41, 0x33, 0x9F, 0x58, 0xA4,
192 0xC7, 0xB1, 0x7D, 0x58, 0x8D, 0x84, 0x49, 0x40, 0xDA, 0x28, 0x81, 0x25, 0xC4, 0x41, 0x02, 0x81,
193 0x80, 0x13, 0x20, 0x65, 0xD5, 0x96, 0x98, 0x8D, 0x16, 0x73, 0xA1, 0x31, 0x73, 0x79, 0xBA, 0xEC,
194 0xB0, 0xD9, 0x0C, 0xF6, 0xEF, 0x2F, 0xC2, 0xE7, 0x96, 0x9B, 0xA1, 0x2D, 0xE9, 0xFB, 0x45, 0xB9,
195 0xD0, 0x30, 0xE2, 0xBD, 0x30, 0x4F, 0xB6, 0xFE, 0x24, 0x02, 0xCF, 0x8D, 0x51, 0x48, 0x45, 0xD9,
196 0xF7, 0x20, 0x53, 0x1C, 0x0B, 0xA9, 0x7E, 0xC2, 0xA2, 0x65, 0xCC, 0x3E, 0x0E, 0x0D, 0xF1, 0x62,
197 0xDD, 0x5F, 0xBC, 0x55, 0x9B, 0x58, 0x26, 0x40, 0x6A, 0xEE, 0x02, 0x55, 0x36, 0xE9, 0xBA, 0x82,
198 0x5A, 0xFD, 0x3C, 0xDF, 0xA6, 0x26, 0x32, 0x81, 0xA9, 0x5E, 0x46, 0xBE, 0xBA, 0xDC, 0xD3, 0x2A,
199 0x3A, 0x3B, 0xC1, 0x4E, 0xF7, 0x1A, 0xDC, 0x4B, 0xAF, 0x67, 0x1B, 0x3A, 0x83, 0x0D, 0x04, 0xDE,
200 0x27, 0x47, 0xFC, 0xE6, 0x39, 0x89, 0x7B, 0x66, 0xF9, 0x50, 0x4D, 0xF1, 0xAC, 0x20, 0x43, 0x7E,
201 0xEE,
202 ];
203
204 /// DER-encoded PKCS#8 format EC key. Generated using:
205 /// openssl ecparam -name prime256v1 -genkey | openssl pkcs8 -topk8 -nocrypt -outform der | hexdump -e '30/1 "%02X" "\n"'
206 pub static EC_P_256_KEY: &[u8] = &[
207 0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02,
208 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x04, 0x6D, 0x30, 0x6B, 0x02,
209 0x01, 0x01, 0x04, 0x20, 0xB9, 0x1D, 0xAF, 0x50, 0xFD, 0xD8, 0x6A, 0x40, 0xAB, 0x2C, 0xCB, 0x54,
210 0x4E, 0xED, 0xF1, 0x64, 0xBC, 0x30, 0x25, 0xFB, 0xC4, 0x69, 0x00, 0x34, 0x1A, 0x82, 0xA3, 0x72,
211 0x5D, 0xC7, 0xA9, 0x85, 0xA1, 0x44, 0x03, 0x42, 0x00, 0x04, 0xE8, 0x53, 0x0A, 0xF2, 0xD3, 0x68,
212 0x40, 0x48, 0x8C, 0xB4, 0x2F, 0x11, 0x34, 0xD7, 0xF4, 0x4A, 0x5C, 0x33, 0xFF, 0xF6, 0x2B, 0xF7,
213 0x98, 0x0F, 0x02, 0xA5, 0xD7, 0x4F, 0xF9, 0xDE, 0x60, 0x9C, 0x6E, 0xB0, 0x45, 0xDA, 0x3F, 0xF4,
214 0x34, 0x23, 0x9B, 0x4C, 0x3A, 0x09, 0x9C, 0x5E, 0x5D, 0x37, 0x96, 0xAC, 0x4A, 0xE7, 0x65, 0x2B,
215 0xD6, 0x84, 0x98, 0xEA, 0x96, 0x91, 0xFB, 0x78, 0xED, 0x86,
216 ];
217
218 /// DER-encoded PKCS#8 format RSA key -
219 /// Size: 2048
220 /// Public Exponent: 65537
221 /// Purpose: WRAP_KEY, ENCRYPT, DECRYPT
222 /// Encryption scheme: RSAES-PKCS1-v1_5
223 /// Digest: SHA_2_256
224 /// Padding: RSA_OAEP
225 /// This sample wrapping_key is taken from KeyMint tests
226 /// (see hardware/interfaces/security/keymint/aidl/vts/functional/KeyMintTest.cpp).
227 /// Similarly more test keys can be generated with below command -
228 /// openssl genrsa 2048 | openssl pkcs8 -topk8 -nocrypt -outform der | hexdump -e '30/1 "%02X" "\n"'
229 pub static WRAPPING_KEY: &[u8] = &[
230 0x30, 0x82, 0x04, 0xbe, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
231 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x04, 0xa8, 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01,
232 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xae, 0xc3, 0x67, 0x93, 0x1d, 0x89, 0x00, 0xce, 0x56, 0xb0,
233 0x06, 0x7f, 0x7d, 0x70, 0xe1, 0xfc, 0x65, 0x3f, 0x3f, 0x34, 0xd1, 0x94, 0xc1, 0xfe, 0xd5, 0x00,
234 0x18, 0xfb, 0x43, 0xdb, 0x93, 0x7b, 0x06, 0xe6, 0x73, 0xa8, 0x37, 0x31, 0x3d, 0x56, 0xb1, 0xc7,
235 0x25, 0x15, 0x0a, 0x3f, 0xef, 0x86, 0xac, 0xbd, 0xdc, 0x41, 0xbb, 0x75, 0x9c, 0x28, 0x54, 0xea,
236 0xe3, 0x2d, 0x35, 0x84, 0x1e, 0xfb, 0x5c, 0x18, 0xd8, 0x2b, 0xc9, 0x0a, 0x1c, 0xb5, 0xc1, 0xd5,
237 0x5a, 0xdf, 0x24, 0x5b, 0x02, 0x91, 0x1f, 0x0b, 0x7c, 0xda, 0x88, 0xc4, 0x21, 0xff, 0x0e, 0xba,
238 0xfe, 0x7c, 0x0d, 0x23, 0xbe, 0x31, 0x2d, 0x7b, 0xd5, 0x92, 0x1f, 0xfa, 0xea, 0x13, 0x47, 0xc1,
239 0x57, 0x40, 0x6f, 0xef, 0x71, 0x8f, 0x68, 0x26, 0x43, 0xe4, 0xe5, 0xd3, 0x3c, 0x67, 0x03, 0xd6,
240 0x1c, 0x0c, 0xf7, 0xac, 0x0b, 0xf4, 0x64, 0x5c, 0x11, 0xf5, 0xc1, 0x37, 0x4c, 0x38, 0x86, 0x42,
241 0x74, 0x11, 0xc4, 0x49, 0x79, 0x67, 0x92, 0xe0, 0xbe, 0xf7, 0x5d, 0xec, 0x85, 0x8a, 0x21, 0x23,
242 0xc3, 0x67, 0x53, 0xe0, 0x2a, 0x95, 0xa9, 0x6d, 0x7c, 0x45, 0x4b, 0x50, 0x4d, 0xe3, 0x85, 0xa6,
243 0x42, 0xe0, 0xdf, 0xc3, 0xe6, 0x0a, 0xc3, 0xa7, 0xee, 0x49, 0x91, 0xd0, 0xd4, 0x8b, 0x01, 0x72,
244 0xa9, 0x5f, 0x95, 0x36, 0xf0, 0x2b, 0xa1, 0x3c, 0xec, 0xcc, 0xb9, 0x2b, 0x72, 0x7d, 0xb5, 0xc2,
245 0x7e, 0x5b, 0x2f, 0x5c, 0xec, 0x09, 0x60, 0x0b, 0x28, 0x6a, 0xf5, 0xcf, 0x14, 0xc4, 0x20, 0x24,
246 0xc6, 0x1d, 0xdf, 0xe7, 0x1c, 0x2a, 0x8d, 0x74, 0x58, 0xf1, 0x85, 0x23, 0x4c, 0xb0, 0x0e, 0x01,
247 0xd2, 0x82, 0xf1, 0x0f, 0x8f, 0xc6, 0x72, 0x1d, 0x2a, 0xed, 0x3f, 0x48, 0x33, 0xcc, 0xa2, 0xbd,
248 0x8f, 0xa6, 0x28, 0x21, 0xdd, 0x55, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x43,
249 0x14, 0x47, 0xb6, 0x25, 0x19, 0x08, 0x11, 0x2b, 0x1e, 0xe7, 0x6f, 0x99, 0xf3, 0x71, 0x1a, 0x52,
250 0xb6, 0x63, 0x09, 0x60, 0x04, 0x6c, 0x2d, 0xe7, 0x0d, 0xe1, 0x88, 0xd8, 0x33, 0xf8, 0xb8, 0xb9,
251 0x1e, 0x4d, 0x78, 0x5c, 0xae, 0xee, 0xaf, 0x4f, 0x0f, 0x74, 0x41, 0x4e, 0x2c, 0xda, 0x40, 0x64,
252 0x1f, 0x7f, 0xe2, 0x4f, 0x14, 0xc6, 0x7a, 0x88, 0x95, 0x9b, 0xdb, 0x27, 0x76, 0x6d, 0xf9, 0xe7,
253 0x10, 0xb6, 0x30, 0xa0, 0x3a, 0xdc, 0x68, 0x3b, 0x5d, 0x2c, 0x43, 0x08, 0x0e, 0x52, 0xbe, 0xe7,
254 0x1e, 0x9e, 0xae, 0xb6, 0xde, 0x29, 0x7a, 0x5f, 0xea, 0x10, 0x72, 0x07, 0x0d, 0x18, 0x1c, 0x82,
255 0x2b, 0xcc, 0xff, 0x08, 0x7d, 0x63, 0xc9, 0x40, 0xba, 0x8a, 0x45, 0xf6, 0x70, 0xfe, 0xb2, 0x9f,
256 0xb4, 0x48, 0x4d, 0x1c, 0x95, 0xe6, 0xd2, 0x57, 0x9b, 0xa0, 0x2a, 0xae, 0x0a, 0x00, 0x90, 0x0c,
257 0x3e, 0xbf, 0x49, 0x0e, 0x3d, 0x2c, 0xd7, 0xee, 0x8d, 0x0e, 0x20, 0xc5, 0x36, 0xe4, 0xdc, 0x5a,
258 0x50, 0x97, 0x27, 0x28, 0x88, 0xcd, 0xdd, 0x7e, 0x91, 0xf2, 0x28, 0xb1, 0xc4, 0xd7, 0x47, 0x4c,
259 0x55, 0xb8, 0xfc, 0xd6, 0x18, 0xc4, 0xa9, 0x57, 0xbb, 0xdd, 0xd5, 0xad, 0x74, 0x07, 0xcc, 0x31,
260 0x2d, 0x8d, 0x98, 0xa5, 0xca, 0xf7, 0xe0, 0x8f, 0x4a, 0x0d, 0x6b, 0x45, 0xbb, 0x41, 0xc6, 0x52,
261 0x65, 0x9d, 0x5a, 0x5b, 0xa0, 0x5b, 0x66, 0x37, 0x37, 0xa8, 0x69, 0x62, 0x81, 0x86, 0x5b, 0xa2,
262 0x0f, 0xbd, 0xd7, 0xf8, 0x51, 0xe6, 0xc5, 0x6e, 0x8c, 0xbe, 0x0d, 0xdb, 0xbf, 0x24, 0xdc, 0x03,
263 0xb2, 0xd2, 0xcb, 0x4c, 0x3d, 0x54, 0x0f, 0xb0, 0xaf, 0x52, 0xe0, 0x34, 0xa2, 0xd0, 0x66, 0x98,
264 0xb1, 0x28, 0xe5, 0xf1, 0x01, 0xe3, 0xb5, 0x1a, 0x34, 0xf8, 0xd8, 0xb4, 0xf8, 0x61, 0x81, 0x02,
265 0x81, 0x81, 0x00, 0xde, 0x39, 0x2e, 0x18, 0xd6, 0x82, 0xc8, 0x29, 0x26, 0x6c, 0xc3, 0x45, 0x4e,
266 0x1d, 0x61, 0x66, 0x24, 0x2f, 0x32, 0xd9, 0xa1, 0xd1, 0x05, 0x77, 0x75, 0x3e, 0x90, 0x4e, 0xa7,
267 0xd0, 0x8b, 0xff, 0x84, 0x1b, 0xe5, 0xba, 0xc8, 0x2a, 0x16, 0x4c, 0x59, 0x70, 0x00, 0x70, 0x47,
268 0xb8, 0xc5, 0x17, 0xdb, 0x8f, 0x8f, 0x84, 0xe3, 0x7b, 0xd5, 0x98, 0x85, 0x61, 0xbd, 0xf5, 0x03,
269 0xd4, 0xdc, 0x2b, 0xdb, 0x38, 0xf8, 0x85, 0x43, 0x4a, 0xe4, 0x2c, 0x35, 0x5f, 0x72, 0x5c, 0x9a,
270 0x60, 0xf9, 0x1f, 0x07, 0x88, 0xe1, 0xf1, 0xa9, 0x72, 0x23, 0xb5, 0x24, 0xb5, 0x35, 0x7f, 0xdf,
271 0x72, 0xe2, 0xf6, 0x96, 0xba, 0xb7, 0xd7, 0x8e, 0x32, 0xbf, 0x92, 0xba, 0x8e, 0x18, 0x64, 0xea,
272 0xb1, 0x22, 0x9e, 0x91, 0x34, 0x61, 0x30, 0x74, 0x8a, 0x6e, 0x3c, 0x12, 0x4f, 0x91, 0x49, 0xd7,
273 0x1c, 0x74, 0x35, 0x02, 0x81, 0x81, 0x00, 0xc9, 0x53, 0x87, 0xc0, 0xf9, 0xd3, 0x5f, 0x13, 0x7b,
274 0x57, 0xd0, 0xd6, 0x5c, 0x39, 0x7c, 0x5e, 0x21, 0xcc, 0x25, 0x1e, 0x47, 0x00, 0x8e, 0xd6, 0x2a,
275 0x54, 0x24, 0x09, 0xc8, 0xb6, 0xb6, 0xac, 0x7f, 0x89, 0x67, 0xb3, 0x86, 0x3c, 0xa6, 0x45, 0xfc,
276 0xce, 0x49, 0x58, 0x2a, 0x9a, 0xa1, 0x73, 0x49, 0xdb, 0x6c, 0x4a, 0x95, 0xaf, 0xfd, 0xae, 0x0d,
277 0xae, 0x61, 0x2e, 0x1a, 0xfa, 0xc9, 0x9e, 0xd3, 0x9a, 0x2d, 0x93, 0x4c, 0x88, 0x04, 0x40, 0xae,
278 0xd8, 0x83, 0x2f, 0x98, 0x43, 0x16, 0x3a, 0x47, 0xf2, 0x7f, 0x39, 0x21, 0x99, 0xdc, 0x12, 0x02,
279 0xf9, 0xa0, 0xf9, 0xbd, 0x08, 0x30, 0x80, 0x07, 0xcb, 0x1e, 0x4e, 0x7f, 0x58, 0x30, 0x93, 0x66,
280 0xa7, 0xde, 0x25, 0xf7, 0xc3, 0xc9, 0xb8, 0x80, 0x67, 0x7c, 0x06, 0x8e, 0x1b, 0xe9, 0x36, 0xe8,
281 0x12, 0x88, 0x81, 0x52, 0x52, 0xa8, 0xa1, 0x02, 0x81, 0x80, 0x57, 0xff, 0x8c, 0xa1, 0x89, 0x50,
282 0x80, 0xb2, 0xca, 0xe4, 0x86, 0xef, 0x0a, 0xdf, 0xd7, 0x91, 0xfb, 0x02, 0x35, 0xc0, 0xb8, 0xb3,
283 0x6c, 0xd6, 0xc1, 0x36, 0xe5, 0x2e, 0x40, 0x85, 0xf4, 0xea, 0x5a, 0x06, 0x32, 0x12, 0xa4, 0xf1,
284 0x05, 0xa3, 0x76, 0x47, 0x43, 0xe5, 0x32, 0x81, 0x98, 0x8a, 0xba, 0x07, 0x3f, 0x6e, 0x00, 0x27,
285 0x29, 0x8e, 0x1c, 0x43, 0x78, 0x55, 0x6e, 0x0e, 0xfc, 0xa0, 0xe1, 0x4e, 0xce, 0x1a, 0xf7, 0x6a,
286 0xd0, 0xb0, 0x30, 0xf2, 0x7a, 0xf6, 0xf0, 0xab, 0x35, 0xfb, 0x73, 0xa0, 0x60, 0xd8, 0xb1, 0xa0,
287 0xe1, 0x42, 0xfa, 0x26, 0x47, 0xe9, 0x3b, 0x32, 0xe3, 0x6d, 0x82, 0x82, 0xae, 0x0a, 0x4d, 0xe5,
288 0x0a, 0xb7, 0xaf, 0xe8, 0x55, 0x00, 0xa1, 0x6f, 0x43, 0xa6, 0x47, 0x19, 0xd6, 0xe2, 0xb9, 0x43,
289 0x98, 0x23, 0x71, 0x9c, 0xd0, 0x8b, 0xcd, 0x03, 0x17, 0x81, 0x02, 0x81, 0x81, 0x00, 0xba, 0x73,
290 0xb0, 0xbb, 0x28, 0xe3, 0xf8, 0x1e, 0x9b, 0xd1, 0xc5, 0x68, 0x71, 0x3b, 0x10, 0x12, 0x41, 0xac,
291 0xc6, 0x07, 0x97, 0x6c, 0x4d, 0xdc, 0xcc, 0x90, 0xe6, 0x5b, 0x65, 0x56, 0xca, 0x31, 0x51, 0x60,
292 0x58, 0xf9, 0x2b, 0x6e, 0x09, 0xf3, 0xb1, 0x60, 0xff, 0x0e, 0x37, 0x4e, 0xc4, 0x0d, 0x78, 0xae,
293 0x4d, 0x49, 0x79, 0xfd, 0xe6, 0xac, 0x06, 0xa1, 0xa4, 0x00, 0xc6, 0x1d, 0xd3, 0x12, 0x54, 0x18,
294 0x6a, 0xf3, 0x0b, 0x22, 0xc1, 0x05, 0x82, 0xa8, 0xa4, 0x3e, 0x34, 0xfe, 0x94, 0x9c, 0x5f, 0x3b,
295 0x97, 0x55, 0xba, 0xe7, 0xba, 0xa7, 0xb7, 0xb7, 0xa6, 0xbd, 0x03, 0xb3, 0x8c, 0xef, 0x55, 0xc8,
296 0x68, 0x85, 0xfc, 0x6c, 0x19, 0x78, 0xb9, 0xce, 0xe7, 0xef, 0x33, 0xda, 0x50, 0x7c, 0x9d, 0xf6,
297 0xb9, 0x27, 0x7c, 0xff, 0x1e, 0x6a, 0xaa, 0x5d, 0x57, 0xac, 0xa5, 0x28, 0x46, 0x61, 0x02, 0x81,
298 0x81, 0x00, 0xc9, 0x31, 0x61, 0x7c, 0x77, 0x82, 0x9d, 0xfb, 0x12, 0x70, 0x50, 0x2b, 0xe9, 0x19,
299 0x5c, 0x8f, 0x28, 0x30, 0x88, 0x5f, 0x57, 0xdb, 0xa8, 0x69, 0x53, 0x68, 0x11, 0xe6, 0x86, 0x42,
300 0x36, 0xd0, 0xc4, 0x73, 0x6a, 0x00, 0x08, 0xa1, 0x45, 0xaf, 0x36, 0xb8, 0x35, 0x7a, 0x7c, 0x3d,
301 0x13, 0x99, 0x66, 0xd0, 0x4c, 0x4e, 0x00, 0x93, 0x4e, 0xa1, 0xae, 0xde, 0x3b, 0xb6, 0xb8, 0xec,
302 0x84, 0x1d, 0xc9, 0x5e, 0x3f, 0x57, 0x97, 0x51, 0xe2, 0xbf, 0xdf, 0xe2, 0x7a, 0xe7, 0x78, 0x98,
303 0x3f, 0x95, 0x93, 0x56, 0x21, 0x07, 0x23, 0x28, 0x7b, 0x0a, 0xff, 0xcc, 0x9f, 0x72, 0x70, 0x44,
304 0xd4, 0x8c, 0x37, 0x3f, 0x1b, 0xab, 0xde, 0x07, 0x24, 0xfa, 0x17, 0xa4, 0xfd, 0x4d, 0xa0, 0x90,
305 0x2c, 0x7c, 0x9b, 0x9b, 0xf2, 0x7b, 0xa6, 0x1b, 0xe6, 0xad, 0x02, 0xdf, 0xdd, 0xda, 0x8f, 0x4e,
306 0x68, 0x22,
307 ];
308
309 /// WrappedKeyData as ASN.1 DER-encoded data corresponding to the `SecureKeyWrapper` schema
310 /// specified in IKeyMintDevice.aidl. Wrapped key parameters are -
311 /// Algorithm: AES
312 /// Key size: 256
313 /// Block mode: ECB
314 /// Padding mode: PKCS7
315 /// This sample wrapped_key is taken from KeyMint tests (see KeyMintTest.cpp).
316 pub static WRAPPED_KEY: &[u8] = &[
317 0x30, 0x82, 0x01, 0x79, 0x02, 0x01, 0x00, 0x04, 0x82, 0x01, 0x00, 0x93, 0x4b, 0xf9, 0x4e, 0x2a,
318 0xa2, 0x8a, 0x3f, 0x83, 0xc9, 0xf7, 0x92, 0x97, 0x25, 0x02, 0x62, 0xfb, 0xe3, 0x27, 0x6b, 0x5a,
319 0x1c, 0x91, 0x15, 0x9b, 0xbf, 0xa3, 0xef, 0x89, 0x57, 0xaa, 0xc8, 0x4b, 0x59, 0xb3, 0x0b, 0x45,
320 0x5a, 0x79, 0xc2, 0x97, 0x34, 0x80, 0x82, 0x3d, 0x8b, 0x38, 0x63, 0xc3, 0xde, 0xef, 0x4a, 0x8e,
321 0x24, 0x35, 0x90, 0x26, 0x8d, 0x80, 0xe1, 0x87, 0x51, 0xa0, 0xe1, 0x30, 0xf6, 0x7c, 0xe6, 0xa1,
322 0xac, 0xe9, 0xf7, 0x9b, 0x95, 0xe0, 0x97, 0x47, 0x4f, 0xeb, 0xc9, 0x81, 0x19, 0x5b, 0x1d, 0x13,
323 0xa6, 0x90, 0x86, 0xc0, 0x86, 0x3f, 0x66, 0xa7, 0xb7, 0xfd, 0xb4, 0x87, 0x92, 0x22, 0x7b, 0x1a,
324 0xc5, 0xe2, 0x48, 0x9f, 0xeb, 0xdf, 0x08, 0x7a, 0xb5, 0x48, 0x64, 0x83, 0x03, 0x3a, 0x6f, 0x00,
325 0x1c, 0xa5, 0xd1, 0xec, 0x1e, 0x27, 0xf5, 0xc3, 0x0f, 0x4c, 0xec, 0x26, 0x42, 0x07, 0x4a, 0x39,
326 0xae, 0x68, 0xae, 0xe5, 0x52, 0xe1, 0x96, 0x62, 0x7a, 0x8e, 0x3d, 0x86, 0x7e, 0x67, 0xa8, 0xc0,
327 0x1b, 0x11, 0xe7, 0x5f, 0x13, 0xcc, 0xa0, 0xa9, 0x7a, 0xb6, 0x68, 0xb5, 0x0c, 0xda, 0x07, 0xa8,
328 0xec, 0xb7, 0xcd, 0x8e, 0x3d, 0xd7, 0x00, 0x9c, 0x96, 0x36, 0x53, 0x4f, 0x6f, 0x23, 0x9c, 0xff,
329 0xe1, 0xfc, 0x8d, 0xaa, 0x46, 0x6f, 0x78, 0xb6, 0x76, 0xc7, 0x11, 0x9e, 0xfb, 0x96, 0xbc, 0xe4,
330 0xe6, 0x9c, 0xa2, 0xa2, 0x5d, 0x0b, 0x34, 0xed, 0x9c, 0x3f, 0xf9, 0x99, 0xb8, 0x01, 0x59, 0x7d,
331 0x52, 0x20, 0xe3, 0x07, 0xea, 0xa5, 0xbe, 0xe5, 0x07, 0xfb, 0x94, 0xd1, 0xfa, 0x69, 0xf9, 0xe5,
332 0x19, 0xb2, 0xde, 0x31, 0x5b, 0xac, 0x92, 0xc3, 0x6f, 0x2e, 0xa1, 0xfa, 0x1d, 0xf4, 0x47, 0x8c,
333 0x0d, 0xde, 0xde, 0xae, 0x8c, 0x70, 0xe0, 0x23, 0x3c, 0xd0, 0x98, 0x04, 0x0c, 0xd7, 0x96, 0xb0,
334 0x2c, 0x37, 0x0f, 0x1f, 0xa4, 0xcc, 0x01, 0x24, 0xf1, 0x30, 0x2e, 0x02, 0x01, 0x03, 0x30, 0x29,
335 0xa1, 0x08, 0x31, 0x06, 0x02, 0x01, 0x00, 0x02, 0x01, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20, 0xa3,
336 0x04, 0x02, 0x02, 0x01, 0x00, 0xa4, 0x05, 0x31, 0x03, 0x02, 0x01, 0x01, 0xa6, 0x05, 0x31, 0x03,
337 0x02, 0x01, 0x40, 0xbf, 0x83, 0x77, 0x02, 0x05, 0x00, 0x04, 0x20, 0xcc, 0xd5, 0x40, 0x85, 0x5f,
338 0x83, 0x3a, 0x5e, 0x14, 0x80, 0xbf, 0xd2, 0xd3, 0x6f, 0xaf, 0x3a, 0xee, 0xe1, 0x5d, 0xf5, 0xbe,
339 0xab, 0xe2, 0x69, 0x1b, 0xc8, 0x2d, 0xde, 0x2a, 0x7a, 0xa9, 0x10, 0x04, 0x10, 0x64, 0xc9, 0xf6,
340 0x89, 0xc6, 0x0f, 0xf6, 0x22, 0x3a, 0xb6, 0xe6, 0x99, 0x9e, 0x0e, 0xb6, 0xe5,
341 ];
342
343 /// To map Keystore errors.
344 #[derive(thiserror::Error, Debug, Eq, PartialEq)]
345 pub enum Error {
346 /// Keystore2 error code
347 #[error("ResponseCode {0:?}")]
348 Rc(ResponseCode),
349 /// Keymint error code
350 #[error("ErrorCode {0:?}")]
351 Km(ErrorCode),
352 /// Exception
353 #[error("Binder exception {0:?}")]
354 Binder(ExceptionCode),
355 /// This is returned if the C implementation of extractSubjectFromCertificate failed.
356 #[error("Failed to validate certificate chain.")]
357 ValidateCertChainFailed,
358 /// Error code to indicate error in ASN.1 DER-encoded data creation.
359 #[error("Failed to create and encode ASN.1 data.")]
360 DerEncodeFailed,
361 /// Error code to indicate error while using keystore-engine API.
362 #[error("Failed to perform crypto op using keystore-engine APIs.")]
363 Keystore2EngineOpFailed,
364 /// Error code to indicate error in attestation-id validation.
365 #[error("Failed to validate attestation-id.")]
366 ValidateAttestIdFailed,
367 /// Error code to indicate error in getting value from attest record.
368 #[error("Failed to get value from attest record.")]
369 AttestRecordGetValueFailed,
370 }
371
372 /// Keystore2 error mapping.
map_ks_error<T>(r: BinderResult<T>) -> Result<T, Error>373 pub fn map_ks_error<T>(r: BinderResult<T>) -> Result<T, Error> {
374 r.map_err(|s| {
375 match s.exception_code() {
376 ExceptionCode::SERVICE_SPECIFIC => {
377 match s.service_specific_error() {
378 se if se < 0 => {
379 // Negative service specific errors are KM error codes.
380 Error::Km(ErrorCode(se))
381 }
382 se => {
383 // Positive service specific errors are KS response codes.
384 Error::Rc(ResponseCode(se))
385 }
386 }
387 }
388 // We create `Error::Binder` to preserve the exception code
389 // for logging.
390 e_code => Error::Binder(e_code),
391 }
392 })
393 }
394
395 /// Check for a specific KeyMint error.
396 #[macro_export]
397 macro_rules! expect_km_error {
398 { $result:expr, $want:expr } => {
399 match $result {
400 Ok(_) => return Err(format!(
401 "{}:{}: Expected KeyMint error {:?}, found success",
402 file!(),
403 line!(),
404 $want
405 ).into()),
406 Err(s) if s.exception_code() == ExceptionCode::SERVICE_SPECIFIC
407 && s.service_specific_error() == $want.0 => {}
408 Err(e) => return Err(format!(
409 "{}:{}: Expected KeyMint service-specific error {:?}, got {e:?}",
410 file!(),
411 line!(),
412 $want
413 ).into()),
414 }
415
416 };
417 }
418
419 /// Get the value of the given system property, if the given system property doesn't exist
420 /// then returns an empty byte vector.
get_system_prop(name: &str) -> Vec<u8>421 pub fn get_system_prop(name: &str) -> Vec<u8> {
422 match rustutils::system_properties::read(name) {
423 Ok(Some(value)) => value.as_bytes().to_vec(),
424 _ => vec![],
425 }
426 }
427
428 /// Determines whether test is running on GSI.
is_gsi() -> bool429 pub fn is_gsi() -> bool {
430 // This file is only present on GSI builds.
431 PathBuf::from("/system/system_ext/etc/init/init.gsi.rc").as_path().is_file()
432 }
433
434 /// Determines whether the test is on a GSI build where the rkp-only status of the device is
435 /// unknown. GSI replaces the values for remote_prov_prop properties (since they’re
436 /// system_internal_prop properties), so on GSI the properties are not reliable indicators of
437 /// whether StrongBox/TEE is RKP-only or not.
is_rkp_only_unknown_on_gsi(sec_level: SecurityLevel) -> bool438 pub fn is_rkp_only_unknown_on_gsi(sec_level: SecurityLevel) -> bool {
439 if sec_level == SecurityLevel::TRUSTED_ENVIRONMENT {
440 is_gsi() && get_system_prop(TEE_KEYMINT_RKP_ONLY).is_empty()
441 } else {
442 is_gsi() && get_system_prop(STRONGBOX_KEYMINT_RKP_ONLY).is_empty()
443 }
444 }
445
446 /// Verify that given key param is listed in given authorizations list.
check_key_param(authorizations: &[Authorization], key_param: &KeyParameter) -> bool447 pub fn check_key_param(authorizations: &[Authorization], key_param: &KeyParameter) -> bool {
448 authorizations.iter().any(|auth| &auth.keyParameter == key_param)
449 }
450
451 /// Verify the given key authorizations with the expected authorizations.
check_key_authorizations( sl: &SecLevel, authorizations: &[Authorization], expected_params: &[KeyParameter], expected_key_origin: KeyOrigin, )452 pub fn check_key_authorizations(
453 sl: &SecLevel,
454 authorizations: &[Authorization],
455 expected_params: &[KeyParameter],
456 expected_key_origin: KeyOrigin,
457 ) {
458 // Make sure key authorizations contains only `ALLOWED_TAGS_IN_KEY_AUTHS`
459 authorizations.iter().all(|auth| {
460 // Ignore `INVALID` tag
461 if auth.keyParameter.tag == Tag::INVALID {
462 return true;
463 }
464 assert!(
465 ALLOWED_TAGS_IN_KEY_AUTHS.contains(&auth.keyParameter.tag),
466 "key authorization is not allowed: {:#?}",
467 auth.keyParameter
468 );
469 true
470 });
471
472 // Check allowed-expected-key-parameters are present in given key authorizations list.
473 expected_params.iter().all(|key_param| {
474 // `INCLUDE_UNIQUE_ID` is not strictly expected to be in key authorizations but has been
475 // put there by some implementations so cope with that.
476 if key_param.tag == Tag::INCLUDE_UNIQUE_ID
477 && !authorizations.iter().any(|auth| auth.keyParameter.tag == key_param.tag)
478 {
479 return true;
480 }
481
482 // `Tag::RSA_OAEP_MGF_DIGEST` was added in KeyMint 1.0, but the KeyMint VTS tests didn't
483 // originally check for its presence and so some implementations of early versions (< 3) of
484 // the KeyMint HAL don't include it (cf. b/297306437 and aosp/2758513).
485 //
486 // Given that Keymaster implementations will also omit this tag, skip the check for it
487 // altogether (and rely on the updated KeyMint VTS tests to ensure that up-level KeyMint
488 // implementations correctly populate this tag).
489 if matches!(key_param.tag, Tag::RSA_OAEP_MGF_DIGEST) {
490 return true;
491 }
492
493 // Don't check these parameters if the underlying device is a Keymaster implementation.
494 if sl.is_keymaster() {
495 if matches!(
496 key_param.tag,
497 // `Tag::USAGE_COUNT_LIMIT` was added in KeyMint 1.0.
498 Tag::USAGE_COUNT_LIMIT |
499 // Keymaster implementations may not consistently include `Tag::VENDOR_PATCHLEVEL`
500 // in generated key characteristics.
501 Tag::VENDOR_PATCHLEVEL
502 ) {
503 return true;
504 }
505 // `KeyPurpose::ATTEST_KEY` was added in KeyMint 1.0.
506 if key_param.tag == Tag::PURPOSE
507 && key_param.value == KeyParameterValue::KeyPurpose(KeyPurpose::ATTEST_KEY)
508 {
509 return true;
510 }
511 }
512
513 if ALLOWED_TAGS_IN_KEY_AUTHS.contains(&key_param.tag) {
514 assert!(
515 check_key_param(authorizations, key_param),
516 "Key parameter not found: {:#?}",
517 key_param
518 );
519 }
520 true
521 });
522
523 check_common_auths(sl, authorizations, expected_key_origin);
524 }
525
526 /// Verify common key authorizations.
check_common_auths( sl: &SecLevel, authorizations: &[Authorization], expected_key_origin: KeyOrigin, )527 fn check_common_auths(
528 sl: &SecLevel,
529 authorizations: &[Authorization],
530 expected_key_origin: KeyOrigin,
531 ) {
532 assert!(check_key_param(
533 authorizations,
534 &KeyParameter {
535 tag: Tag::OS_VERSION,
536 value: KeyParameterValue::Integer(get_os_version().try_into().unwrap())
537 }
538 ));
539 assert!(check_key_param(
540 authorizations,
541 &KeyParameter {
542 tag: Tag::OS_PATCHLEVEL,
543 value: KeyParameterValue::Integer(get_os_patchlevel().try_into().unwrap())
544 }
545 ));
546
547 assert!(check_key_param(
548 authorizations,
549 &KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(expected_key_origin) }
550 ));
551 assert!(check_key_param(
552 authorizations,
553 &KeyParameter {
554 tag: Tag::USER_ID,
555 value: KeyParameterValue::Integer(
556 rustutils::users::multiuser_get_user_id(ThreadState::get_calling_uid())
557 .try_into()
558 .unwrap()
559 )
560 }
561 ));
562
563 if sl.is_keymint() {
564 assert!(authorizations
565 .iter()
566 .map(|auth| &auth.keyParameter)
567 .any(|key_param| key_param.tag == Tag::CREATION_DATETIME));
568
569 // Access denied for finding vendor-patch-level ("ro.vendor.build.security_patch") property
570 // in a test running with `untrusted_app` context. Keeping this check to verify
571 // vendor-patch-level in tests running with `su` context.
572 if getuid().is_root() {
573 // Keymaster implementations may not consistently include `Tag::VENDOR_PATCHLEVEL`
574 // in generated key characteristics. So, checking this if the underlying device is a
575 // KeyMint implementation.
576 assert!(check_key_param(
577 authorizations,
578 &KeyParameter {
579 tag: Tag::VENDOR_PATCHLEVEL,
580 value: KeyParameterValue::Integer(get_vendor_patchlevel().try_into().unwrap())
581 }
582 ));
583 }
584 }
585 }
586
587 /// Get the key `Authorization` for the given auth `Tag`.
get_key_auth(authorizations: &[Authorization], tag: Tag) -> Option<&Authorization>588 pub fn get_key_auth(authorizations: &[Authorization], tag: Tag) -> Option<&Authorization> {
589 let auths: Vec<&Authorization> =
590 authorizations.iter().filter(|auth| auth.keyParameter.tag == tag).collect();
591
592 if !auths.is_empty() {
593 Some(auths[0])
594 } else {
595 None
596 }
597 }
598
599 /// Generate EC Key using given security level and domain with below key parameters and
600 /// optionally allow the generated key to be attested with factory provisioned attest key using
601 /// given challenge and application id -
602 /// Purposes: SIGN and VERIFY
603 /// Digest: SHA_2_256
604 /// Curve: P_256
generate_ec_p256_signing_key( sl: &SecLevel, domain: Domain, nspace: i64, alias: Option<String>, att_challenge: Option<&[u8]>, ) -> binder::Result<KeyMetadata>605 pub fn generate_ec_p256_signing_key(
606 sl: &SecLevel,
607 domain: Domain,
608 nspace: i64,
609 alias: Option<String>,
610 att_challenge: Option<&[u8]>,
611 ) -> binder::Result<KeyMetadata> {
612 let mut key_attest = false;
613 let mut gen_params = AuthSetBuilder::new()
614 .no_auth_required()
615 .algorithm(Algorithm::EC)
616 .purpose(KeyPurpose::SIGN)
617 .purpose(KeyPurpose::VERIFY)
618 .digest(Digest::SHA_2_256)
619 .ec_curve(EcCurve::P_256);
620
621 if let Some(challenge) = att_challenge {
622 key_attest = true;
623 gen_params = gen_params.clone().attestation_challenge(challenge.to_vec());
624 }
625
626 match sl.binder.generateKey(
627 &KeyDescriptor { domain, nspace, alias, blob: None },
628 None,
629 &gen_params,
630 0,
631 b"entropy",
632 ) {
633 Ok(key_metadata) => {
634 assert!(key_metadata.certificate.is_some());
635 if key_attest {
636 assert!(key_metadata.certificateChain.is_some());
637 }
638 if domain == Domain::BLOB {
639 assert!(key_metadata.key.blob.is_some());
640 }
641
642 check_key_authorizations(
643 sl,
644 &key_metadata.authorizations,
645 &gen_params,
646 KeyOrigin::GENERATED,
647 );
648 Ok(key_metadata)
649 }
650 Err(e) => Err(e),
651 }
652 }
653
654 /// Generate EC signing key.
generate_ec_key( sl: &SecLevel, domain: Domain, nspace: i64, alias: Option<String>, ec_curve: EcCurve, digest: Digest, ) -> binder::Result<KeyMetadata>655 pub fn generate_ec_key(
656 sl: &SecLevel,
657 domain: Domain,
658 nspace: i64,
659 alias: Option<String>,
660 ec_curve: EcCurve,
661 digest: Digest,
662 ) -> binder::Result<KeyMetadata> {
663 let gen_params = AuthSetBuilder::new()
664 .no_auth_required()
665 .algorithm(Algorithm::EC)
666 .purpose(KeyPurpose::SIGN)
667 .purpose(KeyPurpose::VERIFY)
668 .digest(digest)
669 .ec_curve(ec_curve);
670
671 let key_metadata = sl.binder.generateKey(
672 &KeyDescriptor { domain, nspace, alias, blob: None },
673 None,
674 &gen_params,
675 0,
676 b"entropy",
677 )?;
678
679 // Must have a public key.
680 assert!(key_metadata.certificate.is_some());
681
682 // Should not have an attestation record.
683 assert!(key_metadata.certificateChain.is_none());
684
685 if domain == Domain::BLOB {
686 assert!(key_metadata.key.blob.is_some());
687 } else {
688 assert!(key_metadata.key.blob.is_none());
689 }
690 check_key_authorizations(sl, &key_metadata.authorizations, &gen_params, KeyOrigin::GENERATED);
691 Ok(key_metadata)
692 }
693
694 /// Generate a RSA key with the given key parameters, alias, domain and namespace.
generate_rsa_key( sl: &SecLevel, domain: Domain, nspace: i64, alias: Option<String>, key_params: &KeyParams, attest_key: Option<&KeyDescriptor>, ) -> binder::Result<Option<KeyMetadata>>695 pub fn generate_rsa_key(
696 sl: &SecLevel,
697 domain: Domain,
698 nspace: i64,
699 alias: Option<String>,
700 key_params: &KeyParams,
701 attest_key: Option<&KeyDescriptor>,
702 ) -> binder::Result<Option<KeyMetadata>> {
703 let mut gen_params = AuthSetBuilder::new()
704 .no_auth_required()
705 .algorithm(Algorithm::RSA)
706 .rsa_public_exponent(65537)
707 .key_size(key_params.key_size);
708
709 for purpose in &key_params.purpose {
710 gen_params = gen_params.purpose(*purpose);
711 }
712 if let Some(value) = key_params.digest {
713 gen_params = gen_params.digest(value)
714 }
715 if let Some(value) = key_params.padding {
716 gen_params = gen_params.padding_mode(value);
717 }
718 if let Some(value) = key_params.mgf_digest {
719 gen_params = gen_params.mgf_digest(value);
720 }
721 if let Some(value) = key_params.block_mode {
722 gen_params = gen_params.block_mode(value)
723 }
724 if let Some(value) = &key_params.att_challenge {
725 gen_params = gen_params.attestation_challenge(value.to_vec())
726 }
727
728 let key_metadata = match sl.binder.generateKey(
729 &KeyDescriptor { domain, nspace, alias, blob: None },
730 attest_key,
731 &gen_params,
732 0,
733 b"entropy",
734 ) {
735 Ok(metadata) => metadata,
736 Err(e) => {
737 return if is_rkp_only_unknown_on_gsi(sl.level)
738 && e.service_specific_error() == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED.0
739 {
740 // GSI replaces the values for remote_prov_prop properties (since they’re
741 // system_internal_prop properties), so on GSI the properties are not
742 // reliable indicators of whether StrongBox/TEE are RKP-only or not.
743 // Test can be skipped if it generates a key with attestation but doesn't provide
744 // an ATTEST_KEY and rkp-only property is undetermined.
745 Ok(None)
746 } else {
747 Err(e)
748 };
749 }
750 };
751
752 // Must have a public key.
753 assert!(key_metadata.certificate.is_some());
754
755 if attest_key.is_none() && key_params.att_challenge.is_some() {
756 // Should have an attestation record.
757 assert!(key_metadata.certificateChain.is_some());
758 } else {
759 // Should not have an attestation record.
760 assert!(key_metadata.certificateChain.is_none());
761 }
762
763 assert!(
764 (domain == Domain::BLOB && key_metadata.key.blob.is_some())
765 || key_metadata.key.blob.is_none()
766 );
767
768 check_key_authorizations(sl, &key_metadata.authorizations, &gen_params, KeyOrigin::GENERATED);
769 // If `RSA_OAEP_MGF_DIGEST` tag is not mentioned explicitly while generating/importing a key,
770 // then make sure `RSA_OAEP_MGF_DIGEST` tag with default value (SHA1) must not be included in
771 // key authorization list.
772 if key_params.mgf_digest.is_none() {
773 assert!(!check_key_param(
774 &key_metadata.authorizations,
775 &KeyParameter {
776 tag: Tag::RSA_OAEP_MGF_DIGEST,
777 value: KeyParameterValue::Digest(Digest::SHA1)
778 }
779 ));
780 }
781 Ok(Some(key_metadata))
782 }
783
784 /// Generate AES/3DES key.
generate_sym_key( sl: &SecLevel, algorithm: Algorithm, size: i32, alias: &str, padding_mode: &PaddingMode, block_mode: &BlockMode, min_mac_len: Option<i32>, ) -> binder::Result<KeyMetadata>785 pub fn generate_sym_key(
786 sl: &SecLevel,
787 algorithm: Algorithm,
788 size: i32,
789 alias: &str,
790 padding_mode: &PaddingMode,
791 block_mode: &BlockMode,
792 min_mac_len: Option<i32>,
793 ) -> binder::Result<KeyMetadata> {
794 let mut gen_params = AuthSetBuilder::new()
795 .no_auth_required()
796 .algorithm(algorithm)
797 .purpose(KeyPurpose::ENCRYPT)
798 .purpose(KeyPurpose::DECRYPT)
799 .key_size(size)
800 .padding_mode(*padding_mode)
801 .block_mode(*block_mode);
802
803 if let Some(val) = min_mac_len {
804 gen_params = gen_params.min_mac_length(val);
805 }
806
807 let key_metadata = sl.binder.generateKey(
808 &KeyDescriptor {
809 domain: Domain::APP,
810 nspace: -1,
811 alias: Some(alias.to_string()),
812 blob: None,
813 },
814 None,
815 &gen_params,
816 0,
817 b"entropy",
818 )?;
819
820 // Should not have public certificate.
821 assert!(key_metadata.certificate.is_none());
822
823 // Should not have an attestation record.
824 assert!(key_metadata.certificateChain.is_none());
825 check_key_authorizations(sl, &key_metadata.authorizations, &gen_params, KeyOrigin::GENERATED);
826 Ok(key_metadata)
827 }
828
829 /// Generate HMAC key.
generate_hmac_key( sl: &SecLevel, alias: &str, key_size: i32, min_mac_len: i32, digest: Digest, ) -> binder::Result<KeyMetadata>830 pub fn generate_hmac_key(
831 sl: &SecLevel,
832 alias: &str,
833 key_size: i32,
834 min_mac_len: i32,
835 digest: Digest,
836 ) -> binder::Result<KeyMetadata> {
837 let gen_params = AuthSetBuilder::new()
838 .no_auth_required()
839 .algorithm(Algorithm::HMAC)
840 .purpose(KeyPurpose::SIGN)
841 .purpose(KeyPurpose::VERIFY)
842 .key_size(key_size)
843 .min_mac_length(min_mac_len)
844 .digest(digest);
845
846 let key_metadata = sl.binder.generateKey(
847 &KeyDescriptor {
848 domain: Domain::APP,
849 nspace: -1,
850 alias: Some(alias.to_string()),
851 blob: None,
852 },
853 None,
854 &gen_params,
855 0,
856 b"entropy",
857 )?;
858
859 // Should not have public certificate.
860 assert!(key_metadata.certificate.is_none());
861
862 // Should not have an attestation record.
863 assert!(key_metadata.certificateChain.is_none());
864
865 check_key_authorizations(sl, &key_metadata.authorizations, &gen_params, KeyOrigin::GENERATED);
866 Ok(key_metadata)
867 }
868
869 /// Generate RSA or EC attestation keys using below parameters -
870 /// Purpose: ATTEST_KEY
871 /// Digest: Digest::SHA_2_256
872 /// Padding: PaddingMode::RSA_PKCS1_1_5_SIGN
873 /// RSA-Key-Size: 2048
874 /// EC-Curve: EcCurve::P_256
generate_attestation_key( sl: &SecLevel, algorithm: Algorithm, att_challenge: &[u8], ) -> binder::Result<Option<KeyMetadata>>875 pub fn generate_attestation_key(
876 sl: &SecLevel,
877 algorithm: Algorithm,
878 att_challenge: &[u8],
879 ) -> binder::Result<Option<KeyMetadata>> {
880 assert!(algorithm == Algorithm::RSA || algorithm == Algorithm::EC);
881
882 if algorithm == Algorithm::RSA {
883 let alias = "ks_rsa_attest_test_key";
884 generate_rsa_key(
885 sl,
886 Domain::APP,
887 -1,
888 Some(alias.to_string()),
889 &KeyParams {
890 key_size: 2048,
891 purpose: vec![KeyPurpose::ATTEST_KEY],
892 padding: Some(PaddingMode::RSA_PKCS1_1_5_SIGN),
893 digest: Some(Digest::SHA_2_256),
894 mgf_digest: None,
895 block_mode: None,
896 att_challenge: Some(att_challenge.to_vec()),
897 },
898 None,
899 )
900 } else {
901 generate_ec_attestation_key(sl, att_challenge, Digest::SHA_2_256, EcCurve::P_256)
902 }
903 }
904
905 /// Generate EC attestation key with the given
906 /// curve, attestation-challenge and attestation-app-id.
generate_ec_attestation_key( sl: &SecLevel, att_challenge: &[u8], digest: Digest, ec_curve: EcCurve, ) -> binder::Result<Option<KeyMetadata>>907 pub fn generate_ec_attestation_key(
908 sl: &SecLevel,
909 att_challenge: &[u8],
910 digest: Digest,
911 ec_curve: EcCurve,
912 ) -> binder::Result<Option<KeyMetadata>> {
913 let alias = "ks_attest_ec_test_key";
914 let gen_params = AuthSetBuilder::new()
915 .no_auth_required()
916 .algorithm(Algorithm::EC)
917 .purpose(KeyPurpose::ATTEST_KEY)
918 .ec_curve(ec_curve)
919 .digest(digest)
920 .attestation_challenge(att_challenge.to_vec());
921
922 let attestation_key_metadata = match sl.binder.generateKey(
923 &KeyDescriptor {
924 domain: Domain::APP,
925 nspace: -1,
926 alias: Some(alias.to_string()),
927 blob: None,
928 },
929 None,
930 &gen_params,
931 0,
932 b"entropy",
933 ) {
934 Ok(metadata) => metadata,
935 Err(e) => {
936 return if is_rkp_only_unknown_on_gsi(sl.level)
937 && e.service_specific_error() == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED.0
938 {
939 // GSI replaces the values for remote_prov_prop properties (since they’re
940 // system_internal_prop properties), so on GSI the properties are not
941 // reliable indicators of whether StrongBox/TEE are RKP-only or not.
942 // Test can be skipped if it generates a key with attestation but doesn't provide
943 // an ATTEST_KEY and rkp-only property is undetermined.
944 Ok(None)
945 } else {
946 Err(e)
947 };
948 }
949 };
950
951 // Should have public certificate.
952 assert!(attestation_key_metadata.certificate.is_some());
953 // Should have an attestation record.
954 assert!(attestation_key_metadata.certificateChain.is_some());
955
956 check_key_authorizations(
957 sl,
958 &attestation_key_metadata.authorizations,
959 &gen_params,
960 KeyOrigin::GENERATED,
961 );
962 Ok(Some(attestation_key_metadata))
963 }
964
965 /// Generate EC-P-256 key and attest it with given attestation key.
generate_ec_256_attested_key( sl: &SecLevel, alias: Option<String>, att_challenge: &[u8], attest_key: &KeyDescriptor, ) -> binder::Result<KeyMetadata>966 pub fn generate_ec_256_attested_key(
967 sl: &SecLevel,
968 alias: Option<String>,
969 att_challenge: &[u8],
970 attest_key: &KeyDescriptor,
971 ) -> binder::Result<KeyMetadata> {
972 let ec_gen_params = AuthSetBuilder::new()
973 .no_auth_required()
974 .algorithm(Algorithm::EC)
975 .purpose(KeyPurpose::SIGN)
976 .purpose(KeyPurpose::VERIFY)
977 .digest(Digest::SHA_2_256)
978 .ec_curve(EcCurve::P_256)
979 .attestation_challenge(att_challenge.to_vec());
980
981 let ec_key_metadata = sl
982 .binder
983 .generateKey(
984 &KeyDescriptor { domain: Domain::APP, nspace: -1, alias, blob: None },
985 Some(attest_key),
986 &ec_gen_params,
987 0,
988 b"entropy",
989 )
990 .unwrap();
991
992 // Should have public certificate.
993 assert!(ec_key_metadata.certificate.is_some());
994 // Shouldn't have an attestation record.
995 assert!(ec_key_metadata.certificateChain.is_none());
996
997 check_key_authorizations(
998 sl,
999 &ec_key_metadata.authorizations,
1000 &ec_gen_params,
1001 KeyOrigin::GENERATED,
1002 );
1003 Ok(ec_key_metadata)
1004 }
1005
1006 /// Imports above defined RSA key - `RSA_2048_KEY` and validates imported key parameters.
import_rsa_2048_key( sl: &SecLevel, domain: Domain, nspace: i64, alias: Option<String>, import_params: AuthSetBuilder, ) -> binder::Result<KeyMetadata>1007 pub fn import_rsa_2048_key(
1008 sl: &SecLevel,
1009 domain: Domain,
1010 nspace: i64,
1011 alias: Option<String>,
1012 import_params: AuthSetBuilder,
1013 ) -> binder::Result<KeyMetadata> {
1014 let key_metadata = sl
1015 .binder
1016 .importKey(
1017 &KeyDescriptor { domain, nspace, alias, blob: None },
1018 None,
1019 &import_params,
1020 0,
1021 RSA_2048_KEY,
1022 )
1023 .unwrap();
1024
1025 assert!(key_metadata.certificate.is_some());
1026 assert!(key_metadata.certificateChain.is_none());
1027
1028 check_key_authorizations(sl, &key_metadata.authorizations, &import_params, KeyOrigin::IMPORTED);
1029
1030 // Check below auths explicitly, they might not be addd in import parameters.
1031 assert!(check_key_param(
1032 &key_metadata.authorizations,
1033 &KeyParameter { tag: Tag::ALGORITHM, value: KeyParameterValue::Algorithm(Algorithm::RSA) }
1034 ));
1035
1036 assert!(check_key_param(
1037 &key_metadata.authorizations,
1038 &KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(2048) }
1039 ));
1040
1041 assert!(check_key_param(
1042 &key_metadata.authorizations,
1043 &KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) }
1044 ));
1045
1046 assert!(check_key_param(
1047 &key_metadata.authorizations,
1048 &KeyParameter {
1049 tag: Tag::RSA_PUBLIC_EXPONENT,
1050 value: KeyParameterValue::LongInteger(65537)
1051 }
1052 ));
1053
1054 assert!(check_key_param(
1055 &key_metadata.authorizations,
1056 &KeyParameter {
1057 tag: Tag::PADDING,
1058 value: KeyParameterValue::PaddingMode(PaddingMode::RSA_PSS)
1059 }
1060 ));
1061
1062 assert!(check_key_param(
1063 &key_metadata.authorizations,
1064 &KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
1065 ));
1066
1067 Ok(key_metadata)
1068 }
1069
1070 /// Imports above defined EC key - `EC_P_256_KEY` and validates imported key parameters.
import_ec_p_256_key( sl: &SecLevel, domain: Domain, nspace: i64, alias: Option<String>, import_params: AuthSetBuilder, ) -> binder::Result<KeyMetadata>1071 pub fn import_ec_p_256_key(
1072 sl: &SecLevel,
1073 domain: Domain,
1074 nspace: i64,
1075 alias: Option<String>,
1076 import_params: AuthSetBuilder,
1077 ) -> binder::Result<KeyMetadata> {
1078 let key_metadata = sl
1079 .binder
1080 .importKey(
1081 &KeyDescriptor { domain, nspace, alias, blob: None },
1082 None,
1083 &import_params,
1084 0,
1085 EC_P_256_KEY,
1086 )
1087 .unwrap();
1088
1089 assert!(key_metadata.certificate.is_some());
1090 assert!(key_metadata.certificateChain.is_none());
1091
1092 check_key_authorizations(sl, &key_metadata.authorizations, &import_params, KeyOrigin::IMPORTED);
1093
1094 // Check below auths explicitly, they might not be addd in import parameters.
1095 assert!(check_key_param(
1096 &key_metadata.authorizations,
1097 &KeyParameter { tag: Tag::ALGORITHM, value: KeyParameterValue::Algorithm(Algorithm::EC) }
1098 ));
1099
1100 assert!(check_key_param(
1101 &key_metadata.authorizations,
1102 &KeyParameter { tag: Tag::EC_CURVE, value: KeyParameterValue::EcCurve(EcCurve::P_256) }
1103 ));
1104
1105 assert!(check_key_param(
1106 &key_metadata.authorizations,
1107 &KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) }
1108 ));
1109 assert!(check_key_param(
1110 &key_metadata.authorizations,
1111 &KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
1112 ));
1113
1114 Ok(key_metadata)
1115 }
1116
1117 /// Import sample AES key and validate its key parameters.
import_aes_key( sl: &SecLevel, domain: Domain, nspace: i64, alias: Option<String>, ) -> binder::Result<KeyMetadata>1118 pub fn import_aes_key(
1119 sl: &SecLevel,
1120 domain: Domain,
1121 nspace: i64,
1122 alias: Option<String>,
1123 ) -> binder::Result<KeyMetadata> {
1124 static AES_KEY: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
1125 let key_size = AES_KEY.len() * 8;
1126
1127 let import_params = AuthSetBuilder::new()
1128 .no_auth_required()
1129 .algorithm(Algorithm::AES)
1130 .block_mode(BlockMode::ECB)
1131 .key_size(key_size.try_into().unwrap())
1132 .purpose(KeyPurpose::ENCRYPT)
1133 .purpose(KeyPurpose::DECRYPT)
1134 .padding_mode(PaddingMode::PKCS7);
1135
1136 let key_metadata = sl.binder.importKey(
1137 &KeyDescriptor { domain, nspace, alias, blob: None },
1138 None,
1139 &import_params,
1140 0,
1141 AES_KEY,
1142 )?;
1143
1144 check_key_authorizations(sl, &key_metadata.authorizations, &import_params, KeyOrigin::IMPORTED);
1145
1146 // Check below auths explicitly, they might not be addd in import parameters.
1147 assert!(check_key_param(
1148 &key_metadata.authorizations,
1149 &KeyParameter { tag: Tag::ALGORITHM, value: KeyParameterValue::Algorithm(Algorithm::AES) }
1150 ));
1151 assert!(check_key_param(
1152 &key_metadata.authorizations,
1153 &KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) }
1154 ));
1155 assert!(check_key_param(
1156 &key_metadata.authorizations,
1157 &KeyParameter {
1158 tag: Tag::PADDING,
1159 value: KeyParameterValue::PaddingMode(PaddingMode::PKCS7)
1160 }
1161 ));
1162 assert!(check_key_param(
1163 &key_metadata.authorizations,
1164 &KeyParameter { tag: Tag::BLOCK_MODE, value: KeyParameterValue::BlockMode(BlockMode::ECB) }
1165 ));
1166 assert!(check_key_param(
1167 &key_metadata.authorizations,
1168 &KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
1169 ));
1170
1171 Ok(key_metadata)
1172 }
1173
1174 /// Import sample 3DES key and validate its key parameters.
import_3des_key( sl: &SecLevel, domain: Domain, nspace: i64, alias: Option<String>, ) -> binder::Result<KeyMetadata>1175 pub fn import_3des_key(
1176 sl: &SecLevel,
1177 domain: Domain,
1178 nspace: i64,
1179 alias: Option<String>,
1180 ) -> binder::Result<KeyMetadata> {
1181 static TRIPLE_DES_KEY: &[u8] = &[
1182 0xa4, 0x9d, 0x75, 0x64, 0x19, 0x9e, 0x97, 0xcb, 0x52, 0x9d, 0x2c, 0x9d, 0x97, 0xbf, 0x2f,
1183 0x98, 0xd3, 0x5e, 0xdf, 0x57, 0xba, 0x1f, 0x73, 0x58,
1184 ];
1185
1186 let import_params = AuthSetBuilder::new()
1187 .no_auth_required()
1188 .algorithm(Algorithm::TRIPLE_DES)
1189 .block_mode(BlockMode::ECB)
1190 .key_size(168)
1191 .purpose(KeyPurpose::ENCRYPT)
1192 .purpose(KeyPurpose::DECRYPT)
1193 .padding_mode(PaddingMode::PKCS7);
1194
1195 let key_metadata = sl.binder.importKey(
1196 &KeyDescriptor { domain, nspace, alias, blob: None },
1197 None,
1198 &import_params,
1199 0,
1200 TRIPLE_DES_KEY,
1201 )?;
1202
1203 check_key_authorizations(sl, &key_metadata.authorizations, &import_params, KeyOrigin::IMPORTED);
1204
1205 // Check below auths explicitly, they might not be addd in import parameters.
1206 assert!(check_key_param(
1207 &key_metadata.authorizations,
1208 &KeyParameter {
1209 tag: Tag::ALGORITHM,
1210 value: KeyParameterValue::Algorithm(Algorithm::TRIPLE_DES)
1211 }
1212 ));
1213 assert!(check_key_param(
1214 &key_metadata.authorizations,
1215 &KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(168) }
1216 ));
1217 assert!(check_key_param(
1218 &key_metadata.authorizations,
1219 &KeyParameter {
1220 tag: Tag::PADDING,
1221 value: KeyParameterValue::PaddingMode(PaddingMode::PKCS7)
1222 }
1223 ));
1224 assert!(check_key_param(
1225 &key_metadata.authorizations,
1226 &KeyParameter { tag: Tag::BLOCK_MODE, value: KeyParameterValue::BlockMode(BlockMode::ECB) }
1227 ));
1228 assert!(check_key_param(
1229 &key_metadata.authorizations,
1230 &KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
1231 ));
1232
1233 Ok(key_metadata)
1234 }
1235
1236 /// Import sample HMAC key and validate its key parameters.
import_hmac_key( sl: &SecLevel, domain: Domain, nspace: i64, alias: Option<String>, ) -> binder::Result<KeyMetadata>1237 pub fn import_hmac_key(
1238 sl: &SecLevel,
1239 domain: Domain,
1240 nspace: i64,
1241 alias: Option<String>,
1242 ) -> binder::Result<KeyMetadata> {
1243 static HMAC_KEY: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
1244 let key_size = HMAC_KEY.len() * 8;
1245
1246 let import_params = AuthSetBuilder::new()
1247 .no_auth_required()
1248 .algorithm(Algorithm::HMAC)
1249 .key_size(key_size.try_into().unwrap())
1250 .purpose(KeyPurpose::SIGN)
1251 .purpose(KeyPurpose::VERIFY)
1252 .digest(Digest::SHA_2_256)
1253 .min_mac_length(256);
1254
1255 let key_metadata = sl.binder.importKey(
1256 &KeyDescriptor { domain, nspace, alias, blob: None },
1257 None,
1258 &import_params,
1259 0,
1260 HMAC_KEY,
1261 )?;
1262
1263 check_key_authorizations(sl, &key_metadata.authorizations, &import_params, KeyOrigin::IMPORTED);
1264
1265 // Check below auths explicitly, they might not be addd in import parameters.
1266 assert!(check_key_param(
1267 &key_metadata.authorizations,
1268 &KeyParameter { tag: Tag::ALGORITHM, value: KeyParameterValue::Algorithm(Algorithm::HMAC) }
1269 ));
1270 assert!(check_key_param(
1271 &key_metadata.authorizations,
1272 &KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) }
1273 ));
1274 assert!(check_key_param(
1275 &key_metadata.authorizations,
1276 &KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) }
1277 ));
1278 assert!(check_key_param(
1279 &key_metadata.authorizations,
1280 &KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
1281 ));
1282
1283 Ok(key_metadata)
1284 }
1285
1286 /// Imports RSA encryption key with WRAP_KEY purpose.
import_wrapping_key( sl: &SecLevel, wrapping_key_data: &[u8], wrapping_key_alias: Option<String>, ) -> binder::Result<KeyMetadata>1287 pub fn import_wrapping_key(
1288 sl: &SecLevel,
1289 wrapping_key_data: &[u8],
1290 wrapping_key_alias: Option<String>,
1291 ) -> binder::Result<KeyMetadata> {
1292 let wrapping_key_params = AuthSetBuilder::new()
1293 .no_auth_required()
1294 .algorithm(Algorithm::RSA)
1295 .digest(Digest::SHA_2_256)
1296 .purpose(KeyPurpose::ENCRYPT)
1297 .purpose(KeyPurpose::DECRYPT)
1298 .purpose(KeyPurpose::WRAP_KEY)
1299 .padding_mode(PaddingMode::RSA_OAEP)
1300 .key_size(2048)
1301 .rsa_public_exponent(65537)
1302 .cert_not_before(0)
1303 .cert_not_after(253402300799000);
1304
1305 sl.binder.importKey(
1306 &KeyDescriptor { domain: Domain::APP, nspace: -1, alias: wrapping_key_alias, blob: None },
1307 None,
1308 &wrapping_key_params,
1309 0,
1310 wrapping_key_data,
1311 )
1312 }
1313
1314 /// Import wrapped key using given wrapping key.
import_wrapped_key( sl: &SecLevel, alias: Option<String>, wrapping_key_metadata: &KeyMetadata, wrapped_key: Option<Vec<u8>>, ) -> binder::Result<KeyMetadata>1315 pub fn import_wrapped_key(
1316 sl: &SecLevel,
1317 alias: Option<String>,
1318 wrapping_key_metadata: &KeyMetadata,
1319 wrapped_key: Option<Vec<u8>>,
1320 ) -> binder::Result<KeyMetadata> {
1321 let unwrap_params =
1322 AuthSetBuilder::new().digest(Digest::SHA_2_256).padding_mode(PaddingMode::RSA_OAEP);
1323
1324 let authenticator_spec: &[AuthenticatorSpec] = &[AuthenticatorSpec {
1325 authenticatorType: HardwareAuthenticatorType::NONE,
1326 authenticatorId: 0,
1327 }];
1328
1329 let key_metadata = sl.binder.importWrappedKey(
1330 &KeyDescriptor { domain: Domain::APP, nspace: -1, alias, blob: wrapped_key },
1331 &wrapping_key_metadata.key,
1332 None,
1333 &unwrap_params,
1334 authenticator_spec,
1335 )?;
1336
1337 Ok(key_metadata)
1338 }
1339
1340 /// Import wrapping key and then import wrapped key using wrapping key.
import_wrapping_key_and_wrapped_key( sl: &SecLevel, domain: Domain, nspace: i64, alias: Option<String>, wrapping_key_alias: Option<String>, wrapping_key_params: AuthSetBuilder, ) -> binder::Result<KeyMetadata>1341 pub fn import_wrapping_key_and_wrapped_key(
1342 sl: &SecLevel,
1343 domain: Domain,
1344 nspace: i64,
1345 alias: Option<String>,
1346 wrapping_key_alias: Option<String>,
1347 wrapping_key_params: AuthSetBuilder,
1348 ) -> binder::Result<KeyMetadata> {
1349 let wrapping_key_metadata = sl.binder.importKey(
1350 &KeyDescriptor { domain, nspace, alias: wrapping_key_alias, blob: None },
1351 None,
1352 &wrapping_key_params,
1353 0,
1354 WRAPPING_KEY,
1355 )?;
1356
1357 import_wrapped_key(sl, alias, &wrapping_key_metadata, Some(WRAPPED_KEY.to_vec()))
1358 }
1359
1360 /// Import given key material as AES-256-GCM-NONE transport key.
import_transport_key( sl: &SecLevel, transport_key_alias: Option<String>, transport_key: &[u8], ) -> binder::Result<KeyMetadata>1361 pub fn import_transport_key(
1362 sl: &SecLevel,
1363 transport_key_alias: Option<String>,
1364 transport_key: &[u8],
1365 ) -> binder::Result<KeyMetadata> {
1366 let transport_key_params = AuthSetBuilder::new()
1367 .no_auth_required()
1368 .algorithm(Algorithm::AES)
1369 .block_mode(BlockMode::GCM)
1370 .padding_mode(PaddingMode::NONE)
1371 .key_size(256)
1372 .caller_nonce()
1373 .min_mac_length(128)
1374 .purpose(KeyPurpose::ENCRYPT)
1375 .purpose(KeyPurpose::DECRYPT);
1376
1377 sl.binder.importKey(
1378 &KeyDescriptor { domain: Domain::APP, nspace: -1, alias: transport_key_alias, blob: None },
1379 None,
1380 &transport_key_params,
1381 0,
1382 transport_key,
1383 )
1384 }
1385
1386 /// Generate EC key with purpose AGREE_KEY.
generate_ec_agree_key( sl: &SecLevel, ec_curve: EcCurve, digest: Digest, domain: Domain, nspace: i64, alias: Option<String>, ) -> binder::Result<KeyMetadata>1387 pub fn generate_ec_agree_key(
1388 sl: &SecLevel,
1389 ec_curve: EcCurve,
1390 digest: Digest,
1391 domain: Domain,
1392 nspace: i64,
1393 alias: Option<String>,
1394 ) -> binder::Result<KeyMetadata> {
1395 let gen_params = AuthSetBuilder::new()
1396 .no_auth_required()
1397 .algorithm(Algorithm::EC)
1398 .purpose(KeyPurpose::AGREE_KEY)
1399 .digest(digest)
1400 .ec_curve(ec_curve);
1401
1402 match sl.binder.generateKey(
1403 &KeyDescriptor { domain, nspace, alias, blob: None },
1404 None,
1405 &gen_params,
1406 0,
1407 b"entropy",
1408 ) {
1409 Ok(key_metadata) => {
1410 assert!(key_metadata.certificate.is_some());
1411 if domain == Domain::BLOB {
1412 assert!(key_metadata.key.blob.is_some());
1413 }
1414
1415 check_key_authorizations(
1416 sl,
1417 &key_metadata.authorizations,
1418 &gen_params,
1419 KeyOrigin::GENERATED,
1420 );
1421 Ok(key_metadata)
1422 }
1423 Err(e) => Err(e),
1424 }
1425 }
1426
1427 /// Helper method to import AES keys `total_count` of times.
import_aes_keys( sl: &SecLevel, alias_prefix: String, total_count: Range<i32>, ) -> binder::Result<HashSet<String>>1428 pub fn import_aes_keys(
1429 sl: &SecLevel,
1430 alias_prefix: String,
1431 total_count: Range<i32>,
1432 ) -> binder::Result<HashSet<String>> {
1433 let mut imported_key_aliases = HashSet::new();
1434
1435 // Import Total number of keys with given alias prefix.
1436 for count in total_count {
1437 let mut alias = String::new();
1438 write!(alias, "{}_{}", alias_prefix, count).unwrap();
1439 imported_key_aliases.insert(alias.clone());
1440
1441 import_aes_key(sl, Domain::APP, -1, Some(alias))?;
1442 }
1443
1444 Ok(imported_key_aliases)
1445 }
1446
1447 /// Generate attested EC-P_256 key with device id attestation.
generate_key_with_attest_id( sl: &SecLevel, algorithm: Algorithm, alias: Option<String>, att_challenge: &[u8], attest_key: &KeyDescriptor, attest_id: Tag, value: Vec<u8>, ) -> binder::Result<KeyMetadata>1448 pub fn generate_key_with_attest_id(
1449 sl: &SecLevel,
1450 algorithm: Algorithm,
1451 alias: Option<String>,
1452 att_challenge: &[u8],
1453 attest_key: &KeyDescriptor,
1454 attest_id: Tag,
1455 value: Vec<u8>,
1456 ) -> binder::Result<KeyMetadata> {
1457 assert!(algorithm == Algorithm::RSA || algorithm == Algorithm::EC);
1458
1459 let mut ec_gen_params;
1460 if algorithm == Algorithm::EC {
1461 ec_gen_params = AuthSetBuilder::new()
1462 .no_auth_required()
1463 .algorithm(Algorithm::EC)
1464 .purpose(KeyPurpose::SIGN)
1465 .purpose(KeyPurpose::VERIFY)
1466 .digest(Digest::SHA_2_256)
1467 .ec_curve(EcCurve::P_256)
1468 .attestation_challenge(att_challenge.to_vec());
1469 } else {
1470 ec_gen_params = AuthSetBuilder::new()
1471 .no_auth_required()
1472 .algorithm(Algorithm::RSA)
1473 .rsa_public_exponent(65537)
1474 .key_size(2048)
1475 .purpose(KeyPurpose::SIGN)
1476 .purpose(KeyPurpose::VERIFY)
1477 .digest(Digest::SHA_2_256)
1478 .padding_mode(PaddingMode::RSA_PKCS1_1_5_SIGN)
1479 .attestation_challenge(att_challenge.to_vec());
1480 }
1481
1482 match attest_id {
1483 Tag::ATTESTATION_ID_BRAND => {
1484 ec_gen_params = ec_gen_params.attestation_device_brand(value);
1485 }
1486 Tag::ATTESTATION_ID_DEVICE => {
1487 ec_gen_params = ec_gen_params.attestation_device_name(value);
1488 }
1489 Tag::ATTESTATION_ID_PRODUCT => {
1490 ec_gen_params = ec_gen_params.attestation_device_product_name(value);
1491 }
1492 Tag::ATTESTATION_ID_SERIAL => {
1493 ec_gen_params = ec_gen_params.attestation_device_serial(value);
1494 }
1495 Tag::ATTESTATION_ID_MANUFACTURER => {
1496 ec_gen_params = ec_gen_params.attestation_device_manufacturer(value);
1497 }
1498 Tag::ATTESTATION_ID_MODEL => {
1499 ec_gen_params = ec_gen_params.attestation_device_model(value);
1500 }
1501 Tag::ATTESTATION_ID_IMEI => {
1502 ec_gen_params = ec_gen_params.attestation_device_imei(value);
1503 }
1504 Tag::ATTESTATION_ID_SECOND_IMEI => {
1505 ec_gen_params = ec_gen_params.attestation_device_second_imei(value);
1506 }
1507 _ => {
1508 panic!("Unknown attestation id");
1509 }
1510 }
1511
1512 sl.binder.generateKey(
1513 &KeyDescriptor { domain: Domain::APP, nspace: -1, alias, blob: None },
1514 Some(attest_key),
1515 &ec_gen_params,
1516 0,
1517 b"entropy",
1518 )
1519 }
1520
1521 /// Generate Key and validate key characteristics.
generate_key( sl: &SecLevel, gen_params: &AuthSetBuilder, alias: &str, ) -> binder::Result<Option<KeyMetadata>>1522 pub fn generate_key(
1523 sl: &SecLevel,
1524 gen_params: &AuthSetBuilder,
1525 alias: &str,
1526 ) -> binder::Result<Option<KeyMetadata>> {
1527 let key_metadata = match sl.binder.generateKey(
1528 &KeyDescriptor {
1529 domain: Domain::APP,
1530 nspace: -1,
1531 alias: Some(alias.to_string()),
1532 blob: None,
1533 },
1534 None,
1535 gen_params,
1536 0,
1537 b"entropy",
1538 ) {
1539 Ok(metadata) => metadata,
1540 Err(e) => {
1541 return if is_rkp_only_unknown_on_gsi(sl.level)
1542 && e.service_specific_error() == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED.0
1543 {
1544 // GSI replaces the values for remote_prov_prop properties (since they’re
1545 // system_internal_prop properties), so on GSI the properties are not
1546 // reliable indicators of whether StrongBox/TEE are RKP-only or not.
1547 // Test can be skipped if it generates a key with attestation but doesn't provide
1548 // an ATTEST_KEY and rkp-only property is undetermined.
1549 Ok(None)
1550 } else {
1551 Err(e)
1552 };
1553 }
1554 };
1555
1556 if gen_params.iter().any(|kp| {
1557 matches!(
1558 kp.value,
1559 KeyParameterValue::Algorithm(Algorithm::RSA)
1560 | KeyParameterValue::Algorithm(Algorithm::EC)
1561 )
1562 }) {
1563 assert!(key_metadata.certificate.is_some());
1564 if gen_params.iter().any(|kp| kp.tag == Tag::ATTESTATION_CHALLENGE) {
1565 assert!(key_metadata.certificateChain.is_some());
1566 let mut cert_chain: Vec<u8> = Vec::new();
1567 cert_chain.extend(key_metadata.certificate.as_ref().unwrap());
1568 cert_chain.extend(key_metadata.certificateChain.as_ref().unwrap());
1569 let strict_issuer_check =
1570 !(gen_params.iter().any(|kp| kp.tag == Tag::DEVICE_UNIQUE_ATTESTATION));
1571 validate_certchain_with_strict_issuer_check(&cert_chain, strict_issuer_check)
1572 .expect("Error while validating cert chain");
1573 }
1574
1575 if let Some(challenge_param) =
1576 gen_params.iter().find(|kp| kp.tag == Tag::ATTESTATION_CHALLENGE)
1577 {
1578 if let KeyParameterValue::Blob(val) = &challenge_param.value {
1579 let att_challenge = get_value_from_attest_record(
1580 key_metadata.certificate.as_ref().unwrap(),
1581 challenge_param.tag,
1582 key_metadata.keySecurityLevel,
1583 )
1584 .expect("Attestation challenge verification failed.");
1585 assert_eq!(&att_challenge, val);
1586 }
1587
1588 let att_app_id = get_value_from_attest_record(
1589 key_metadata.certificate.as_ref().unwrap(),
1590 Tag::ATTESTATION_APPLICATION_ID,
1591 SecurityLevel::KEYSTORE,
1592 )
1593 .expect("Attestation application id verification failed.");
1594 assert!(!att_app_id.is_empty());
1595 }
1596 }
1597 check_key_authorizations(sl, &key_metadata.authorizations, gen_params, KeyOrigin::GENERATED);
1598
1599 Ok(Some(key_metadata))
1600 }
1601
1602 /// Generate a key using given authorizations and create an operation using the generated key.
create_key_and_operation( sl: &SecLevel, gen_params: &AuthSetBuilder, op_params: &AuthSetBuilder, alias: &str, ) -> binder::Result<Option<CreateOperationResponse>>1603 pub fn create_key_and_operation(
1604 sl: &SecLevel,
1605 gen_params: &AuthSetBuilder,
1606 op_params: &AuthSetBuilder,
1607 alias: &str,
1608 ) -> binder::Result<Option<CreateOperationResponse>> {
1609 let Some(key_metadata) = generate_key(sl, gen_params, alias)? else {
1610 return Ok(None);
1611 };
1612
1613 sl.binder.createOperation(&key_metadata.key, op_params, false).map(Some)
1614 }
1615