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 if is_gsi() && sl.is_keymaster() {
540 // The expected value of TAG::OS_PATCHLEVEL should match the system's reported
541 // OS patch level (obtained via get_os_patchlevel()). However, booting a Generic System
542 // Image (GSI) with a newer patch level is permitted. Therefore, the generated key's
543 // TAG::OS_PATCHLEVEL may be less than or equal to the current system's OS patch level.
544 assert!(authorizations.iter().map(|auth| &auth.keyParameter).any(|key_param| key_param
545 .tag
546 == Tag::OS_PATCHLEVEL
547 && key_param.value
548 <= KeyParameterValue::Integer(get_os_patchlevel().try_into().unwrap())));
549 } else {
550 // The KeyMint spec required that the patch-levels match that of the running system, even
551 // under GSI.
552 assert!(check_key_param(
553 authorizations,
554 &KeyParameter {
555 tag: Tag::OS_PATCHLEVEL,
556 value: KeyParameterValue::Integer(get_os_patchlevel().try_into().unwrap())
557 }
558 ));
559 }
560
561 assert!(check_key_param(
562 authorizations,
563 &KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(expected_key_origin) }
564 ));
565 assert!(check_key_param(
566 authorizations,
567 &KeyParameter {
568 tag: Tag::USER_ID,
569 value: KeyParameterValue::Integer(
570 rustutils::users::multiuser_get_user_id(ThreadState::get_calling_uid())
571 .try_into()
572 .unwrap()
573 )
574 }
575 ));
576
577 if sl.is_keymint() {
578 assert!(authorizations
579 .iter()
580 .map(|auth| &auth.keyParameter)
581 .any(|key_param| key_param.tag == Tag::CREATION_DATETIME));
582
583 // Access denied for finding vendor-patch-level ("ro.vendor.build.security_patch") property
584 // in a test running with `untrusted_app` context. Keeping this check to verify
585 // vendor-patch-level in tests running with `su` context.
586 if getuid().is_root() {
587 // Keymaster implementations may not consistently include `Tag::VENDOR_PATCHLEVEL`
588 // in generated key characteristics. So, checking this if the underlying device is a
589 // KeyMint implementation.
590 assert!(check_key_param(
591 authorizations,
592 &KeyParameter {
593 tag: Tag::VENDOR_PATCHLEVEL,
594 value: KeyParameterValue::Integer(get_vendor_patchlevel().try_into().unwrap())
595 }
596 ));
597 }
598 }
599 }
600
601 /// Get the key `Authorization` for the given auth `Tag`.
get_key_auth(authorizations: &[Authorization], tag: Tag) -> Option<&Authorization>602 pub fn get_key_auth(authorizations: &[Authorization], tag: Tag) -> Option<&Authorization> {
603 let auths: Vec<&Authorization> =
604 authorizations.iter().filter(|auth| auth.keyParameter.tag == tag).collect();
605
606 if !auths.is_empty() {
607 Some(auths[0])
608 } else {
609 None
610 }
611 }
612
613 /// Generate EC Key using given security level and domain with below key parameters and
614 /// optionally allow the generated key to be attested with factory provisioned attest key using
615 /// given challenge and application id -
616 /// Purposes: SIGN and VERIFY
617 /// Digest: SHA_2_256
618 /// Curve: P_256
generate_ec_p256_signing_key( sl: &SecLevel, domain: Domain, nspace: i64, alias: Option<String>, att_challenge: Option<&[u8]>, ) -> binder::Result<KeyMetadata>619 pub fn generate_ec_p256_signing_key(
620 sl: &SecLevel,
621 domain: Domain,
622 nspace: i64,
623 alias: Option<String>,
624 att_challenge: Option<&[u8]>,
625 ) -> binder::Result<KeyMetadata> {
626 let mut key_attest = false;
627 let mut gen_params = AuthSetBuilder::new()
628 .no_auth_required()
629 .algorithm(Algorithm::EC)
630 .purpose(KeyPurpose::SIGN)
631 .purpose(KeyPurpose::VERIFY)
632 .digest(Digest::SHA_2_256)
633 .ec_curve(EcCurve::P_256);
634
635 if let Some(challenge) = att_challenge {
636 key_attest = true;
637 gen_params = gen_params.clone().attestation_challenge(challenge.to_vec());
638 }
639
640 match sl.binder.generateKey(
641 &KeyDescriptor { domain, nspace, alias, blob: None },
642 None,
643 &gen_params,
644 0,
645 b"entropy",
646 ) {
647 Ok(key_metadata) => {
648 assert!(key_metadata.certificate.is_some());
649 if key_attest {
650 assert!(key_metadata.certificateChain.is_some());
651 }
652 if domain == Domain::BLOB {
653 assert!(key_metadata.key.blob.is_some());
654 }
655
656 check_key_authorizations(
657 sl,
658 &key_metadata.authorizations,
659 &gen_params,
660 KeyOrigin::GENERATED,
661 );
662 Ok(key_metadata)
663 }
664 Err(e) => Err(e),
665 }
666 }
667
668 /// Generate EC signing key.
generate_ec_key( sl: &SecLevel, domain: Domain, nspace: i64, alias: Option<String>, ec_curve: EcCurve, digest: Digest, ) -> binder::Result<KeyMetadata>669 pub fn generate_ec_key(
670 sl: &SecLevel,
671 domain: Domain,
672 nspace: i64,
673 alias: Option<String>,
674 ec_curve: EcCurve,
675 digest: Digest,
676 ) -> binder::Result<KeyMetadata> {
677 let gen_params = AuthSetBuilder::new()
678 .no_auth_required()
679 .algorithm(Algorithm::EC)
680 .purpose(KeyPurpose::SIGN)
681 .purpose(KeyPurpose::VERIFY)
682 .digest(digest)
683 .ec_curve(ec_curve);
684
685 let key_metadata = sl.binder.generateKey(
686 &KeyDescriptor { domain, nspace, alias, blob: None },
687 None,
688 &gen_params,
689 0,
690 b"entropy",
691 )?;
692
693 // Must have a public key.
694 assert!(key_metadata.certificate.is_some());
695
696 // Should not have an attestation record.
697 assert!(key_metadata.certificateChain.is_none());
698
699 if domain == Domain::BLOB {
700 assert!(key_metadata.key.blob.is_some());
701 } else {
702 assert!(key_metadata.key.blob.is_none());
703 }
704 check_key_authorizations(sl, &key_metadata.authorizations, &gen_params, KeyOrigin::GENERATED);
705 Ok(key_metadata)
706 }
707
708 /// 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>>709 pub fn generate_rsa_key(
710 sl: &SecLevel,
711 domain: Domain,
712 nspace: i64,
713 alias: Option<String>,
714 key_params: &KeyParams,
715 attest_key: Option<&KeyDescriptor>,
716 ) -> binder::Result<Option<KeyMetadata>> {
717 let mut gen_params = AuthSetBuilder::new()
718 .no_auth_required()
719 .algorithm(Algorithm::RSA)
720 .rsa_public_exponent(65537)
721 .key_size(key_params.key_size);
722
723 for purpose in &key_params.purpose {
724 gen_params = gen_params.purpose(*purpose);
725 }
726 if let Some(value) = key_params.digest {
727 gen_params = gen_params.digest(value)
728 }
729 if let Some(value) = key_params.padding {
730 gen_params = gen_params.padding_mode(value);
731 }
732 if let Some(value) = key_params.mgf_digest {
733 gen_params = gen_params.mgf_digest(value);
734 }
735 if let Some(value) = key_params.block_mode {
736 gen_params = gen_params.block_mode(value)
737 }
738 if let Some(value) = &key_params.att_challenge {
739 gen_params = gen_params.attestation_challenge(value.to_vec())
740 }
741
742 let key_metadata = match sl.binder.generateKey(
743 &KeyDescriptor { domain, nspace, alias, blob: None },
744 attest_key,
745 &gen_params,
746 0,
747 b"entropy",
748 ) {
749 Ok(metadata) => metadata,
750 Err(e) => {
751 return if is_rkp_only_unknown_on_gsi(sl.level)
752 && e.service_specific_error() == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED.0
753 {
754 // GSI replaces the values for remote_prov_prop properties (since they’re
755 // system_internal_prop properties), so on GSI the properties are not
756 // reliable indicators of whether StrongBox/TEE are RKP-only or not.
757 // Test can be skipped if it generates a key with attestation but doesn't provide
758 // an ATTEST_KEY and rkp-only property is undetermined.
759 Ok(None)
760 } else {
761 Err(e)
762 };
763 }
764 };
765
766 // Must have a public key.
767 assert!(key_metadata.certificate.is_some());
768
769 if attest_key.is_none() && key_params.att_challenge.is_some() {
770 // Should have an attestation record.
771 assert!(key_metadata.certificateChain.is_some());
772 } else {
773 // Should not have an attestation record.
774 assert!(key_metadata.certificateChain.is_none());
775 }
776
777 assert!(
778 (domain == Domain::BLOB && key_metadata.key.blob.is_some())
779 || key_metadata.key.blob.is_none()
780 );
781
782 check_key_authorizations(sl, &key_metadata.authorizations, &gen_params, KeyOrigin::GENERATED);
783 // If `RSA_OAEP_MGF_DIGEST` tag is not mentioned explicitly while generating/importing a key,
784 // then make sure `RSA_OAEP_MGF_DIGEST` tag with default value (SHA1) must not be included in
785 // key authorization list.
786 if key_params.mgf_digest.is_none() {
787 assert!(!check_key_param(
788 &key_metadata.authorizations,
789 &KeyParameter {
790 tag: Tag::RSA_OAEP_MGF_DIGEST,
791 value: KeyParameterValue::Digest(Digest::SHA1)
792 }
793 ));
794 }
795 Ok(Some(key_metadata))
796 }
797
798 /// 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>799 pub fn generate_sym_key(
800 sl: &SecLevel,
801 algorithm: Algorithm,
802 size: i32,
803 alias: &str,
804 padding_mode: &PaddingMode,
805 block_mode: &BlockMode,
806 min_mac_len: Option<i32>,
807 ) -> binder::Result<KeyMetadata> {
808 let mut gen_params = AuthSetBuilder::new()
809 .no_auth_required()
810 .algorithm(algorithm)
811 .purpose(KeyPurpose::ENCRYPT)
812 .purpose(KeyPurpose::DECRYPT)
813 .key_size(size)
814 .padding_mode(*padding_mode)
815 .block_mode(*block_mode);
816
817 if let Some(val) = min_mac_len {
818 gen_params = gen_params.min_mac_length(val);
819 }
820
821 let key_metadata = sl.binder.generateKey(
822 &KeyDescriptor {
823 domain: Domain::APP,
824 nspace: -1,
825 alias: Some(alias.to_string()),
826 blob: None,
827 },
828 None,
829 &gen_params,
830 0,
831 b"entropy",
832 )?;
833
834 // Should not have public certificate.
835 assert!(key_metadata.certificate.is_none());
836
837 // Should not have an attestation record.
838 assert!(key_metadata.certificateChain.is_none());
839 check_key_authorizations(sl, &key_metadata.authorizations, &gen_params, KeyOrigin::GENERATED);
840 Ok(key_metadata)
841 }
842
843 /// Generate HMAC key.
generate_hmac_key( sl: &SecLevel, alias: &str, key_size: i32, min_mac_len: i32, digest: Digest, ) -> binder::Result<KeyMetadata>844 pub fn generate_hmac_key(
845 sl: &SecLevel,
846 alias: &str,
847 key_size: i32,
848 min_mac_len: i32,
849 digest: Digest,
850 ) -> binder::Result<KeyMetadata> {
851 let gen_params = AuthSetBuilder::new()
852 .no_auth_required()
853 .algorithm(Algorithm::HMAC)
854 .purpose(KeyPurpose::SIGN)
855 .purpose(KeyPurpose::VERIFY)
856 .key_size(key_size)
857 .min_mac_length(min_mac_len)
858 .digest(digest);
859
860 let key_metadata = sl.binder.generateKey(
861 &KeyDescriptor {
862 domain: Domain::APP,
863 nspace: -1,
864 alias: Some(alias.to_string()),
865 blob: None,
866 },
867 None,
868 &gen_params,
869 0,
870 b"entropy",
871 )?;
872
873 // Should not have public certificate.
874 assert!(key_metadata.certificate.is_none());
875
876 // Should not have an attestation record.
877 assert!(key_metadata.certificateChain.is_none());
878
879 check_key_authorizations(sl, &key_metadata.authorizations, &gen_params, KeyOrigin::GENERATED);
880 Ok(key_metadata)
881 }
882
883 /// Generate RSA or EC attestation keys using below parameters -
884 /// Purpose: ATTEST_KEY
885 /// Digest: Digest::SHA_2_256
886 /// Padding: PaddingMode::RSA_PKCS1_1_5_SIGN
887 /// RSA-Key-Size: 2048
888 /// EC-Curve: EcCurve::P_256
generate_attestation_key( sl: &SecLevel, algorithm: Algorithm, att_challenge: &[u8], ) -> binder::Result<Option<KeyMetadata>>889 pub fn generate_attestation_key(
890 sl: &SecLevel,
891 algorithm: Algorithm,
892 att_challenge: &[u8],
893 ) -> binder::Result<Option<KeyMetadata>> {
894 assert!(algorithm == Algorithm::RSA || algorithm == Algorithm::EC);
895
896 if algorithm == Algorithm::RSA {
897 let alias = "ks_rsa_attest_test_key";
898 generate_rsa_key(
899 sl,
900 Domain::APP,
901 -1,
902 Some(alias.to_string()),
903 &KeyParams {
904 key_size: 2048,
905 purpose: vec![KeyPurpose::ATTEST_KEY],
906 padding: Some(PaddingMode::RSA_PKCS1_1_5_SIGN),
907 digest: Some(Digest::SHA_2_256),
908 mgf_digest: None,
909 block_mode: None,
910 att_challenge: Some(att_challenge.to_vec()),
911 },
912 None,
913 )
914 } else {
915 generate_ec_attestation_key(sl, att_challenge, Digest::SHA_2_256, EcCurve::P_256)
916 }
917 }
918
919 /// Generate EC attestation key with the given
920 /// 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>>921 pub fn generate_ec_attestation_key(
922 sl: &SecLevel,
923 att_challenge: &[u8],
924 digest: Digest,
925 ec_curve: EcCurve,
926 ) -> binder::Result<Option<KeyMetadata>> {
927 let alias = "ks_attest_ec_test_key";
928 let gen_params = AuthSetBuilder::new()
929 .no_auth_required()
930 .algorithm(Algorithm::EC)
931 .purpose(KeyPurpose::ATTEST_KEY)
932 .ec_curve(ec_curve)
933 .digest(digest)
934 .attestation_challenge(att_challenge.to_vec());
935
936 let attestation_key_metadata = match sl.binder.generateKey(
937 &KeyDescriptor {
938 domain: Domain::APP,
939 nspace: -1,
940 alias: Some(alias.to_string()),
941 blob: None,
942 },
943 None,
944 &gen_params,
945 0,
946 b"entropy",
947 ) {
948 Ok(metadata) => metadata,
949 Err(e) => {
950 return if is_rkp_only_unknown_on_gsi(sl.level)
951 && e.service_specific_error() == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED.0
952 {
953 // GSI replaces the values for remote_prov_prop properties (since they’re
954 // system_internal_prop properties), so on GSI the properties are not
955 // reliable indicators of whether StrongBox/TEE are RKP-only or not.
956 // Test can be skipped if it generates a key with attestation but doesn't provide
957 // an ATTEST_KEY and rkp-only property is undetermined.
958 Ok(None)
959 } else {
960 Err(e)
961 };
962 }
963 };
964
965 // Should have public certificate.
966 assert!(attestation_key_metadata.certificate.is_some());
967 // Should have an attestation record.
968 assert!(attestation_key_metadata.certificateChain.is_some());
969
970 check_key_authorizations(
971 sl,
972 &attestation_key_metadata.authorizations,
973 &gen_params,
974 KeyOrigin::GENERATED,
975 );
976 Ok(Some(attestation_key_metadata))
977 }
978
979 /// 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>980 pub fn generate_ec_256_attested_key(
981 sl: &SecLevel,
982 alias: Option<String>,
983 att_challenge: &[u8],
984 attest_key: &KeyDescriptor,
985 ) -> binder::Result<KeyMetadata> {
986 let ec_gen_params = AuthSetBuilder::new()
987 .no_auth_required()
988 .algorithm(Algorithm::EC)
989 .purpose(KeyPurpose::SIGN)
990 .purpose(KeyPurpose::VERIFY)
991 .digest(Digest::SHA_2_256)
992 .ec_curve(EcCurve::P_256)
993 .attestation_challenge(att_challenge.to_vec());
994
995 let ec_key_metadata = sl
996 .binder
997 .generateKey(
998 &KeyDescriptor { domain: Domain::APP, nspace: -1, alias, blob: None },
999 Some(attest_key),
1000 &ec_gen_params,
1001 0,
1002 b"entropy",
1003 )
1004 .unwrap();
1005
1006 // Should have public certificate.
1007 assert!(ec_key_metadata.certificate.is_some());
1008 // Shouldn't have an attestation record.
1009 assert!(ec_key_metadata.certificateChain.is_none());
1010
1011 check_key_authorizations(
1012 sl,
1013 &ec_key_metadata.authorizations,
1014 &ec_gen_params,
1015 KeyOrigin::GENERATED,
1016 );
1017 Ok(ec_key_metadata)
1018 }
1019
1020 /// 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>1021 pub fn import_rsa_2048_key(
1022 sl: &SecLevel,
1023 domain: Domain,
1024 nspace: i64,
1025 alias: Option<String>,
1026 import_params: AuthSetBuilder,
1027 ) -> binder::Result<KeyMetadata> {
1028 let key_metadata = sl
1029 .binder
1030 .importKey(
1031 &KeyDescriptor { domain, nspace, alias, blob: None },
1032 None,
1033 &import_params,
1034 0,
1035 RSA_2048_KEY,
1036 )
1037 .unwrap();
1038
1039 assert!(key_metadata.certificate.is_some());
1040 assert!(key_metadata.certificateChain.is_none());
1041
1042 check_key_authorizations(sl, &key_metadata.authorizations, &import_params, KeyOrigin::IMPORTED);
1043
1044 // Check below auths explicitly, they might not be addd in import parameters.
1045 assert!(check_key_param(
1046 &key_metadata.authorizations,
1047 &KeyParameter { tag: Tag::ALGORITHM, value: KeyParameterValue::Algorithm(Algorithm::RSA) }
1048 ));
1049
1050 assert!(check_key_param(
1051 &key_metadata.authorizations,
1052 &KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(2048) }
1053 ));
1054
1055 assert!(check_key_param(
1056 &key_metadata.authorizations,
1057 &KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) }
1058 ));
1059
1060 assert!(check_key_param(
1061 &key_metadata.authorizations,
1062 &KeyParameter {
1063 tag: Tag::RSA_PUBLIC_EXPONENT,
1064 value: KeyParameterValue::LongInteger(65537)
1065 }
1066 ));
1067
1068 assert!(check_key_param(
1069 &key_metadata.authorizations,
1070 &KeyParameter {
1071 tag: Tag::PADDING,
1072 value: KeyParameterValue::PaddingMode(PaddingMode::RSA_PSS)
1073 }
1074 ));
1075
1076 assert!(check_key_param(
1077 &key_metadata.authorizations,
1078 &KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
1079 ));
1080
1081 Ok(key_metadata)
1082 }
1083
1084 /// 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>1085 pub fn import_ec_p_256_key(
1086 sl: &SecLevel,
1087 domain: Domain,
1088 nspace: i64,
1089 alias: Option<String>,
1090 import_params: AuthSetBuilder,
1091 ) -> binder::Result<KeyMetadata> {
1092 let key_metadata = sl
1093 .binder
1094 .importKey(
1095 &KeyDescriptor { domain, nspace, alias, blob: None },
1096 None,
1097 &import_params,
1098 0,
1099 EC_P_256_KEY,
1100 )
1101 .unwrap();
1102
1103 assert!(key_metadata.certificate.is_some());
1104 assert!(key_metadata.certificateChain.is_none());
1105
1106 check_key_authorizations(sl, &key_metadata.authorizations, &import_params, KeyOrigin::IMPORTED);
1107
1108 // Check below auths explicitly, they might not be addd in import parameters.
1109 assert!(check_key_param(
1110 &key_metadata.authorizations,
1111 &KeyParameter { tag: Tag::ALGORITHM, value: KeyParameterValue::Algorithm(Algorithm::EC) }
1112 ));
1113
1114 assert!(check_key_param(
1115 &key_metadata.authorizations,
1116 &KeyParameter { tag: Tag::EC_CURVE, value: KeyParameterValue::EcCurve(EcCurve::P_256) }
1117 ));
1118
1119 assert!(check_key_param(
1120 &key_metadata.authorizations,
1121 &KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) }
1122 ));
1123 assert!(check_key_param(
1124 &key_metadata.authorizations,
1125 &KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
1126 ));
1127
1128 Ok(key_metadata)
1129 }
1130
1131 /// Import sample AES key and validate its key parameters.
import_aes_key( sl: &SecLevel, domain: Domain, nspace: i64, alias: Option<String>, ) -> binder::Result<KeyMetadata>1132 pub fn import_aes_key(
1133 sl: &SecLevel,
1134 domain: Domain,
1135 nspace: i64,
1136 alias: Option<String>,
1137 ) -> binder::Result<KeyMetadata> {
1138 static AES_KEY: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
1139 let key_size = AES_KEY.len() * 8;
1140
1141 let import_params = AuthSetBuilder::new()
1142 .no_auth_required()
1143 .algorithm(Algorithm::AES)
1144 .block_mode(BlockMode::ECB)
1145 .key_size(key_size.try_into().unwrap())
1146 .purpose(KeyPurpose::ENCRYPT)
1147 .purpose(KeyPurpose::DECRYPT)
1148 .padding_mode(PaddingMode::PKCS7);
1149
1150 let key_metadata = sl.binder.importKey(
1151 &KeyDescriptor { domain, nspace, alias, blob: None },
1152 None,
1153 &import_params,
1154 0,
1155 AES_KEY,
1156 )?;
1157
1158 check_key_authorizations(sl, &key_metadata.authorizations, &import_params, KeyOrigin::IMPORTED);
1159
1160 // Check below auths explicitly, they might not be addd in import parameters.
1161 assert!(check_key_param(
1162 &key_metadata.authorizations,
1163 &KeyParameter { tag: Tag::ALGORITHM, value: KeyParameterValue::Algorithm(Algorithm::AES) }
1164 ));
1165 assert!(check_key_param(
1166 &key_metadata.authorizations,
1167 &KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) }
1168 ));
1169 assert!(check_key_param(
1170 &key_metadata.authorizations,
1171 &KeyParameter {
1172 tag: Tag::PADDING,
1173 value: KeyParameterValue::PaddingMode(PaddingMode::PKCS7)
1174 }
1175 ));
1176 assert!(check_key_param(
1177 &key_metadata.authorizations,
1178 &KeyParameter { tag: Tag::BLOCK_MODE, value: KeyParameterValue::BlockMode(BlockMode::ECB) }
1179 ));
1180 assert!(check_key_param(
1181 &key_metadata.authorizations,
1182 &KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
1183 ));
1184
1185 Ok(key_metadata)
1186 }
1187
1188 /// Import sample 3DES key and validate its key parameters.
import_3des_key( sl: &SecLevel, domain: Domain, nspace: i64, alias: Option<String>, ) -> binder::Result<KeyMetadata>1189 pub fn import_3des_key(
1190 sl: &SecLevel,
1191 domain: Domain,
1192 nspace: i64,
1193 alias: Option<String>,
1194 ) -> binder::Result<KeyMetadata> {
1195 static TRIPLE_DES_KEY: &[u8] = &[
1196 0xa4, 0x9d, 0x75, 0x64, 0x19, 0x9e, 0x97, 0xcb, 0x52, 0x9d, 0x2c, 0x9d, 0x97, 0xbf, 0x2f,
1197 0x98, 0xd3, 0x5e, 0xdf, 0x57, 0xba, 0x1f, 0x73, 0x58,
1198 ];
1199
1200 let import_params = AuthSetBuilder::new()
1201 .no_auth_required()
1202 .algorithm(Algorithm::TRIPLE_DES)
1203 .block_mode(BlockMode::ECB)
1204 .key_size(168)
1205 .purpose(KeyPurpose::ENCRYPT)
1206 .purpose(KeyPurpose::DECRYPT)
1207 .padding_mode(PaddingMode::PKCS7);
1208
1209 let key_metadata = sl.binder.importKey(
1210 &KeyDescriptor { domain, nspace, alias, blob: None },
1211 None,
1212 &import_params,
1213 0,
1214 TRIPLE_DES_KEY,
1215 )?;
1216
1217 check_key_authorizations(sl, &key_metadata.authorizations, &import_params, KeyOrigin::IMPORTED);
1218
1219 // Check below auths explicitly, they might not be addd in import parameters.
1220 assert!(check_key_param(
1221 &key_metadata.authorizations,
1222 &KeyParameter {
1223 tag: Tag::ALGORITHM,
1224 value: KeyParameterValue::Algorithm(Algorithm::TRIPLE_DES)
1225 }
1226 ));
1227 assert!(check_key_param(
1228 &key_metadata.authorizations,
1229 &KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(168) }
1230 ));
1231 assert!(check_key_param(
1232 &key_metadata.authorizations,
1233 &KeyParameter {
1234 tag: Tag::PADDING,
1235 value: KeyParameterValue::PaddingMode(PaddingMode::PKCS7)
1236 }
1237 ));
1238 assert!(check_key_param(
1239 &key_metadata.authorizations,
1240 &KeyParameter { tag: Tag::BLOCK_MODE, value: KeyParameterValue::BlockMode(BlockMode::ECB) }
1241 ));
1242 assert!(check_key_param(
1243 &key_metadata.authorizations,
1244 &KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
1245 ));
1246
1247 Ok(key_metadata)
1248 }
1249
1250 /// Import sample HMAC key and validate its key parameters.
import_hmac_key( sl: &SecLevel, domain: Domain, nspace: i64, alias: Option<String>, ) -> binder::Result<KeyMetadata>1251 pub fn import_hmac_key(
1252 sl: &SecLevel,
1253 domain: Domain,
1254 nspace: i64,
1255 alias: Option<String>,
1256 ) -> binder::Result<KeyMetadata> {
1257 static HMAC_KEY: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
1258 let key_size = HMAC_KEY.len() * 8;
1259
1260 let import_params = AuthSetBuilder::new()
1261 .no_auth_required()
1262 .algorithm(Algorithm::HMAC)
1263 .key_size(key_size.try_into().unwrap())
1264 .purpose(KeyPurpose::SIGN)
1265 .purpose(KeyPurpose::VERIFY)
1266 .digest(Digest::SHA_2_256)
1267 .min_mac_length(256);
1268
1269 let key_metadata = sl.binder.importKey(
1270 &KeyDescriptor { domain, nspace, alias, blob: None },
1271 None,
1272 &import_params,
1273 0,
1274 HMAC_KEY,
1275 )?;
1276
1277 check_key_authorizations(sl, &key_metadata.authorizations, &import_params, KeyOrigin::IMPORTED);
1278
1279 // Check below auths explicitly, they might not be addd in import parameters.
1280 assert!(check_key_param(
1281 &key_metadata.authorizations,
1282 &KeyParameter { tag: Tag::ALGORITHM, value: KeyParameterValue::Algorithm(Algorithm::HMAC) }
1283 ));
1284 assert!(check_key_param(
1285 &key_metadata.authorizations,
1286 &KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) }
1287 ));
1288 assert!(check_key_param(
1289 &key_metadata.authorizations,
1290 &KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) }
1291 ));
1292 assert!(check_key_param(
1293 &key_metadata.authorizations,
1294 &KeyParameter { tag: Tag::ORIGIN, value: KeyParameterValue::Origin(KeyOrigin::IMPORTED) }
1295 ));
1296
1297 Ok(key_metadata)
1298 }
1299
1300 /// 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>1301 pub fn import_wrapping_key(
1302 sl: &SecLevel,
1303 wrapping_key_data: &[u8],
1304 wrapping_key_alias: Option<String>,
1305 ) -> binder::Result<KeyMetadata> {
1306 let wrapping_key_params = AuthSetBuilder::new()
1307 .no_auth_required()
1308 .algorithm(Algorithm::RSA)
1309 .digest(Digest::SHA_2_256)
1310 .purpose(KeyPurpose::ENCRYPT)
1311 .purpose(KeyPurpose::DECRYPT)
1312 .purpose(KeyPurpose::WRAP_KEY)
1313 .padding_mode(PaddingMode::RSA_OAEP)
1314 .key_size(2048)
1315 .rsa_public_exponent(65537)
1316 .cert_not_before(0)
1317 .cert_not_after(253402300799000);
1318
1319 sl.binder.importKey(
1320 &KeyDescriptor { domain: Domain::APP, nspace: -1, alias: wrapping_key_alias, blob: None },
1321 None,
1322 &wrapping_key_params,
1323 0,
1324 wrapping_key_data,
1325 )
1326 }
1327
1328 /// 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>1329 pub fn import_wrapped_key(
1330 sl: &SecLevel,
1331 alias: Option<String>,
1332 wrapping_key_metadata: &KeyMetadata,
1333 wrapped_key: Option<Vec<u8>>,
1334 ) -> binder::Result<KeyMetadata> {
1335 let unwrap_params =
1336 AuthSetBuilder::new().digest(Digest::SHA_2_256).padding_mode(PaddingMode::RSA_OAEP);
1337
1338 let authenticator_spec: &[AuthenticatorSpec] = &[AuthenticatorSpec {
1339 authenticatorType: HardwareAuthenticatorType::NONE,
1340 authenticatorId: 0,
1341 }];
1342
1343 let key_metadata = sl.binder.importWrappedKey(
1344 &KeyDescriptor { domain: Domain::APP, nspace: -1, alias, blob: wrapped_key },
1345 &wrapping_key_metadata.key,
1346 None,
1347 &unwrap_params,
1348 authenticator_spec,
1349 )?;
1350
1351 Ok(key_metadata)
1352 }
1353
1354 /// 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>1355 pub fn import_wrapping_key_and_wrapped_key(
1356 sl: &SecLevel,
1357 domain: Domain,
1358 nspace: i64,
1359 alias: Option<String>,
1360 wrapping_key_alias: Option<String>,
1361 wrapping_key_params: AuthSetBuilder,
1362 ) -> binder::Result<KeyMetadata> {
1363 let wrapping_key_metadata = sl.binder.importKey(
1364 &KeyDescriptor { domain, nspace, alias: wrapping_key_alias, blob: None },
1365 None,
1366 &wrapping_key_params,
1367 0,
1368 WRAPPING_KEY,
1369 )?;
1370
1371 import_wrapped_key(sl, alias, &wrapping_key_metadata, Some(WRAPPED_KEY.to_vec()))
1372 }
1373
1374 /// 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>1375 pub fn import_transport_key(
1376 sl: &SecLevel,
1377 transport_key_alias: Option<String>,
1378 transport_key: &[u8],
1379 ) -> binder::Result<KeyMetadata> {
1380 let transport_key_params = AuthSetBuilder::new()
1381 .no_auth_required()
1382 .algorithm(Algorithm::AES)
1383 .block_mode(BlockMode::GCM)
1384 .padding_mode(PaddingMode::NONE)
1385 .key_size(256)
1386 .caller_nonce()
1387 .min_mac_length(128)
1388 .purpose(KeyPurpose::ENCRYPT)
1389 .purpose(KeyPurpose::DECRYPT);
1390
1391 sl.binder.importKey(
1392 &KeyDescriptor { domain: Domain::APP, nspace: -1, alias: transport_key_alias, blob: None },
1393 None,
1394 &transport_key_params,
1395 0,
1396 transport_key,
1397 )
1398 }
1399
1400 /// 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>1401 pub fn generate_ec_agree_key(
1402 sl: &SecLevel,
1403 ec_curve: EcCurve,
1404 digest: Digest,
1405 domain: Domain,
1406 nspace: i64,
1407 alias: Option<String>,
1408 ) -> binder::Result<KeyMetadata> {
1409 let gen_params = AuthSetBuilder::new()
1410 .no_auth_required()
1411 .algorithm(Algorithm::EC)
1412 .purpose(KeyPurpose::AGREE_KEY)
1413 .digest(digest)
1414 .ec_curve(ec_curve);
1415
1416 match sl.binder.generateKey(
1417 &KeyDescriptor { domain, nspace, alias, blob: None },
1418 None,
1419 &gen_params,
1420 0,
1421 b"entropy",
1422 ) {
1423 Ok(key_metadata) => {
1424 assert!(key_metadata.certificate.is_some());
1425 if domain == Domain::BLOB {
1426 assert!(key_metadata.key.blob.is_some());
1427 }
1428
1429 check_key_authorizations(
1430 sl,
1431 &key_metadata.authorizations,
1432 &gen_params,
1433 KeyOrigin::GENERATED,
1434 );
1435 Ok(key_metadata)
1436 }
1437 Err(e) => Err(e),
1438 }
1439 }
1440
1441 /// 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>>1442 pub fn import_aes_keys(
1443 sl: &SecLevel,
1444 alias_prefix: String,
1445 total_count: Range<i32>,
1446 ) -> binder::Result<HashSet<String>> {
1447 let mut imported_key_aliases = HashSet::new();
1448
1449 // Import Total number of keys with given alias prefix.
1450 for count in total_count {
1451 let mut alias = String::new();
1452 write!(alias, "{}_{}", alias_prefix, count).unwrap();
1453 imported_key_aliases.insert(alias.clone());
1454
1455 import_aes_key(sl, Domain::APP, -1, Some(alias))?;
1456 }
1457
1458 Ok(imported_key_aliases)
1459 }
1460
1461 /// 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>1462 pub fn generate_key_with_attest_id(
1463 sl: &SecLevel,
1464 algorithm: Algorithm,
1465 alias: Option<String>,
1466 att_challenge: &[u8],
1467 attest_key: &KeyDescriptor,
1468 attest_id: Tag,
1469 value: Vec<u8>,
1470 ) -> binder::Result<KeyMetadata> {
1471 assert!(algorithm == Algorithm::RSA || algorithm == Algorithm::EC);
1472
1473 let mut ec_gen_params;
1474 if algorithm == Algorithm::EC {
1475 ec_gen_params = AuthSetBuilder::new()
1476 .no_auth_required()
1477 .algorithm(Algorithm::EC)
1478 .purpose(KeyPurpose::SIGN)
1479 .purpose(KeyPurpose::VERIFY)
1480 .digest(Digest::SHA_2_256)
1481 .ec_curve(EcCurve::P_256)
1482 .attestation_challenge(att_challenge.to_vec());
1483 } else {
1484 ec_gen_params = AuthSetBuilder::new()
1485 .no_auth_required()
1486 .algorithm(Algorithm::RSA)
1487 .rsa_public_exponent(65537)
1488 .key_size(2048)
1489 .purpose(KeyPurpose::SIGN)
1490 .purpose(KeyPurpose::VERIFY)
1491 .digest(Digest::SHA_2_256)
1492 .padding_mode(PaddingMode::RSA_PKCS1_1_5_SIGN)
1493 .attestation_challenge(att_challenge.to_vec());
1494 }
1495
1496 match attest_id {
1497 Tag::ATTESTATION_ID_BRAND => {
1498 ec_gen_params = ec_gen_params.attestation_device_brand(value);
1499 }
1500 Tag::ATTESTATION_ID_DEVICE => {
1501 ec_gen_params = ec_gen_params.attestation_device_name(value);
1502 }
1503 Tag::ATTESTATION_ID_PRODUCT => {
1504 ec_gen_params = ec_gen_params.attestation_device_product_name(value);
1505 }
1506 Tag::ATTESTATION_ID_SERIAL => {
1507 ec_gen_params = ec_gen_params.attestation_device_serial(value);
1508 }
1509 Tag::ATTESTATION_ID_MANUFACTURER => {
1510 ec_gen_params = ec_gen_params.attestation_device_manufacturer(value);
1511 }
1512 Tag::ATTESTATION_ID_MODEL => {
1513 ec_gen_params = ec_gen_params.attestation_device_model(value);
1514 }
1515 Tag::ATTESTATION_ID_IMEI => {
1516 ec_gen_params = ec_gen_params.attestation_device_imei(value);
1517 }
1518 Tag::ATTESTATION_ID_SECOND_IMEI => {
1519 ec_gen_params = ec_gen_params.attestation_device_second_imei(value);
1520 }
1521 _ => {
1522 panic!("Unknown attestation id");
1523 }
1524 }
1525
1526 sl.binder.generateKey(
1527 &KeyDescriptor { domain: Domain::APP, nspace: -1, alias, blob: None },
1528 Some(attest_key),
1529 &ec_gen_params,
1530 0,
1531 b"entropy",
1532 )
1533 }
1534
1535 /// Generate Key and validate key characteristics.
generate_key( sl: &SecLevel, gen_params: &AuthSetBuilder, alias: &str, ) -> binder::Result<Option<KeyMetadata>>1536 pub fn generate_key(
1537 sl: &SecLevel,
1538 gen_params: &AuthSetBuilder,
1539 alias: &str,
1540 ) -> binder::Result<Option<KeyMetadata>> {
1541 let key_metadata = match sl.binder.generateKey(
1542 &KeyDescriptor {
1543 domain: Domain::APP,
1544 nspace: -1,
1545 alias: Some(alias.to_string()),
1546 blob: None,
1547 },
1548 None,
1549 gen_params,
1550 0,
1551 b"entropy",
1552 ) {
1553 Ok(metadata) => metadata,
1554 Err(e) => {
1555 return if is_rkp_only_unknown_on_gsi(sl.level)
1556 && e.service_specific_error() == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED.0
1557 {
1558 // GSI replaces the values for remote_prov_prop properties (since they’re
1559 // system_internal_prop properties), so on GSI the properties are not
1560 // reliable indicators of whether StrongBox/TEE are RKP-only or not.
1561 // Test can be skipped if it generates a key with attestation but doesn't provide
1562 // an ATTEST_KEY and rkp-only property is undetermined.
1563 Ok(None)
1564 } else {
1565 Err(e)
1566 };
1567 }
1568 };
1569
1570 if gen_params.iter().any(|kp| {
1571 matches!(
1572 kp.value,
1573 KeyParameterValue::Algorithm(Algorithm::RSA)
1574 | KeyParameterValue::Algorithm(Algorithm::EC)
1575 )
1576 }) {
1577 assert!(key_metadata.certificate.is_some());
1578 if gen_params.iter().any(|kp| kp.tag == Tag::ATTESTATION_CHALLENGE) {
1579 assert!(key_metadata.certificateChain.is_some());
1580 let mut cert_chain: Vec<u8> = Vec::new();
1581 cert_chain.extend(key_metadata.certificate.as_ref().unwrap());
1582 cert_chain.extend(key_metadata.certificateChain.as_ref().unwrap());
1583 let strict_issuer_check =
1584 !(gen_params.iter().any(|kp| kp.tag == Tag::DEVICE_UNIQUE_ATTESTATION));
1585 validate_certchain_with_strict_issuer_check(&cert_chain, strict_issuer_check)
1586 .expect("Error while validating cert chain");
1587 }
1588
1589 if let Some(challenge_param) =
1590 gen_params.iter().find(|kp| kp.tag == Tag::ATTESTATION_CHALLENGE)
1591 {
1592 if let KeyParameterValue::Blob(val) = &challenge_param.value {
1593 let att_challenge = get_value_from_attest_record(
1594 key_metadata.certificate.as_ref().unwrap(),
1595 challenge_param.tag,
1596 key_metadata.keySecurityLevel,
1597 )
1598 .expect("Attestation challenge verification failed.");
1599 assert_eq!(&att_challenge, val);
1600 }
1601
1602 let att_app_id = get_value_from_attest_record(
1603 key_metadata.certificate.as_ref().unwrap(),
1604 Tag::ATTESTATION_APPLICATION_ID,
1605 SecurityLevel::KEYSTORE,
1606 )
1607 .expect("Attestation application id verification failed.");
1608 assert!(!att_app_id.is_empty());
1609 }
1610 }
1611 check_key_authorizations(sl, &key_metadata.authorizations, gen_params, KeyOrigin::GENERATED);
1612
1613 Ok(Some(key_metadata))
1614 }
1615
1616 /// 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>>1617 pub fn create_key_and_operation(
1618 sl: &SecLevel,
1619 gen_params: &AuthSetBuilder,
1620 op_params: &AuthSetBuilder,
1621 alias: &str,
1622 ) -> binder::Result<Option<CreateOperationResponse>> {
1623 let Some(key_metadata) = generate_key(sl, gen_params, alias)? else {
1624 return Ok(None);
1625 };
1626
1627 sl.binder.createOperation(&key_metadata.key, op_params, false).map(Some)
1628 }
1629