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