blob: f08031e66d8dd4a50d36f704f2ef0c4d442037a1 [file] [log] [blame]
Hasini Gunasinghe12486362020-07-24 18:40:20 +00001// Copyright 2020, 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//! KeyParameter is used to express different characteristics of a key requested by the user
16//! and enforced by the OEMs. This module implements the internal representation of KeyParameter
17//! and the methods to work with KeyParameter.
18
Hasini Gunasingheaf993662020-07-24 18:40:20 +000019use crate::error::Error as KeystoreError;
Janis Danisevskise24f3472020-08-12 17:58:49 -070020use crate::error::Rc;
Hasini Gunasingheaf993662020-07-24 18:40:20 +000021pub use android_hardware_keymint::aidl::android::hardware::keymint::{
22 Algorithm, Algorithm::Algorithm as AlgorithmType, BlockMode,
23 BlockMode::BlockMode as BlockModeType, Digest, Digest::Digest as DigestType, EcCurve,
24 EcCurve::EcCurve as EcCurveType, HardwareAuthenticatorType,
25 HardwareAuthenticatorType::HardwareAuthenticatorType as HardwareAuthenticatorTypeType,
Hasini Gunasinghe3eb77c22020-08-28 15:45:06 +000026 KeyOrigin, KeyOrigin::KeyOrigin as KeyOriginType,
27 KeyParameter::KeyParameter as AidlKeyParameter, KeyPurpose,
Hasini Gunasingheaf993662020-07-24 18:40:20 +000028 KeyPurpose::KeyPurpose as KeyPurposeType, PaddingMode,
29 PaddingMode::PaddingMode as PaddingModeType, SecurityLevel,
30 SecurityLevel::SecurityLevel as SecurityLevelType, Tag, Tag::Tag as TagType,
Hasini Gunasinghe12486362020-07-24 18:40:20 +000031};
Hasini Gunasingheaf993662020-07-24 18:40:20 +000032use anyhow::{Context, Result};
33use rusqlite::types::{FromSql, Null, ToSql, ToSqlOutput};
34use rusqlite::{Result as SqlResult, Row};
Hasini Gunasinghe12486362020-07-24 18:40:20 +000035
36/// KeyParameter wraps the KeyParameterValue and the security level at which it is enforced.
Janis Danisevskis3f322cb2020-09-03 14:46:22 -070037#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
Hasini Gunasinghe12486362020-07-24 18:40:20 +000038pub struct KeyParameter {
39 key_parameter_value: KeyParameterValue,
Hasini Gunasingheaf993662020-07-24 18:40:20 +000040 security_level: SecurityLevelType,
Hasini Gunasinghe12486362020-07-24 18:40:20 +000041}
42
43/// KeyParameterValue holds a value corresponding to one of the Tags defined in
44/// the AIDL spec at hardware/interfaces/keymint
Janis Danisevskis3f322cb2020-09-03 14:46:22 -070045#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
Hasini Gunasinghe12486362020-07-24 18:40:20 +000046pub enum KeyParameterValue {
47 /// Associated with Tag:INVALID
48 Invalid,
49 /// Set of purposes for which the key may be used
Hasini Gunasingheaf993662020-07-24 18:40:20 +000050 KeyPurpose(KeyPurposeType),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000051 /// Cryptographic algorithm with which the key is used
Hasini Gunasingheaf993662020-07-24 18:40:20 +000052 Algorithm(AlgorithmType),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000053 /// Size of the key , in bits
Hasini Gunasingheaf993662020-07-24 18:40:20 +000054 KeySize(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000055 /// Block cipher mode(s) with which the key may be used
Hasini Gunasingheaf993662020-07-24 18:40:20 +000056 BlockMode(BlockModeType),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000057 /// Digest algorithms that may be used with the key to perform signing and verification
Hasini Gunasingheaf993662020-07-24 18:40:20 +000058 Digest(DigestType),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000059 /// Padding modes that may be used with the key. Relevant to RSA, AES and 3DES keys.
Hasini Gunasingheaf993662020-07-24 18:40:20 +000060 PaddingMode(PaddingModeType),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000061 /// Can the caller provide a nonce for nonce-requiring operations
62 CallerNonce,
63 /// Minimum length of MAC for HMAC keys and AES keys that support GCM mode
Hasini Gunasingheaf993662020-07-24 18:40:20 +000064 MinMacLength(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000065 /// The elliptic curve
Hasini Gunasingheaf993662020-07-24 18:40:20 +000066 EcCurve(EcCurveType),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000067 /// Value of the public exponent for an RSA key pair
Hasini Gunasingheaf993662020-07-24 18:40:20 +000068 RSAPublicExponent(i64),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000069 /// An attestation certificate for the generated key should contain an application-scoped
70 /// and time-bounded device-unique ID
71 IncludeUniqueID,
Hasini Gunasingheaf993662020-07-24 18:40:20 +000072 //TODO: find out about this
73 // /// Necessary system environment conditions for the generated key to be used
74 // KeyBlobUsageRequirements(KeyBlobUsageRequirements),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000075 /// Only the boot loader can use the key
76 BootLoaderOnly,
77 /// When deleted, the key is guaranteed to be permanently deleted and unusable
78 RollbackResistance,
Hasini Gunasinghe12486362020-07-24 18:40:20 +000079 /// The date and time at which the key becomes active
Hasini Gunasingheaf993662020-07-24 18:40:20 +000080 ActiveDateTime(i64),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000081 /// The date and time at which the key expires for signing and encryption
Hasini Gunasingheaf993662020-07-24 18:40:20 +000082 OriginationExpireDateTime(i64),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000083 /// The date and time at which the key expires for verification and decryption
Hasini Gunasingheaf993662020-07-24 18:40:20 +000084 UsageExpireDateTime(i64),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000085 /// Minimum amount of time that elapses between allowed operations
Hasini Gunasingheaf993662020-07-24 18:40:20 +000086 MinSecondsBetweenOps(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000087 /// Maximum number of times that a key may be used between system reboots
Hasini Gunasingheaf993662020-07-24 18:40:20 +000088 MaxUsesPerBoot(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000089 /// ID of the Android user that is permitted to use the key
Hasini Gunasingheaf993662020-07-24 18:40:20 +000090 UserID(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000091 /// A key may only be used under a particular secure user authentication state
Hasini Gunasingheaf993662020-07-24 18:40:20 +000092 UserSecureID(i64),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000093 /// No authentication is required to use this key
94 NoAuthRequired,
95 /// The types of user authenticators that may be used to authorize this key
Hasini Gunasingheaf993662020-07-24 18:40:20 +000096 HardwareAuthenticatorType(HardwareAuthenticatorTypeType),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000097 /// The time in seconds for which the key is authorized for use, after user authentication
Hasini Gunasingheaf993662020-07-24 18:40:20 +000098 AuthTimeout(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +000099 /// The key may be used after authentication timeout if device is still on-body
100 AllowWhileOnBody,
101 /// The key must be unusable except when the user has provided proof of physical presence
102 TrustedUserPresenceRequired,
103 /// Applicable to keys with KeyPurpose SIGN, and specifies that this key must not be usable
104 /// unless the user provides confirmation of the data to be signed
105 TrustedConfirmationRequired,
106 /// The key may only be used when the device is unlocked
107 UnlockedDeviceRequired,
108 /// When provided to generateKey or importKey, this tag specifies data
109 /// that is necessary during all uses of the key
110 ApplicationID(Vec<u8>),
111 /// When provided to generateKey or importKey, this tag specifies data
112 /// that is necessary during all uses of the key
113 ApplicationData(Vec<u8>),
114 /// Specifies the date and time the key was created
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000115 CreationDateTime(i64),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000116 /// Specifies where the key was created, if known
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000117 KeyOrigin(KeyOriginType),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000118 /// The key used by verified boot to validate the operating system booted
119 RootOfTrust(Vec<u8>),
120 /// System OS version with which the key may be used
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000121 OSVersion(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000122 /// Specifies the system security patch level with which the key may be used
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000123 OSPatchLevel(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000124 /// Specifies a unique, time-based identifier
125 UniqueID(Vec<u8>),
126 /// Used to deliver a "challenge" value to the attestKey() method
127 AttestationChallenge(Vec<u8>),
128 /// The set of applications which may use a key, used only with attestKey()
129 AttestationApplicationID(Vec<u8>),
130 /// Provides the device's brand name, to attestKey()
131 AttestationIdBrand(Vec<u8>),
132 /// Provides the device's device name, to attestKey()
133 AttestationIdDevice(Vec<u8>),
134 /// Provides the device's product name, to attestKey()
135 AttestationIdProduct(Vec<u8>),
136 /// Provides the device's serial number, to attestKey()
137 AttestationIdSerial(Vec<u8>),
138 /// Provides the IMEIs for all radios on the device, to attestKey()
139 AttestationIdIMEI(Vec<u8>),
140 /// Provides the MEIDs for all radios on the device, to attestKey()
141 AttestationIdMEID(Vec<u8>),
142 /// Provides the device's manufacturer name, to attestKey()
143 AttestationIdManufacturer(Vec<u8>),
144 /// Provides the device's model name, to attestKey()
145 AttestationIdModel(Vec<u8>),
146 /// Specifies the vendor image security patch level with which the key may be used
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000147 VendorPatchLevel(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000148 /// Specifies the boot image (kernel) security patch level with which the key may be used
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000149 BootPatchLevel(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000150 /// Provides "associated data" for AES-GCM encryption or decryption
151 AssociatedData(Vec<u8>),
152 /// Provides or returns a nonce or Initialization Vector (IV) for AES-GCM,
153 /// AES-CBC, AES-CTR, or 3DES-CBC encryption or decryption
154 Nonce(Vec<u8>),
155 /// Provides the requested length of a MAC or GCM authentication tag, in bits
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000156 MacLength(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000157 /// Specifies whether the device has been factory reset since the
158 /// last unique ID rotation. Used for key attestation
159 ResetSinceIdRotation,
160 /// Used to deliver a cryptographic token proving that the user
161 /// confirmed a signing request
162 ConfirmationToken(Vec<u8>),
163}
164
165impl KeyParameter {
166 /// Create an instance of KeyParameter, given the value and the security level.
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000167 pub fn new(key_parameter_value: KeyParameterValue, security_level: SecurityLevelType) -> Self {
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000168 KeyParameter { key_parameter_value, security_level }
169 }
170
171 /// Returns the tag given the KeyParameter instance.
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000172 pub fn get_tag(&self) -> TagType {
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000173 match self.key_parameter_value {
174 KeyParameterValue::Invalid => Tag::INVALID,
175 KeyParameterValue::KeyPurpose(_) => Tag::PURPOSE,
176 KeyParameterValue::Algorithm(_) => Tag::ALGORITHM,
177 KeyParameterValue::KeySize(_) => Tag::KEY_SIZE,
178 KeyParameterValue::BlockMode(_) => Tag::BLOCK_MODE,
179 KeyParameterValue::Digest(_) => Tag::DIGEST,
180 KeyParameterValue::PaddingMode(_) => Tag::PADDING,
181 KeyParameterValue::CallerNonce => Tag::CALLER_NONCE,
182 KeyParameterValue::MinMacLength(_) => Tag::MIN_MAC_LENGTH,
183 KeyParameterValue::EcCurve(_) => Tag::EC_CURVE,
184 KeyParameterValue::RSAPublicExponent(_) => Tag::RSA_PUBLIC_EXPONENT,
185 KeyParameterValue::IncludeUniqueID => Tag::INCLUDE_UNIQUE_ID,
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000186 KeyParameterValue::BootLoaderOnly => Tag::BOOTLOADER_ONLY,
187 KeyParameterValue::RollbackResistance => Tag::ROLLBACK_RESISTANCE,
188 KeyParameterValue::ActiveDateTime(_) => Tag::ACTIVE_DATETIME,
189 KeyParameterValue::OriginationExpireDateTime(_) => Tag::ORIGINATION_EXPIRE_DATETIME,
190 KeyParameterValue::UsageExpireDateTime(_) => Tag::USAGE_EXPIRE_DATETIME,
191 KeyParameterValue::MinSecondsBetweenOps(_) => Tag::MIN_SECONDS_BETWEEN_OPS,
192 KeyParameterValue::MaxUsesPerBoot(_) => Tag::MAX_USES_PER_BOOT,
193 KeyParameterValue::UserID(_) => Tag::USER_ID,
194 KeyParameterValue::UserSecureID(_) => Tag::USER_SECURE_ID,
195 KeyParameterValue::NoAuthRequired => Tag::NO_AUTH_REQUIRED,
196 KeyParameterValue::HardwareAuthenticatorType(_) => Tag::USER_AUTH_TYPE,
197 KeyParameterValue::AuthTimeout(_) => Tag::AUTH_TIMEOUT,
198 KeyParameterValue::AllowWhileOnBody => Tag::ALLOW_WHILE_ON_BODY,
199 KeyParameterValue::TrustedUserPresenceRequired => Tag::TRUSTED_USER_PRESENCE_REQUIRED,
200 KeyParameterValue::TrustedConfirmationRequired => Tag::TRUSTED_CONFIRMATION_REQUIRED,
201 KeyParameterValue::UnlockedDeviceRequired => Tag::UNLOCKED_DEVICE_REQUIRED,
202 KeyParameterValue::ApplicationID(_) => Tag::APPLICATION_ID,
203 KeyParameterValue::ApplicationData(_) => Tag::APPLICATION_DATA,
204 KeyParameterValue::CreationDateTime(_) => Tag::CREATION_DATETIME,
205 KeyParameterValue::KeyOrigin(_) => Tag::ORIGIN,
206 KeyParameterValue::RootOfTrust(_) => Tag::ROOT_OF_TRUST,
207 KeyParameterValue::OSVersion(_) => Tag::OS_VERSION,
208 KeyParameterValue::OSPatchLevel(_) => Tag::OS_PATCHLEVEL,
209 KeyParameterValue::UniqueID(_) => Tag::UNIQUE_ID,
210 KeyParameterValue::AttestationChallenge(_) => Tag::ATTESTATION_CHALLENGE,
211 KeyParameterValue::AttestationApplicationID(_) => Tag::ATTESTATION_APPLICATION_ID,
212 KeyParameterValue::AttestationIdBrand(_) => Tag::ATTESTATION_ID_BRAND,
213 KeyParameterValue::AttestationIdDevice(_) => Tag::ATTESTATION_ID_DEVICE,
214 KeyParameterValue::AttestationIdProduct(_) => Tag::ATTESTATION_ID_PRODUCT,
215 KeyParameterValue::AttestationIdSerial(_) => Tag::ATTESTATION_ID_SERIAL,
216 KeyParameterValue::AttestationIdIMEI(_) => Tag::ATTESTATION_ID_IMEI,
217 KeyParameterValue::AttestationIdMEID(_) => Tag::ATTESTATION_ID_MEID,
218 KeyParameterValue::AttestationIdManufacturer(_) => Tag::ATTESTATION_ID_MANUFACTURER,
219 KeyParameterValue::AttestationIdModel(_) => Tag::ATTESTATION_ID_MODEL,
220 KeyParameterValue::VendorPatchLevel(_) => Tag::VENDOR_PATCHLEVEL,
221 KeyParameterValue::BootPatchLevel(_) => Tag::BOOT_PATCHLEVEL,
222 KeyParameterValue::AssociatedData(_) => Tag::ASSOCIATED_DATA,
223 KeyParameterValue::Nonce(_) => Tag::NONCE,
224 KeyParameterValue::MacLength(_) => Tag::MAC_LENGTH,
225 KeyParameterValue::ResetSinceIdRotation => Tag::RESET_SINCE_ID_ROTATION,
226 KeyParameterValue::ConfirmationToken(_) => Tag::CONFIRMATION_TOKEN,
227 }
228 }
229
230 /// Returns key parameter value.
231 pub fn key_parameter_value(&self) -> &KeyParameterValue {
232 &self.key_parameter_value
233 }
234
235 /// Returns the security level of a KeyParameter.
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000236 pub fn security_level(&self) -> &SecurityLevelType {
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000237 &self.security_level
238 }
239}
240
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000241/// This struct is defined to postpone converting rusqlite column value to the
242/// appropriate key parameter value until we know the corresponding tag value.
243/// Wraps the column index and a rusqlite row.
244pub struct SqlField<'a>(usize, &'a Row<'a>);
245
246impl<'a> SqlField<'a> {
Janis Danisevskis3f322cb2020-09-03 14:46:22 -0700247 /// Creates a new SqlField with the given index and row.
248 pub fn new(index: usize, row: &'a Row<'a>) -> Self {
249 Self(index, row)
250 }
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000251 /// Returns the column value from the row, when we know the expected type.
252 pub fn get<T: FromSql>(&self) -> SqlResult<T> {
253 self.1.get(self.0)
254 }
255}
256
257impl ToSql for KeyParameterValue {
258 /// Converts KeyParameterValue to be stored in rusqlite database.
259 /// Note that following variants of KeyParameterValue should not be stored:
260 /// IncludeUniqueID, ApplicationID, ApplicationData, RootOfTrust, UniqueID,
261 /// Attestation*, AssociatedData, Nonce, MacLength, ResetSinceIdRotation, ConfirmationToken.
262 /// This filtering is enforced at a higher level (i.e. enforcement module) and here we support
263 /// conversion for all the variants, to keep error handling simple.
264 fn to_sql(&self) -> SqlResult<ToSqlOutput> {
265 match self {
266 KeyParameterValue::Invalid => Ok(ToSqlOutput::from(Null)),
267 KeyParameterValue::KeyPurpose(k) => Ok(ToSqlOutput::from(*k as u32)),
268 KeyParameterValue::Algorithm(a) => Ok(ToSqlOutput::from(*a as u32)),
269 KeyParameterValue::KeySize(k) => Ok(ToSqlOutput::from(*k)),
270 KeyParameterValue::BlockMode(b) => Ok(ToSqlOutput::from(*b as u32)),
271 KeyParameterValue::Digest(d) => Ok(ToSqlOutput::from(*d as u32)),
272 KeyParameterValue::PaddingMode(p) => Ok(ToSqlOutput::from(*p as u32)),
273 KeyParameterValue::CallerNonce => Ok(ToSqlOutput::from(Null)),
274 KeyParameterValue::MinMacLength(m) => Ok(ToSqlOutput::from(*m)),
275 KeyParameterValue::EcCurve(e) => Ok(ToSqlOutput::from(*e as u32)),
276 KeyParameterValue::RSAPublicExponent(r) => Ok(ToSqlOutput::from(*r as i64)),
277 KeyParameterValue::IncludeUniqueID => Ok(ToSqlOutput::from(Null)),
278 KeyParameterValue::BootLoaderOnly => Ok(ToSqlOutput::from(Null)),
279 KeyParameterValue::RollbackResistance => Ok(ToSqlOutput::from(Null)),
280 KeyParameterValue::ActiveDateTime(a) => Ok(ToSqlOutput::from(*a as i64)),
281 KeyParameterValue::OriginationExpireDateTime(o) => Ok(ToSqlOutput::from(*o as i64)),
282 KeyParameterValue::UsageExpireDateTime(u) => Ok(ToSqlOutput::from(*u as i64)),
283 KeyParameterValue::MinSecondsBetweenOps(m) => Ok(ToSqlOutput::from(*m)),
284 KeyParameterValue::MaxUsesPerBoot(m) => Ok(ToSqlOutput::from(*m)),
285 KeyParameterValue::UserID(u) => Ok(ToSqlOutput::from(*u)),
286 KeyParameterValue::UserSecureID(u) => Ok(ToSqlOutput::from(*u as i64)),
287 KeyParameterValue::NoAuthRequired => Ok(ToSqlOutput::from(Null)),
288 KeyParameterValue::HardwareAuthenticatorType(h) => Ok(ToSqlOutput::from(*h as u32)),
289 KeyParameterValue::AuthTimeout(m) => Ok(ToSqlOutput::from(*m)),
290 KeyParameterValue::AllowWhileOnBody => Ok(ToSqlOutput::from(Null)),
291 KeyParameterValue::TrustedUserPresenceRequired => Ok(ToSqlOutput::from(Null)),
292 KeyParameterValue::TrustedConfirmationRequired => Ok(ToSqlOutput::from(Null)),
293 KeyParameterValue::UnlockedDeviceRequired => Ok(ToSqlOutput::from(Null)),
294 KeyParameterValue::ApplicationID(a) => Ok(ToSqlOutput::from(a.to_vec())),
295 KeyParameterValue::ApplicationData(a) => Ok(ToSqlOutput::from(a.to_vec())),
296 KeyParameterValue::CreationDateTime(c) => Ok(ToSqlOutput::from(*c as i64)),
297 KeyParameterValue::KeyOrigin(k) => Ok(ToSqlOutput::from(*k as u32)),
298 KeyParameterValue::RootOfTrust(r) => Ok(ToSqlOutput::from(r.to_vec())),
299 KeyParameterValue::OSVersion(o) => Ok(ToSqlOutput::from(*o)),
300 KeyParameterValue::OSPatchLevel(o) => Ok(ToSqlOutput::from(*o)),
301 KeyParameterValue::UniqueID(u) => Ok(ToSqlOutput::from(u.to_vec())),
302 KeyParameterValue::AttestationChallenge(a) => Ok(ToSqlOutput::from(a.to_vec())),
303 KeyParameterValue::AttestationApplicationID(a) => Ok(ToSqlOutput::from(a.to_vec())),
304 KeyParameterValue::AttestationIdBrand(a) => Ok(ToSqlOutput::from(a.to_vec())),
305 KeyParameterValue::AttestationIdDevice(a) => Ok(ToSqlOutput::from(a.to_vec())),
306 KeyParameterValue::AttestationIdProduct(a) => Ok(ToSqlOutput::from(a.to_vec())),
307 KeyParameterValue::AttestationIdSerial(a) => Ok(ToSqlOutput::from(a.to_vec())),
308 KeyParameterValue::AttestationIdIMEI(a) => Ok(ToSqlOutput::from(a.to_vec())),
309 KeyParameterValue::AttestationIdMEID(a) => Ok(ToSqlOutput::from(a.to_vec())),
310 KeyParameterValue::AttestationIdManufacturer(a) => Ok(ToSqlOutput::from(a.to_vec())),
311 KeyParameterValue::AttestationIdModel(a) => Ok(ToSqlOutput::from(a.to_vec())),
312 KeyParameterValue::VendorPatchLevel(v) => Ok(ToSqlOutput::from(*v)),
313 KeyParameterValue::BootPatchLevel(b) => Ok(ToSqlOutput::from(*b)),
314 KeyParameterValue::AssociatedData(a) => Ok(ToSqlOutput::from(a.to_vec())),
315 KeyParameterValue::Nonce(n) => Ok(ToSqlOutput::from(n.to_vec())),
316 KeyParameterValue::MacLength(m) => Ok(ToSqlOutput::from(*m)),
317 KeyParameterValue::ResetSinceIdRotation => Ok(ToSqlOutput::from(Null)),
318 KeyParameterValue::ConfirmationToken(c) => Ok(ToSqlOutput::from(c.to_vec())),
319 }
320 }
321}
322
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000323impl KeyParameter {
324 /// Construct a KeyParameter from the data from a rusqlite row.
325 /// Note that following variants of KeyParameterValue should not be stored:
326 /// IncludeUniqueID, ApplicationID, ApplicationData, RootOfTrust, UniqueID,
327 /// Attestation*, AssociatedData, Nonce, MacLength, ResetSinceIdRotation, ConfirmationToken.
328 /// This filtering is enforced at a higher level and here we support conversion for all the
329 /// variants.
330 pub fn new_from_sql(
331 tag_val: TagType,
332 data: &SqlField,
333 security_level_val: SecurityLevelType,
334 ) -> Result<Self> {
335 let key_param_value = match tag_val {
336 Tag::INVALID => KeyParameterValue::Invalid,
337 Tag::PURPOSE => {
338 let key_purpose: KeyPurposeType = data
339 .get()
Janis Danisevskise24f3472020-08-12 17:58:49 -0700340 .map_err(|_| KeystoreError::Rc(Rc::ValueCorrupted))
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700341 .context("Failed to read sql data for tag: PURPOSE.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000342 KeyParameterValue::KeyPurpose(key_purpose)
343 }
344 Tag::ALGORITHM => {
345 let algorithm: AlgorithmType = data
346 .get()
Janis Danisevskise24f3472020-08-12 17:58:49 -0700347 .map_err(|_| KeystoreError::Rc(Rc::ValueCorrupted))
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700348 .context("Failed to read sql data for tag: ALGORITHM.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000349 KeyParameterValue::Algorithm(algorithm)
350 }
351 Tag::KEY_SIZE => {
352 let key_size: i32 =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700353 data.get().context("Failed to read sql data for tag: KEY_SIZE.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000354 KeyParameterValue::KeySize(key_size)
355 }
356 Tag::BLOCK_MODE => {
357 let block_mode: BlockModeType = data
358 .get()
Janis Danisevskise24f3472020-08-12 17:58:49 -0700359 .map_err(|_| KeystoreError::Rc(Rc::ValueCorrupted))
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700360 .context("Failed to read sql data for tag: BLOCK_MODE.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000361 KeyParameterValue::BlockMode(block_mode)
362 }
363 Tag::DIGEST => {
364 let digest: DigestType = data
365 .get()
Janis Danisevskise24f3472020-08-12 17:58:49 -0700366 .map_err(|_| KeystoreError::Rc(Rc::ValueCorrupted))
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700367 .context("Failed to read sql data for tag: DIGEST.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000368 KeyParameterValue::Digest(digest)
369 }
370 Tag::PADDING => {
371 let padding: PaddingModeType = data
372 .get()
Janis Danisevskise24f3472020-08-12 17:58:49 -0700373 .map_err(|_| KeystoreError::Rc(Rc::ValueCorrupted))
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700374 .context("Failed to read sql data for tag: PADDING.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000375 KeyParameterValue::PaddingMode(padding)
376 }
377 Tag::CALLER_NONCE => KeyParameterValue::CallerNonce,
378 Tag::MIN_MAC_LENGTH => {
379 let min_mac_length: i32 =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700380 data.get().context("Failed to read sql data for tag: MIN_MAC_LENGTH.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000381 KeyParameterValue::MinMacLength(min_mac_length)
382 }
383 Tag::EC_CURVE => {
384 let ec_curve: EcCurveType = data
385 .get()
Janis Danisevskise24f3472020-08-12 17:58:49 -0700386 .map_err(|_| KeystoreError::Rc(Rc::ValueCorrupted))
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700387 .context("Failed to read sql data for tag: EC_CURVE.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000388 KeyParameterValue::EcCurve(ec_curve)
389 }
390 Tag::RSA_PUBLIC_EXPONENT => {
391 let rsa_pub_exponent: i64 =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700392 data.get().context("Failed to read sql data for tag: RSA_PUBLIC_EXPONENT.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000393
394 KeyParameterValue::RSAPublicExponent(rsa_pub_exponent)
395 }
396 Tag::INCLUDE_UNIQUE_ID => KeyParameterValue::IncludeUniqueID,
397 Tag::BOOTLOADER_ONLY => KeyParameterValue::BootLoaderOnly,
398 Tag::ROLLBACK_RESISTANCE => KeyParameterValue::RollbackResistance,
399 Tag::ACTIVE_DATETIME => {
400 let active_datetime: i64 =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700401 data.get().context("Failed to read sql data for tag: ACTIVE_DATETIME.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000402 KeyParameterValue::ActiveDateTime(active_datetime)
403 }
404 Tag::ORIGINATION_EXPIRE_DATETIME => {
405 let origination_expire_datetime: i64 = data
406 .get()
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700407 .context("Failed to read sql data for tag: ORIGINATION_EXPIRE_DATETIME.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000408 KeyParameterValue::OriginationExpireDateTime(origination_expire_datetime)
409 }
410 Tag::USAGE_EXPIRE_DATETIME => {
411 let usage_expire_datetime: i64 = data
412 .get()
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700413 .context("Failed to read sql data for tag: USAGE_EXPIRE_DATETIME.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000414 KeyParameterValue::UsageExpireDateTime(usage_expire_datetime)
415 }
416 Tag::MIN_SECONDS_BETWEEN_OPS => {
417 let min_secs_between_ops: i32 = data
418 .get()
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700419 .context("Failed to read sql data for tag: MIN_SECONDS_BETWEEN_OPS.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000420 KeyParameterValue::MinSecondsBetweenOps(min_secs_between_ops)
421 }
422 Tag::MAX_USES_PER_BOOT => {
423 let max_uses_per_boot: i32 =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700424 data.get().context("Failed to read sql data for tag: MAX_USES_PER_BOOT.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000425 KeyParameterValue::MaxUsesPerBoot(max_uses_per_boot)
426 }
427 Tag::USER_ID => {
428 let user_id: i32 =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700429 data.get().context("Failed to read sql data for tag: USER_ID.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000430 KeyParameterValue::UserID(user_id)
431 }
432 Tag::USER_SECURE_ID => {
433 let user_secure_id: i64 =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700434 data.get().context("Failed to read sql data for tag: USER_SECURE_ID.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000435 KeyParameterValue::UserSecureID(user_secure_id)
436 }
437 Tag::NO_AUTH_REQUIRED => KeyParameterValue::NoAuthRequired,
438 Tag::USER_AUTH_TYPE => {
439 let user_auth_type: HardwareAuthenticatorTypeType = data
440 .get()
Janis Danisevskise24f3472020-08-12 17:58:49 -0700441 .map_err(|_| KeystoreError::Rc(Rc::ValueCorrupted))
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700442 .context("Failed to read sql data for tag: USER_AUTH_TYPE.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000443 KeyParameterValue::HardwareAuthenticatorType(user_auth_type)
444 }
445 Tag::AUTH_TIMEOUT => {
446 let auth_timeout: i32 =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700447 data.get().context("Failed to read sql data for tag: AUTH_TIMEOUT.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000448 KeyParameterValue::AuthTimeout(auth_timeout)
449 }
450 Tag::ALLOW_WHILE_ON_BODY => KeyParameterValue::AllowWhileOnBody,
451 Tag::TRUSTED_USER_PRESENCE_REQUIRED => KeyParameterValue::TrustedUserPresenceRequired,
452 Tag::TRUSTED_CONFIRMATION_REQUIRED => KeyParameterValue::TrustedConfirmationRequired,
453 Tag::UNLOCKED_DEVICE_REQUIRED => KeyParameterValue::UnlockedDeviceRequired,
454 Tag::APPLICATION_ID => {
455 let app_id: Vec<u8> =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700456 data.get().context("Failed to read sql data for tag: APPLICATION_ID.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000457 KeyParameterValue::ApplicationID(app_id)
458 }
459 Tag::APPLICATION_DATA => {
460 let app_data: Vec<u8> =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700461 data.get().context("Failed to read sql data for tag: APPLICATION_DATA.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000462 KeyParameterValue::ApplicationData(app_data)
463 }
464 Tag::CREATION_DATETIME => {
465 let creation_datetime: i64 =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700466 data.get().context("Failed to read sql data for tag: CREATION_DATETIME.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000467 KeyParameterValue::CreationDateTime(creation_datetime)
468 }
469 Tag::ORIGIN => {
470 let origin: KeyOriginType = data
471 .get()
Janis Danisevskise24f3472020-08-12 17:58:49 -0700472 .map_err(|_| KeystoreError::Rc(Rc::ValueCorrupted))
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700473 .context("Failed to read sql data for tag: ORIGIN.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000474 KeyParameterValue::KeyOrigin(origin)
475 }
476 Tag::ROOT_OF_TRUST => {
477 let root_of_trust: Vec<u8> =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700478 data.get().context("Failed to read sql data for tag: ROOT_OF_TRUST.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000479 KeyParameterValue::RootOfTrust(root_of_trust)
480 }
481 Tag::OS_VERSION => {
482 let os_version: i32 =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700483 data.get().context("Failed to read sql data for tag: OS_VERSION.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000484 KeyParameterValue::OSVersion(os_version)
485 }
486 Tag::OS_PATCHLEVEL => {
487 let os_patch_level: i32 =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700488 data.get().context("Failed to read sql data for tag: OS_PATCHLEVEL.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000489 KeyParameterValue::OSPatchLevel(os_patch_level)
490 }
491 Tag::UNIQUE_ID => {
492 let unique_id: Vec<u8> =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700493 data.get().context("Failed to read sql data for tag: UNIQUE_ID.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000494 KeyParameterValue::UniqueID(unique_id)
495 }
496 Tag::ATTESTATION_CHALLENGE => {
497 let attestation_challenge: Vec<u8> = data
498 .get()
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700499 .context("Failed to read sql data for tag: ATTESTATION_CHALLENGE.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000500 KeyParameterValue::AttestationChallenge(attestation_challenge)
501 }
502 Tag::ATTESTATION_APPLICATION_ID => {
503 let attestation_app_id: Vec<u8> = data
504 .get()
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700505 .context("Failed to read sql data for tag: ATTESTATION_APPLICATION_ID.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000506 KeyParameterValue::AttestationApplicationID(attestation_app_id)
507 }
508 Tag::ATTESTATION_ID_BRAND => {
509 let attestation_id_brand: Vec<u8> =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700510 data.get().context("Failed to read sql data for tag: ATTESTATION_ID_BRAND.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000511 KeyParameterValue::AttestationIdBrand(attestation_id_brand)
512 }
513 Tag::ATTESTATION_ID_DEVICE => {
514 let attestation_id_device: Vec<u8> = data
515 .get()
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700516 .context("Failed to read sql data for tag: ATTESTATION_ID_DEVICE.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000517 KeyParameterValue::AttestationIdDevice(attestation_id_device)
518 }
519 Tag::ATTESTATION_ID_PRODUCT => {
520 let attestation_id_product: Vec<u8> = data
521 .get()
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700522 .context("Failed to read sql data for tag: ATTESTATION_ID_PRODUCT.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000523 KeyParameterValue::AttestationIdProduct(attestation_id_product)
524 }
525 Tag::ATTESTATION_ID_SERIAL => {
526 let attestation_id_serial: Vec<u8> = data
527 .get()
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700528 .context("Failed to read sql data for tag: ATTESTATION_ID_SERIAL.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000529 KeyParameterValue::AttestationIdSerial(attestation_id_serial)
530 }
531 Tag::ATTESTATION_ID_IMEI => {
532 let attestation_id_imei: Vec<u8> =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700533 data.get().context("Failed to read sql data for tag: ATTESTATION_ID_IMEI.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000534 KeyParameterValue::AttestationIdIMEI(attestation_id_imei)
535 }
536 Tag::ATTESTATION_ID_MEID => {
537 let attestation_id_meid: Vec<u8> =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700538 data.get().context("Failed to read sql data for tag: ATTESTATION_ID_MEID.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000539 KeyParameterValue::AttestationIdMEID(attestation_id_meid)
540 }
541 Tag::ATTESTATION_ID_MANUFACTURER => {
542 let attestation_id_manufacturer: Vec<u8> = data
543 .get()
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700544 .context("Failed to read sql data for tag: ATTESTATION_ID_MANUFACTURER.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000545 KeyParameterValue::AttestationIdManufacturer(attestation_id_manufacturer)
546 }
547 Tag::ATTESTATION_ID_MODEL => {
548 let attestation_id_model: Vec<u8> =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700549 data.get().context("Failed to read sql data for tag: ATTESTATION_ID_MODEL.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000550 KeyParameterValue::AttestationIdModel(attestation_id_model)
551 }
552 Tag::VENDOR_PATCHLEVEL => {
553 let vendor_patch_level: i32 =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700554 data.get().context("Failed to read sql data for tag: VENDOR_PATCHLEVEL.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000555 KeyParameterValue::VendorPatchLevel(vendor_patch_level)
556 }
557 Tag::BOOT_PATCHLEVEL => {
558 let boot_patch_level: i32 =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700559 data.get().context("Failed to read sql data for tag: BOOT_PATCHLEVEL.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000560 KeyParameterValue::BootPatchLevel(boot_patch_level)
561 }
562 Tag::ASSOCIATED_DATA => {
563 let associated_data: Vec<u8> =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700564 data.get().context("Failed to read sql data for tag: ASSOCIATED_DATA.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000565 KeyParameterValue::AssociatedData(associated_data)
566 }
567 Tag::NONCE => {
568 let nonce: Vec<u8> =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700569 data.get().context("Failed to read sql data for tag: NONCE.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000570 KeyParameterValue::Nonce(nonce)
571 }
572 Tag::MAC_LENGTH => {
573 let mac_length: i32 =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700574 data.get().context("Failed to read sql data for tag: MAC_LENGTH.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000575 KeyParameterValue::MacLength(mac_length)
576 }
577 Tag::RESET_SINCE_ID_ROTATION => KeyParameterValue::ResetSinceIdRotation,
578 Tag::CONFIRMATION_TOKEN => {
579 let confirmation_token: Vec<u8> =
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700580 data.get().context("Failed to read sql data for tag: CONFIRMATION_TOKEN.")?;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000581 KeyParameterValue::ConfirmationToken(confirmation_token)
582 }
583 _ => {
Janis Danisevskise24f3472020-08-12 17:58:49 -0700584 return Err(KeystoreError::Rc(Rc::ValueCorrupted))
Joel Galenson5c0ec0d2020-09-02 14:24:30 -0700585 .context("Failed to decode Tag enum from value.")?
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000586 }
587 };
588 Ok(KeyParameter::new(key_param_value, security_level_val))
589 }
590}
591
Hasini Gunasinghe3eb77c22020-08-28 15:45:06 +0000592/// Macro rules for converting key parameter to/from wire type.
593/// This macro takes three different pieces of information about each of the KeyParameterValue
594/// variants.
595/// 1. variant name
596/// 2. tag name corresponding to the variant
597/// 3. the field name in the AidlKeyParameter struct, in which information about this variant is
598/// stored when converted
599/// The macro takes a set of lines corresponding to each KeyParameterValue variant and generates
600/// the two conversion methods: convert_to_wire() and convert_from_wire().
601/// ## Example
602/// ```
603/// implement_key_parameter_conversion_to_from_wire! {
604/// Invalid, INVALID, na;
605/// KeyPurpose, PURPOSE, integer;
606/// CallerNonce, CALLER_NONCE, boolValue;
607/// UserSecureID, USER_SECURE_ID, longInteger;
608/// ApplicationID, APPLICATION_ID, blob;
609/// ActiveDateTime, ACTIVE_DATETIME, dateTime;
610/// }
611/// ```
612/// expands to:
613/// ```
614/// pub fn convert_to_wire(self) -> AidlKeyParameter {
615/// match self {
616/// KeyParameterValue::Invalid => AidlKeyParameter {
617/// tag: Tag::INVALID,
618/// ..Default::default()
619/// },
620/// KeyParameterValue::KeyPurpose(v) => AidlKeyParameter {
621/// tag: Tag::PURPOSE,
622/// integer: v,
623/// ..Default::default()
624/// },
625/// KeyParameterValue::CallerNonce => AidlKeyParameter {
626/// tag: Tag::CALLER_NONCE,
627/// boolValue: true,
628/// ..Default::default()
629/// },
630/// KeyParameterValue::UserSecureID(v) => AidlKeyParameter {
631/// tag: Tag::USER_SECURE_ID,
632/// longInteger: v,
633/// ..Default::default()
634/// },
635/// KeyParameterValue::ApplicationID(v) => AidlKeyParameter {
636/// tag: Tag::APPLICATION_ID,
637/// blob: v,
638/// ..Default::default()
639/// },
640/// KeyParameterValue::ActiveDateTime(v) => AidlKeyParameter {
641/// tag: Tag::ACTIVE_DATETIME,
642/// dateTime: v,
643/// ..Default::default()
644/// },
645/// }
646/// }
647/// ```
648/// and
649/// ```
650/// pub fn convert_from_wire(aidl_kp: AidlKeyParameter) -> KeyParameterValue {
651/// match aidl_kp {
652/// AidlKeyParameter {
653/// tag: Tag::INVALID,
654/// ..
655/// } => KeyParameterValue::Invalid,
656/// AidlKeyParameter {
657/// tag: Tag::PURPOSE,
658/// integer: v,
659/// ..
660/// } => KeyParameterValue::KeyPurpose(v),
661/// AidlKeyParameter {
662/// tag: Tag::CALLER_NONCE,
663/// boolValue: true,
664/// ..
665/// } => KeyParameterValue::CallerNonce,
666/// AidlKeyParameter {
667/// tag: Tag::USER_SECURE_ID,
668/// longInteger: v,
669/// ..
670/// } => KeyParameterValue::UserSecureID(v),
671/// AidlKeyParameter {
672/// tag: Tag::APPLICATION_ID,
673/// blob: v,
674/// ..
675/// } => KeyParameterValue::ApplicationID(v),
676/// AidlKeyParameter {
677/// tag: Tag::ACTIVE_DATETIME,
678/// dateTime: v,
679/// ..
680/// } => KeyParameterValue::ActiveDateTime(v),
681/// _ => KeyParameterValue::Invalid,
682/// }
683/// }
684///
685macro_rules! implement_key_parameter_conversion_to_from_wire {
686 // There are three groups of rules in this macro.
687 // 1. The first group contains the rule which acts as the public interface. It takes the input
688 // given to this macro and prepares it to be given as input to the two groups of rules
689 // mentioned below.
690 // 2. The second group starts with the prefix @to and generates convert_to_wire() method.
691 // 3. The third group starts with the prefix @from and generates convert_from_wire() method.
692 //
693 // Input to this macro is first handled by the first macro rule (belonging to the first
694 // group above), which pre-processes the input such that rules in the other two groups
695 // generate the code for the two methods, when called recursively.
696 // Each of convert_to_wire() and convert_from_wire() methods are generated using a set of
697 // four macro rules in the second two groups. These four rules intend to do the following
698 // tasks respectively:
699 // i) generates match arms related to Invalid KeyParameterValue variant.
700 // ii) generates match arms related to boolValue field in AidlKeyParameter struct.
701 // iii) generates match arms related to all the other fields in AidlKeyParameter struct.
702 // iv) generates the method definition including the match arms generated from the above
703 // three recursive macro rules.
704
705 // This rule is applied on the input given to the macro invocations from outside the macro.
706 ($($variant:ident, $tag_name:ident, $field_name:ident;)*) => {
707 // pre-processes input to target the rules that generate convert_to_wire() method.
708 implement_key_parameter_conversion_to_from_wire! {@to
709 [], $($variant, $tag_name, $field_name;)*
710 }
711 // pre-processes input to target the rules that generate convert_from_wire() method.
712 implement_key_parameter_conversion_to_from_wire! {@from
713 [], $($variant, $tag_name, $field_name;)*
714 }
715 };
716
717 // Following four rules (belonging to the aforementioned second group) generate
718 // convert_to_wire() conversion method.
719 // -----------------------------------------------------------------------
720 // This rule handles Invalid variant.
721 // On an input: 'Invalid, INVALID, na;' it generates a match arm like:
722 // KeyParameterValue::Invalid => AidlKeyParameter {
723 // tag: Tag::INVALID,
724 // ..Default::default()
725 // },
726 (@to [$($out:tt)*], Invalid, INVALID, na; $($in:tt)*) => {
727 implement_key_parameter_conversion_to_from_wire! {@to
728 [$($out)*
729 KeyParameterValue::Invalid => AidlKeyParameter {
730 tag: Tag::INVALID,
731 ..Default::default()
732 },
733 ], $($in)*
734 }
735 };
736 // This rule handles all variants that correspond to bool values.
737 // On an input like: 'CallerNonce, CALLER_NONCE, boolValue;' it generates
738 // a match arm like:
739 // KeyParameterValue::CallerNonce => AidlKeyParameter {
740 // tag: Tag::CALLER_NONCE,
741 // boolValue: true,
742 // ..Default::default()
743 // },
744 (@to [$($out:tt)*], $variant:ident, $tag_val:ident, boolValue; $($in:tt)*) => {
745 implement_key_parameter_conversion_to_from_wire! {@to
746 [$($out)*
747 KeyParameterValue::$variant => AidlKeyParameter {
748 tag: Tag::$tag_val,
749 boolValue: true,
750 ..Default::default()
751 },
752 ], $($in)*
753 }
754 };
755 // This rule handles all variants that are neither invalid nor bool values
756 // (i.e. all variants which correspond to integer, longInteger, dateTime and blob fields in
757 // AidlKeyParameter).
758 // On an input like: 'ConfirmationToken, CONFIRMATION_TOKEN, blob;' it generates a match arm
759 // like: KeyParameterValue::ConfirmationToken(v) => AidlKeyParameter {
760 // tag: Tag::CONFIRMATION_TOKEN,
761 // blob: v,
762 // ..Default::default(),
763 // }
764 (@to [$($out:tt)*], $variant:ident, $tag_val:ident, $field:ident; $($in:tt)*) => {
765 implement_key_parameter_conversion_to_from_wire! {@to
766 [$($out)*
767 KeyParameterValue::$variant(v) => AidlKeyParameter {
768 tag: Tag::$tag_val,
769 $field: v,
770 ..Default::default()
771 },
772 ], $($in)*
773 }
774 };
775 // After all the match arms are generated by the above three rules, this rule combines them
776 // into the convert_to_wire() method.
777 (@to [$($out:tt)*], ) => {
778 /// Conversion of key parameter to wire type
779 pub fn convert_to_wire(self) -> AidlKeyParameter {
780 match self {
781 $($out)*
782 }
783 }
784 };
785
786 // Following four rules (belonging to the aforementioned third group) generate
787 // convert_from_wire() conversion method.
788 // ------------------------------------------------------------------------
789 // This rule handles Invalid variant.
790 // On an input: 'Invalid, INVALID, na;' it generates a match arm like:
791 // AidlKeyParameter { tag: Tag::INVALID, .. } => KeyParameterValue::Invalid,
792 (@from [$($out:tt)*], Invalid, INVALID, na; $($in:tt)*) => {
793 implement_key_parameter_conversion_to_from_wire! {@from
794 [$($out)*
795 AidlKeyParameter {
796 tag: Tag::INVALID,
797 ..
798 } => KeyParameterValue::Invalid,
799 ], $($in)*
800 }
801 };
802 // This rule handles all variants that correspond to bool values.
803 // On an input like: 'CallerNonce, CALLER_NONCE, boolValue;' it generates a match arm like:
804 // AidlKeyParameter {
805 // tag: Tag::CALLER_NONCE,
806 // boolValue: true,
807 // ..
808 // } => KeyParameterValue::CallerNonce,
809 (@from [$($out:tt)*], $variant:ident, $tag_val:ident, boolValue; $($in:tt)*) => {
810 implement_key_parameter_conversion_to_from_wire! {@from
811 [$($out)*
812 AidlKeyParameter {
813 tag: Tag::$tag_val,
814 boolValue: true,
815 ..
816 } => KeyParameterValue::$variant,
817 ], $($in)*
818 }
819 };
820 // This rule handles all variants that are neither invalid nor bool values
821 // (i.e. all variants which correspond to integer, longInteger, dateTime and blob fields in
822 // AidlKeyParameter).
823 // On an input like: 'ConfirmationToken, CONFIRMATION_TOKEN, blob;' it generates a match arm
824 // like:
825 // AidlKeyParameter {
826 // tag: Tag::CONFIRMATION_TOKEN,
827 // blob: v,
828 // ..,
829 // } => KeyParameterValue::ConfirmationToken(v),
830 (@from [$($out:tt)*], $variant:ident, $tag_val:ident, $field:ident; $($in:tt)*) => {
831 implement_key_parameter_conversion_to_from_wire! {@from
832 [$($out)*
833 AidlKeyParameter {
834 tag: Tag::$tag_val,
835 $field: v,
836 ..
837 } => KeyParameterValue::$variant(v),
838 ], $($in)*
839 }
840 };
841 // After all the match arms are generated by the above three rules, this rule combines them
842 // into the convert_from_wire() method.
843 (@from [$($out:tt)*], ) => {
844 /// Conversion of key parameter from wire type
845 pub fn convert_from_wire(aidl_kp: AidlKeyParameter) -> KeyParameterValue {
846 match aidl_kp {
847 $($out)*
848 _ => KeyParameterValue::Invalid,
849 }
850 }
851 };
852}
853
854impl KeyParameterValue {
855 // Invoke the macro that generates the code for key parameter conversion to/from wire type
856 // with all possible variants of KeyParameterValue. Each line corresponding to a variant
857 // contains: variant identifier, tag value, and the related field name (i.e.
858 // boolValue/integer/longInteger/dateTime/blob) in the AidlKeyParameter.
859 implement_key_parameter_conversion_to_from_wire! {
860 Invalid, INVALID, na;
861 KeyPurpose, PURPOSE, integer;
862 Algorithm, ALGORITHM, integer;
863 KeySize, KEY_SIZE, integer;
864 BlockMode, BLOCK_MODE, integer;
865 Digest, DIGEST, integer;
866 PaddingMode, PADDING, integer;
867 CallerNonce, CALLER_NONCE, boolValue;
868 MinMacLength, MIN_MAC_LENGTH, integer;
869 EcCurve, EC_CURVE, integer;
870 RSAPublicExponent, RSA_PUBLIC_EXPONENT, longInteger;
871 IncludeUniqueID, INCLUDE_UNIQUE_ID, boolValue;
872 BootLoaderOnly, BOOTLOADER_ONLY, boolValue;
873 RollbackResistance, ROLLBACK_RESISTANCE, boolValue;
874 ActiveDateTime, ACTIVE_DATETIME, dateTime;
875 OriginationExpireDateTime, ORIGINATION_EXPIRE_DATETIME, dateTime;
876 UsageExpireDateTime, USAGE_EXPIRE_DATETIME, dateTime;
877 MinSecondsBetweenOps, MIN_SECONDS_BETWEEN_OPS, integer;
878 MaxUsesPerBoot, MAX_USES_PER_BOOT, integer;
879 UserID, USER_ID, integer;
880 UserSecureID, USER_SECURE_ID, longInteger;
881 NoAuthRequired, NO_AUTH_REQUIRED, boolValue;
882 HardwareAuthenticatorType, USER_AUTH_TYPE, integer;
883 AuthTimeout, AUTH_TIMEOUT, integer;
884 AllowWhileOnBody, ALLOW_WHILE_ON_BODY, boolValue;
885 TrustedUserPresenceRequired, TRUSTED_USER_PRESENCE_REQUIRED, boolValue;
886 TrustedConfirmationRequired, TRUSTED_CONFIRMATION_REQUIRED, boolValue;
887 UnlockedDeviceRequired, UNLOCKED_DEVICE_REQUIRED, boolValue;
888 ApplicationID, APPLICATION_ID, blob;
889 ApplicationData, APPLICATION_DATA, blob;
890 CreationDateTime, CREATION_DATETIME, dateTime;
891 KeyOrigin, ORIGIN, integer;
892 RootOfTrust, ROOT_OF_TRUST, blob;
893 OSVersion, OS_VERSION, integer;
894 OSPatchLevel, OS_PATCHLEVEL, integer;
895 UniqueID, UNIQUE_ID, blob;
896 AttestationChallenge, ATTESTATION_CHALLENGE, blob;
897 AttestationApplicationID, ATTESTATION_APPLICATION_ID, blob;
898 AttestationIdBrand, ATTESTATION_ID_BRAND, blob;
899 AttestationIdDevice, ATTESTATION_ID_DEVICE, blob;
900 AttestationIdProduct, ATTESTATION_ID_PRODUCT, blob;
901 AttestationIdSerial, ATTESTATION_ID_SERIAL, blob;
902 AttestationIdIMEI, ATTESTATION_ID_IMEI, blob;
903 AttestationIdMEID, ATTESTATION_ID_MEID, blob;
904 AttestationIdManufacturer, ATTESTATION_ID_MANUFACTURER, blob;
905 AttestationIdModel, ATTESTATION_ID_MODEL, blob;
906 VendorPatchLevel, VENDOR_PATCHLEVEL, integer;
907 BootPatchLevel, BOOT_PATCHLEVEL, integer;
908 AssociatedData, ASSOCIATED_DATA, blob;
909 Nonce, NONCE, blob;
910 MacLength, MAC_LENGTH, integer;
911 ResetSinceIdRotation, RESET_SINCE_ID_ROTATION, boolValue;
912 ConfirmationToken, CONFIRMATION_TOKEN, blob;
913 }
914}
915
916#[cfg(test)]
917mod basic_tests {
918 use crate::key_parameter::*;
919
920 // Test basic functionality of KeyParameter.
921 #[test]
922 fn test_key_parameter() {
923 let key_parameter = KeyParameter::new(
924 KeyParameterValue::Algorithm(Algorithm::RSA),
925 SecurityLevel::STRONGBOX,
926 );
927
928 assert_eq!(key_parameter.get_tag(), Tag::ALGORITHM);
929
930 assert_eq!(
931 *key_parameter.key_parameter_value(),
932 KeyParameterValue::Algorithm(Algorithm::RSA)
933 );
934
935 assert_eq!(*key_parameter.security_level(), SecurityLevel::STRONGBOX);
936 }
937}
938
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000939/// The storage_tests module first tests the 'new_from_sql' method for KeyParameters of different
940/// data types and then tests 'to_sql' method for KeyParameters of those
941/// different data types. The five different data types for KeyParameter values are:
942/// i) enums of u32
943/// ii) u32
944/// iii) u64
945/// iv) Vec<u8>
946/// v) bool
947#[cfg(test)]
948mod storage_tests {
949 use crate::error::*;
950 use crate::key_parameter::*;
951 use anyhow::Result;
952 use rusqlite::types::ToSql;
953 use rusqlite::{params, Connection, NO_PARAMS};
954
955 /// Test initializing a KeyParameter (with key parameter value corresponding to an enum of i32)
956 /// from a database table row.
957 #[test]
958 fn test_new_from_sql_enum_i32() -> Result<()> {
959 let db = init_db()?;
960 insert_into_keyparameter(
961 &db,
962 1,
963 Tag::ALGORITHM,
964 &Algorithm::RSA,
965 SecurityLevel::STRONGBOX,
966 )?;
967 let key_param = query_from_keyparameter(&db)?;
968 assert_eq!(Tag::ALGORITHM, key_param.get_tag());
969 assert_eq!(*key_param.key_parameter_value(), KeyParameterValue::Algorithm(Algorithm::RSA));
970 assert_eq!(*key_param.security_level(), SecurityLevel::STRONGBOX);
971 Ok(())
972 }
973
974 /// Test initializing a KeyParameter (with key parameter value which is of i32)
975 /// from a database table row.
976 #[test]
977 fn test_new_from_sql_i32() -> Result<()> {
978 let db = init_db()?;
979 insert_into_keyparameter(&db, 1, Tag::KEY_SIZE, &1024, SecurityLevel::STRONGBOX)?;
980 let key_param = query_from_keyparameter(&db)?;
981 assert_eq!(Tag::KEY_SIZE, key_param.get_tag());
982 assert_eq!(*key_param.key_parameter_value(), KeyParameterValue::KeySize(1024));
983 Ok(())
984 }
985
986 /// Test initializing a KeyParameter (with key parameter value which is of i64)
987 /// from a database table row.
988 #[test]
989 fn test_new_from_sql_i64() -> Result<()> {
990 let db = init_db()?;
991 // max value for i64, just to test corner cases
992 insert_into_keyparameter(
993 &db,
994 1,
995 Tag::RSA_PUBLIC_EXPONENT,
996 &(i64::MAX),
997 SecurityLevel::STRONGBOX,
998 )?;
999 let key_param = query_from_keyparameter(&db)?;
1000 assert_eq!(Tag::RSA_PUBLIC_EXPONENT, key_param.get_tag());
1001 assert_eq!(
1002 *key_param.key_parameter_value(),
1003 KeyParameterValue::RSAPublicExponent(i64::MAX)
1004 );
1005 Ok(())
1006 }
1007
1008 /// Test initializing a KeyParameter (with key parameter value which is of bool)
1009 /// from a database table row.
1010 #[test]
1011 fn test_new_from_sql_bool() -> Result<()> {
1012 let db = init_db()?;
1013 insert_into_keyparameter(&db, 1, Tag::CALLER_NONCE, &Null, SecurityLevel::STRONGBOX)?;
1014 let key_param = query_from_keyparameter(&db)?;
1015 assert_eq!(Tag::CALLER_NONCE, key_param.get_tag());
1016 assert_eq!(*key_param.key_parameter_value(), KeyParameterValue::CallerNonce);
1017 Ok(())
1018 }
1019
1020 /// Test initializing a KeyParameter (with key parameter value which is of Vec<u8>)
1021 /// from a database table row.
1022 #[test]
1023 fn test_new_from_sql_vec_u8() -> Result<()> {
1024 let db = init_db()?;
1025 let app_id = String::from("MyAppID");
1026 let app_id_bytes = app_id.into_bytes();
1027 insert_into_keyparameter(
1028 &db,
1029 1,
1030 Tag::APPLICATION_ID,
1031 &app_id_bytes,
1032 SecurityLevel::STRONGBOX,
1033 )?;
1034 let key_param = query_from_keyparameter(&db)?;
1035 assert_eq!(Tag::APPLICATION_ID, key_param.get_tag());
1036 assert_eq!(
1037 *key_param.key_parameter_value(),
1038 KeyParameterValue::ApplicationID(app_id_bytes)
1039 );
1040 Ok(())
1041 }
1042
1043 /// Test storing a KeyParameter (with key parameter value which corresponds to an enum of i32)
1044 /// in the database
1045 #[test]
1046 fn test_to_sql_enum_i32() -> Result<()> {
1047 let db = init_db()?;
1048 let kp = KeyParameter::new(
1049 KeyParameterValue::Algorithm(Algorithm::RSA),
1050 SecurityLevel::STRONGBOX,
1051 );
1052 store_keyparameter(&db, 1, &kp)?;
1053 let key_param = query_from_keyparameter(&db)?;
1054 assert_eq!(kp.get_tag(), key_param.get_tag());
1055 assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
1056 assert_eq!(kp.security_level(), key_param.security_level());
1057 Ok(())
1058 }
1059
1060 /// Test storing a KeyParameter (with key parameter value which is of i32) in the database
1061 #[test]
1062 fn test_to_sql_i32() -> Result<()> {
1063 let db = init_db()?;
1064 let kp = KeyParameter::new(KeyParameterValue::KeySize(1024), SecurityLevel::STRONGBOX);
1065 store_keyparameter(&db, 1, &kp)?;
1066 let key_param = query_from_keyparameter(&db)?;
1067 assert_eq!(kp.get_tag(), key_param.get_tag());
1068 assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
1069 assert_eq!(kp.security_level(), key_param.security_level());
1070 Ok(())
1071 }
1072
1073 /// Test storing a KeyParameter (with key parameter value which is of i64) in the database
1074 #[test]
1075 fn test_to_sql_i64() -> Result<()> {
1076 let db = init_db()?;
1077 // max value for i64, just to test corner cases
1078 let kp = KeyParameter::new(
1079 KeyParameterValue::RSAPublicExponent(i64::MAX),
1080 SecurityLevel::STRONGBOX,
1081 );
1082 store_keyparameter(&db, 1, &kp)?;
1083 let key_param = query_from_keyparameter(&db)?;
1084 assert_eq!(kp.get_tag(), key_param.get_tag());
1085 assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
1086 assert_eq!(kp.security_level(), key_param.security_level());
1087 Ok(())
1088 }
1089
1090 /// Test storing a KeyParameter (with key parameter value which is of Vec<u8>) in the database
1091 #[test]
1092 fn test_to_sql_vec_u8() -> Result<()> {
1093 let db = init_db()?;
1094 let kp = KeyParameter::new(
1095 KeyParameterValue::ApplicationID(String::from("MyAppID").into_bytes()),
1096 SecurityLevel::STRONGBOX,
1097 );
1098 store_keyparameter(&db, 1, &kp)?;
1099 let key_param = query_from_keyparameter(&db)?;
1100 assert_eq!(kp.get_tag(), key_param.get_tag());
1101 assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
1102 assert_eq!(kp.security_level(), key_param.security_level());
1103 Ok(())
1104 }
1105
1106 /// Test storing a KeyParameter (with key parameter value which is of i32) in the database
1107 #[test]
1108 fn test_to_sql_bool() -> Result<()> {
1109 let db = init_db()?;
1110 let kp = KeyParameter::new(KeyParameterValue::CallerNonce, SecurityLevel::STRONGBOX);
1111 store_keyparameter(&db, 1, &kp)?;
1112 let key_param = query_from_keyparameter(&db)?;
1113 assert_eq!(kp.get_tag(), key_param.get_tag());
1114 assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
1115 assert_eq!(kp.security_level(), key_param.security_level());
1116 Ok(())
1117 }
1118
1119 #[test]
1120 /// Test Tag::Invalid
1121 fn test_invalid_tag() -> Result<()> {
1122 let db = init_db()?;
1123 insert_into_keyparameter(&db, 1, 0, &123, 1)?;
1124 let key_param = query_from_keyparameter(&db)?;
1125 assert_eq!(Tag::INVALID, key_param.get_tag());
1126 Ok(())
1127 }
1128
1129 #[test]
1130 fn test_non_existing_enum_variant() -> Result<()> {
1131 let db = init_db()?;
1132 insert_into_keyparameter(&db, 1, 100, &123, 1)?;
1133 tests::check_result_contains_error_string(
1134 query_from_keyparameter(&db),
1135 "Failed to decode Tag enum from value.",
1136 );
1137 Ok(())
1138 }
1139
1140 #[test]
1141 fn test_invalid_conversion_from_sql() -> Result<()> {
1142 let db = init_db()?;
1143 insert_into_keyparameter(&db, 1, Tag::ALGORITHM, &Null, 1)?;
1144 tests::check_result_contains_error_string(
1145 query_from_keyparameter(&db),
1146 "Failed to read sql data for tag: ALGORITHM.",
1147 );
1148 Ok(())
1149 }
1150
1151 /// Helper method to init database table for key parameter
1152 fn init_db() -> Result<Connection> {
1153 let db = Connection::open_in_memory().context("Failed to initialize sqlite connection.")?;
1154 db.execute("ATTACH DATABASE ? as 'persistent';", params![""])
1155 .context("Failed to attach databases.")?;
1156 db.execute(
1157 "CREATE TABLE IF NOT EXISTS persistent.keyparameter (
1158 keyentryid INTEGER,
1159 tag INTEGER,
1160 data ANY,
1161 security_level INTEGER);",
1162 NO_PARAMS,
1163 )
1164 .context("Failed to initialize \"keyparameter\" table.")?;
1165 Ok(db)
1166 }
1167
1168 /// Helper method to insert an entry into key parameter table, with individual parameters
1169 fn insert_into_keyparameter<T: ToSql>(
1170 db: &Connection,
1171 key_id: i64,
1172 tag: i32,
1173 value: &T,
1174 security_level: i32,
1175 ) -> Result<()> {
1176 db.execute(
1177 "INSERT into persistent.keyparameter (keyentryid, tag, data, security_level)
1178VALUES(?, ?, ?, ?);",
1179 params![key_id, tag, *value, security_level],
1180 )?;
1181 Ok(())
1182 }
1183
1184 /// Helper method to store a key parameter instance.
1185 fn store_keyparameter(db: &Connection, key_id: i64, kp: &KeyParameter) -> Result<()> {
1186 db.execute(
1187 "INSERT into persistent.keyparameter (keyentryid, tag, data, security_level)
1188VALUES(?, ?, ?, ?);",
1189 params![key_id, kp.get_tag(), kp.key_parameter_value(), kp.security_level()],
1190 )?;
1191 Ok(())
1192 }
1193
1194 /// Helper method to query a row from keyparameter table
1195 fn query_from_keyparameter(db: &Connection) -> Result<KeyParameter> {
1196 let mut stmt = db.prepare(
1197 "SELECT tag, data, security_level FROM
1198persistent.keyparameter",
1199 )?;
1200 let mut rows = stmt.query(NO_PARAMS)?;
1201 let row = rows.next()?.unwrap();
1202 Ok(KeyParameter::new_from_sql(row.get(0)?, &SqlField(1, row), row.get(2)?)?)
1203 }
1204}
Hasini Gunasinghe3eb77c22020-08-28 15:45:06 +00001205
1206/// The wire_tests module tests the 'convert_to_wire' and 'convert_from_wire' methods for
1207/// KeyParameter, for the five different types used in AidlKeyParameter, in addition to Invalid
1208/// key parameter.
1209/// i) bool
1210/// ii) integer
1211/// iii) longInteger
1212/// iv) dateTime
1213/// v) blob
1214#[cfg(test)]
1215mod wire_tests {
1216 use crate::key_parameter::*;
1217 /// unit tests for to conversions
1218 #[test]
1219 fn test_convert_to_wire_invalid() {
1220 let kp = KeyParameter::new(KeyParameterValue::Invalid, SecurityLevel::STRONGBOX);
1221 let actual = KeyParameterValue::convert_to_wire(kp.key_parameter_value);
1222 assert_eq!(Tag::INVALID, actual.tag);
1223 }
1224 #[test]
1225 fn test_convert_to_wire_bool() {
1226 let kp = KeyParameter::new(KeyParameterValue::CallerNonce, SecurityLevel::STRONGBOX);
1227 let actual = KeyParameterValue::convert_to_wire(kp.key_parameter_value);
1228 assert_eq!(Tag::CALLER_NONCE, actual.tag);
1229 assert_eq!(true, actual.boolValue);
1230 }
1231 #[test]
1232 fn test_convert_to_wire_integer() {
1233 let kp = KeyParameter::new(
1234 KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
1235 SecurityLevel::STRONGBOX,
1236 );
1237 let actual = KeyParameterValue::convert_to_wire(kp.key_parameter_value);
1238 assert_eq!(Tag::PURPOSE, actual.tag);
1239 assert_eq!(KeyPurpose::ENCRYPT, actual.integer);
1240 }
1241 #[test]
1242 fn test_convert_to_wire_long_integer() {
1243 let kp =
1244 KeyParameter::new(KeyParameterValue::UserSecureID(i64::MAX), SecurityLevel::STRONGBOX);
1245 let actual = KeyParameterValue::convert_to_wire(kp.key_parameter_value);
1246 assert_eq!(Tag::USER_SECURE_ID, actual.tag);
1247 assert_eq!(i64::MAX, actual.longInteger);
1248 }
1249 #[test]
1250 fn test_convert_to_wire_date_time() {
1251 let kp = KeyParameter::new(
1252 KeyParameterValue::ActiveDateTime(i64::MAX),
1253 SecurityLevel::STRONGBOX,
1254 );
1255 let actual = KeyParameterValue::convert_to_wire(kp.key_parameter_value);
1256 assert_eq!(Tag::ACTIVE_DATETIME, actual.tag);
1257 assert_eq!(i64::MAX, actual.dateTime);
1258 }
1259 #[test]
1260 fn test_convert_to_wire_blob() {
1261 let kp = KeyParameter::new(
1262 KeyParameterValue::ConfirmationToken(String::from("ConfirmationToken").into_bytes()),
1263 SecurityLevel::STRONGBOX,
1264 );
1265 let actual = KeyParameterValue::convert_to_wire(kp.key_parameter_value);
1266 assert_eq!(Tag::CONFIRMATION_TOKEN, actual.tag);
1267 assert_eq!(String::from("ConfirmationToken").into_bytes(), actual.blob);
1268 }
1269
1270 /// unit tests for from conversion
1271 #[test]
1272 fn test_convert_from_wire_invalid() {
1273 let aidl_kp = AidlKeyParameter { tag: Tag::INVALID, ..Default::default() };
1274 let actual = KeyParameterValue::convert_from_wire(aidl_kp);
1275 assert_eq!(KeyParameterValue::Invalid, actual);
1276 }
1277 #[test]
1278 fn test_convert_from_wire_bool() {
1279 let aidl_kp =
1280 AidlKeyParameter { tag: Tag::CALLER_NONCE, boolValue: true, ..Default::default() };
1281 let actual = KeyParameterValue::convert_from_wire(aidl_kp);
1282 assert_eq!(KeyParameterValue::CallerNonce, actual);
1283 }
1284 #[test]
1285 fn test_convert_from_wire_integer() {
1286 let aidl_kp = AidlKeyParameter {
1287 tag: Tag::PURPOSE,
1288 integer: KeyPurpose::ENCRYPT,
1289 ..Default::default()
1290 };
1291 let actual = KeyParameterValue::convert_from_wire(aidl_kp);
1292 assert_eq!(KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT), actual);
1293 }
1294 #[test]
1295 fn test_convert_from_wire_long_integer() {
1296 let aidl_kp = AidlKeyParameter {
1297 tag: Tag::USER_SECURE_ID,
1298 longInteger: i64::MAX,
1299 ..Default::default()
1300 };
1301 let actual = KeyParameterValue::convert_from_wire(aidl_kp);
1302 assert_eq!(KeyParameterValue::UserSecureID(i64::MAX), actual);
1303 }
1304 #[test]
1305 fn test_convert_from_wire_date_time() {
1306 let aidl_kp = AidlKeyParameter {
1307 tag: Tag::ACTIVE_DATETIME,
1308 dateTime: i64::MAX,
1309 ..Default::default()
1310 };
1311 let actual = KeyParameterValue::convert_from_wire(aidl_kp);
1312 assert_eq!(KeyParameterValue::ActiveDateTime(i64::MAX), actual);
1313 }
1314 #[test]
1315 fn test_convert_from_wire_blob() {
1316 let aidl_kp = AidlKeyParameter {
1317 tag: Tag::CONFIRMATION_TOKEN,
1318 blob: String::from("ConfirmationToken").into_bytes(),
1319 ..Default::default()
1320 };
1321 let actual = KeyParameterValue::convert_from_wire(aidl_kp);
1322 assert_eq!(
1323 KeyParameterValue::ConfirmationToken(String::from("ConfirmationToken").into_bytes()),
1324 actual
1325 );
1326 }
1327}