diff --git a/keystore2/src/key_parameter.rs b/keystore2/src/key_parameter.rs new file mode 100644 index 00000000..d9ec7f36 --- /dev/null +++ b/keystore2/src/key_parameter.rs @@ -0,0 +1,251 @@ +// Copyright 2020, The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! KeyParameter is used to express different characteristics of a key requested by the user +//! and enforced by the OEMs. This module implements the internal representation of KeyParameter +//! and the methods to work with KeyParameter. + +use crate::keymint_definitions::{ + Algorithm, BlockMode, Digest, EcCurve, HardwareAuthenticatorType, KeyBlobUsageRequirements, + KeyOrigin, KeyPurpose, PaddingMode, SecurityLevel, Tag, +}; + +/// KeyParameter wraps the KeyParameterValue and the security level at which it is enforced. +pub struct KeyParameter { + key_parameter_value: KeyParameterValue, + security_level: SecurityLevel, +} + +/// KeyParameterValue holds a value corresponding to one of the Tags defined in +/// the AIDL spec at hardware/interfaces/keymint +#[derive(PartialEq, Debug)] +pub enum KeyParameterValue { + /// Associated with Tag:INVALID + Invalid, + /// Set of purposes for which the key may be used + KeyPurpose(KeyPurpose), + /// Cryptographic algorithm with which the key is used + Algorithm(Algorithm), + /// Size of the key , in bits + KeySize(u32), + /// Block cipher mode(s) with which the key may be used + BlockMode(BlockMode), + /// Digest algorithms that may be used with the key to perform signing and verification + Digest(Digest), + /// Padding modes that may be used with the key. Relevant to RSA, AES and 3DES keys. + PaddingMode(PaddingMode), + /// Can the caller provide a nonce for nonce-requiring operations + CallerNonce, + /// Minimum length of MAC for HMAC keys and AES keys that support GCM mode + MinMacLength(u32), + /// The elliptic curve + EcCurve(EcCurve), + /// Value of the public exponent for an RSA key pair + RSAPublicExponent(u64), + /// An attestation certificate for the generated key should contain an application-scoped + /// and time-bounded device-unique ID + IncludeUniqueID, + /// Necessary system environment conditions for the generated key to be used + KeyBlobUsageRequirements(KeyBlobUsageRequirements), + /// Only the boot loader can use the key + BootLoaderOnly, + /// When deleted, the key is guaranteed to be permanently deleted and unusable + RollbackResistance, + //TODO: HARDWARE_TYPE reserved for future use + /// The date and time at which the key becomes active + ActiveDateTime(u64), + /// The date and time at which the key expires for signing and encryption + OriginationExpireDateTime(u64), + /// The date and time at which the key expires for verification and decryption + UsageExpireDateTime(u64), + /// Minimum amount of time that elapses between allowed operations + MinSecondsBetweenOps(u32), + /// Maximum number of times that a key may be used between system reboots + MaxUsesPerBoot(u32), + /// ID of the Android user that is permitted to use the key + UserID(u32), + /// A key may only be used under a particular secure user authentication state + UserSecureID(u64), + /// No authentication is required to use this key + NoAuthRequired, + /// The types of user authenticators that may be used to authorize this key + HardwareAuthenticatorType(HardwareAuthenticatorType), + /// The time in seconds for which the key is authorized for use, after user authentication + AuthTimeout(u32), + /// The key may be used after authentication timeout if device is still on-body + AllowWhileOnBody, + /// The key must be unusable except when the user has provided proof of physical presence + TrustedUserPresenceRequired, + /// Applicable to keys with KeyPurpose SIGN, and specifies that this key must not be usable + /// unless the user provides confirmation of the data to be signed + TrustedConfirmationRequired, + /// The key may only be used when the device is unlocked + UnlockedDeviceRequired, + /// When provided to generateKey or importKey, this tag specifies data + /// that is necessary during all uses of the key + ApplicationID(Vec), + /// When provided to generateKey or importKey, this tag specifies data + /// that is necessary during all uses of the key + ApplicationData(Vec), + /// Specifies the date and time the key was created + CreationDateTime(u64), + /// Specifies where the key was created, if known + KeyOrigin(KeyOrigin), + /// The key used by verified boot to validate the operating system booted + RootOfTrust(Vec), + /// System OS version with which the key may be used + OSVersion(u32), + /// Specifies the system security patch level with which the key may be used + OSPatchLevel(u32), + /// Specifies a unique, time-based identifier + UniqueID(Vec), + /// Used to deliver a "challenge" value to the attestKey() method + AttestationChallenge(Vec), + /// The set of applications which may use a key, used only with attestKey() + AttestationApplicationID(Vec), + /// Provides the device's brand name, to attestKey() + AttestationIdBrand(Vec), + /// Provides the device's device name, to attestKey() + AttestationIdDevice(Vec), + /// Provides the device's product name, to attestKey() + AttestationIdProduct(Vec), + /// Provides the device's serial number, to attestKey() + AttestationIdSerial(Vec), + /// Provides the IMEIs for all radios on the device, to attestKey() + AttestationIdIMEI(Vec), + /// Provides the MEIDs for all radios on the device, to attestKey() + AttestationIdMEID(Vec), + /// Provides the device's manufacturer name, to attestKey() + AttestationIdManufacturer(Vec), + /// Provides the device's model name, to attestKey() + AttestationIdModel(Vec), + /// Specifies the vendor image security patch level with which the key may be used + VendorPatchLevel(u32), + /// Specifies the boot image (kernel) security patch level with which the key may be used + BootPatchLevel(u32), + /// Provides "associated data" for AES-GCM encryption or decryption + AssociatedData(Vec), + /// Provides or returns a nonce or Initialization Vector (IV) for AES-GCM, + /// AES-CBC, AES-CTR, or 3DES-CBC encryption or decryption + Nonce(Vec), + /// Provides the requested length of a MAC or GCM authentication tag, in bits + MacLength(u32), + /// Specifies whether the device has been factory reset since the + /// last unique ID rotation. Used for key attestation + ResetSinceIdRotation, + /// Used to deliver a cryptographic token proving that the user + /// confirmed a signing request + ConfirmationToken(Vec), +} + +impl KeyParameter { + /// Create an instance of KeyParameter, given the value and the security level. + pub fn new(key_parameter_value: KeyParameterValue, security_level: SecurityLevel) -> Self { + KeyParameter { key_parameter_value, security_level } + } + + /// Returns the tag given the KeyParameter instance. + pub fn get_tag(&self) -> Tag { + match self.key_parameter_value { + KeyParameterValue::Invalid => Tag::INVALID, + KeyParameterValue::KeyPurpose(_) => Tag::PURPOSE, + KeyParameterValue::Algorithm(_) => Tag::ALGORITHM, + KeyParameterValue::KeySize(_) => Tag::KEY_SIZE, + KeyParameterValue::BlockMode(_) => Tag::BLOCK_MODE, + KeyParameterValue::Digest(_) => Tag::DIGEST, + KeyParameterValue::PaddingMode(_) => Tag::PADDING, + KeyParameterValue::CallerNonce => Tag::CALLER_NONCE, + KeyParameterValue::MinMacLength(_) => Tag::MIN_MAC_LENGTH, + KeyParameterValue::EcCurve(_) => Tag::EC_CURVE, + KeyParameterValue::RSAPublicExponent(_) => Tag::RSA_PUBLIC_EXPONENT, + KeyParameterValue::IncludeUniqueID => Tag::INCLUDE_UNIQUE_ID, + KeyParameterValue::KeyBlobUsageRequirements(_) => Tag::BLOB_USAGE_REQUIREMENTS, + KeyParameterValue::BootLoaderOnly => Tag::BOOTLOADER_ONLY, + KeyParameterValue::RollbackResistance => Tag::ROLLBACK_RESISTANCE, + KeyParameterValue::ActiveDateTime(_) => Tag::ACTIVE_DATETIME, + KeyParameterValue::OriginationExpireDateTime(_) => Tag::ORIGINATION_EXPIRE_DATETIME, + KeyParameterValue::UsageExpireDateTime(_) => Tag::USAGE_EXPIRE_DATETIME, + KeyParameterValue::MinSecondsBetweenOps(_) => Tag::MIN_SECONDS_BETWEEN_OPS, + KeyParameterValue::MaxUsesPerBoot(_) => Tag::MAX_USES_PER_BOOT, + KeyParameterValue::UserID(_) => Tag::USER_ID, + KeyParameterValue::UserSecureID(_) => Tag::USER_SECURE_ID, + KeyParameterValue::NoAuthRequired => Tag::NO_AUTH_REQUIRED, + KeyParameterValue::HardwareAuthenticatorType(_) => Tag::USER_AUTH_TYPE, + KeyParameterValue::AuthTimeout(_) => Tag::AUTH_TIMEOUT, + KeyParameterValue::AllowWhileOnBody => Tag::ALLOW_WHILE_ON_BODY, + KeyParameterValue::TrustedUserPresenceRequired => Tag::TRUSTED_USER_PRESENCE_REQUIRED, + KeyParameterValue::TrustedConfirmationRequired => Tag::TRUSTED_CONFIRMATION_REQUIRED, + KeyParameterValue::UnlockedDeviceRequired => Tag::UNLOCKED_DEVICE_REQUIRED, + KeyParameterValue::ApplicationID(_) => Tag::APPLICATION_ID, + KeyParameterValue::ApplicationData(_) => Tag::APPLICATION_DATA, + KeyParameterValue::CreationDateTime(_) => Tag::CREATION_DATETIME, + KeyParameterValue::KeyOrigin(_) => Tag::ORIGIN, + KeyParameterValue::RootOfTrust(_) => Tag::ROOT_OF_TRUST, + KeyParameterValue::OSVersion(_) => Tag::OS_VERSION, + KeyParameterValue::OSPatchLevel(_) => Tag::OS_PATCHLEVEL, + KeyParameterValue::UniqueID(_) => Tag::UNIQUE_ID, + KeyParameterValue::AttestationChallenge(_) => Tag::ATTESTATION_CHALLENGE, + KeyParameterValue::AttestationApplicationID(_) => Tag::ATTESTATION_APPLICATION_ID, + KeyParameterValue::AttestationIdBrand(_) => Tag::ATTESTATION_ID_BRAND, + KeyParameterValue::AttestationIdDevice(_) => Tag::ATTESTATION_ID_DEVICE, + KeyParameterValue::AttestationIdProduct(_) => Tag::ATTESTATION_ID_PRODUCT, + KeyParameterValue::AttestationIdSerial(_) => Tag::ATTESTATION_ID_SERIAL, + KeyParameterValue::AttestationIdIMEI(_) => Tag::ATTESTATION_ID_IMEI, + KeyParameterValue::AttestationIdMEID(_) => Tag::ATTESTATION_ID_MEID, + KeyParameterValue::AttestationIdManufacturer(_) => Tag::ATTESTATION_ID_MANUFACTURER, + KeyParameterValue::AttestationIdModel(_) => Tag::ATTESTATION_ID_MODEL, + KeyParameterValue::VendorPatchLevel(_) => Tag::VENDOR_PATCHLEVEL, + KeyParameterValue::BootPatchLevel(_) => Tag::BOOT_PATCHLEVEL, + KeyParameterValue::AssociatedData(_) => Tag::ASSOCIATED_DATA, + KeyParameterValue::Nonce(_) => Tag::NONCE, + KeyParameterValue::MacLength(_) => Tag::MAC_LENGTH, + KeyParameterValue::ResetSinceIdRotation => Tag::RESET_SINCE_ID_ROTATION, + KeyParameterValue::ConfirmationToken(_) => Tag::CONFIRMATION_TOKEN, + } + } + + /// Returns key parameter value. + pub fn key_parameter_value(&self) -> &KeyParameterValue { + &self.key_parameter_value + } + + /// Returns the security level of a KeyParameter. + pub fn security_level(&self) -> &SecurityLevel { + &self.security_level + } +} + +#[cfg(test)] +mod basic_tests { + use crate::key_parameter::*; + use crate::keymint_definitions::{SecurityLevel, Tag}; + + // Test basic functionality of KeyParameter. + #[test] + fn test_key_parameter() { + let key_parameter = KeyParameter::new( + KeyParameterValue::Algorithm(Algorithm::RSA), + SecurityLevel::STRONGBOX, + ); + + assert_eq!(key_parameter.get_tag(), Tag::ALGORITHM); + + assert_eq!( + *key_parameter.key_parameter_value(), + KeyParameterValue::Algorithm(Algorithm::RSA) + ); + + assert_eq!(*key_parameter.security_level(), SecurityLevel::STRONGBOX); + } +} diff --git a/keystore2/src/keymint_definitions.rs b/keystore2/src/keymint_definitions.rs new file mode 100644 index 00000000..2658a01e --- /dev/null +++ b/keystore2/src/keymint_definitions.rs @@ -0,0 +1,177 @@ +// Copyright 2020, The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![allow(non_camel_case_types)] +#![allow(missing_docs)] + +/// This is the current interface for the code to-be-generated from the keymint AIDL. +/// The AIDL spec is at" hardware/interfaces/keymint +#[repr(u32)] +#[derive(PartialEq, Debug)] +pub enum TagType { + INVALID = 0 << 28, + ENUM = 1 << 28, + ENUM_REP = 2 << 28, + UINT = 3 << 28, + UINT_REP = 4 << 28, + ULONG = 5 << 28, + DATE = 6 << 28, + BOOL = 7 << 28, + BIGNUM = 8 << 28, + BYTES = 9 << 28, + ULONG_REP = 10 << 28, +} +#[repr(u32)] +#[derive(PartialEq, Debug, Copy, Clone)] +pub enum Tag { + INVALID = TagType::INVALID as u32, + PURPOSE = TagType::ENUM_REP as u32 | 1, + ALGORITHM = TagType::ENUM as u32 | 2, + KEY_SIZE = TagType::UINT as u32 | 3, + BLOCK_MODE = TagType::ENUM_REP as u32 | 4, + DIGEST = TagType::ENUM_REP as u32 | 5, + PADDING = TagType::ENUM_REP as u32 | 6, + CALLER_NONCE = TagType::BOOL as u32 | 7, + MIN_MAC_LENGTH = TagType::UINT as u32 | 8, + EC_CURVE = TagType::ENUM as u32 | 10, + RSA_PUBLIC_EXPONENT = TagType::ULONG as u32 | 200, + INCLUDE_UNIQUE_ID = TagType::BOOL as u32 | 202, + BLOB_USAGE_REQUIREMENTS = TagType::ENUM as u32 | 301, + BOOTLOADER_ONLY = TagType::BOOL as u32 | 302, + ROLLBACK_RESISTANCE = TagType::BOOL as u32 | 303, + ACTIVE_DATETIME = TagType::DATE as u32 | 400, + ORIGINATION_EXPIRE_DATETIME = TagType::DATE as u32 | 401, + USAGE_EXPIRE_DATETIME = TagType::DATE as u32 | 402, + MIN_SECONDS_BETWEEN_OPS = TagType::UINT as u32 | 403, + MAX_USES_PER_BOOT = TagType::UINT as u32 | 404, + USER_ID = TagType::UINT as u32 | 501, + USER_SECURE_ID = TagType::ULONG_REP as u32 | 502, + NO_AUTH_REQUIRED = TagType::BOOL as u32 | 503, + USER_AUTH_TYPE = TagType::ENUM as u32 | 504, + AUTH_TIMEOUT = TagType::UINT as u32 | 505, + ALLOW_WHILE_ON_BODY = TagType::BOOL as u32 | 506, + TRUSTED_USER_PRESENCE_REQUIRED = TagType::BOOL as u32 | 507, + TRUSTED_CONFIRMATION_REQUIRED = TagType::BOOL as u32 | 508, + UNLOCKED_DEVICE_REQUIRED = TagType::BOOL as u32 | 509, + APPLICATION_ID = TagType::BYTES as u32 | 601, + APPLICATION_DATA = TagType::BYTES as u32 | 700, + CREATION_DATETIME = TagType::DATE as u32 | 701, + ORIGIN = TagType::ENUM as u32 | 702, + ROOT_OF_TRUST = TagType::BYTES as u32 | 704, + OS_VERSION = TagType::UINT as u32 | 705, + OS_PATCHLEVEL = TagType::UINT as u32 | 706, + UNIQUE_ID = TagType::BYTES as u32 | 707, + ATTESTATION_CHALLENGE = TagType::BYTES as u32 | 708, + ATTESTATION_APPLICATION_ID = TagType::BYTES as u32 | 709, + ATTESTATION_ID_BRAND = TagType::BYTES as u32 | 710, + ATTESTATION_ID_DEVICE = TagType::BYTES as u32 | 711, + ATTESTATION_ID_PRODUCT = TagType::BYTES as u32 | 712, + ATTESTATION_ID_SERIAL = TagType::BYTES as u32 | 713, + ATTESTATION_ID_IMEI = TagType::BYTES as u32 | 714, + ATTESTATION_ID_MEID = TagType::BYTES as u32 | 715, + ATTESTATION_ID_MANUFACTURER = TagType::BYTES as u32 | 716, + ATTESTATION_ID_MODEL = TagType::BYTES as u32 | 717, + VENDOR_PATCHLEVEL = TagType::UINT as u32 | 718, + BOOT_PATCHLEVEL = TagType::UINT as u32 | 719, + ASSOCIATED_DATA = TagType::BYTES as u32 | 1000, + NONCE = TagType::BYTES as u32 | 1001, + MAC_LENGTH = TagType::UINT as u32 | 1003, + RESET_SINCE_ID_ROTATION = TagType::BOOL as u32 | 1004, + CONFIRMATION_TOKEN = TagType::BYTES as u32 | 1005, +} +#[repr(u32)] +#[derive(PartialEq, Debug, Copy, Clone)] +pub enum Algorithm { + RSA = 1, + EC = 3, + AES = 32, + TRIPLE_DES = 33, + HMAC = 128, +} +#[repr(u32)] +#[derive(PartialEq, Debug, Copy, Clone)] +pub enum BlockMode { + ECB = 1, + CBC = 2, + CTR = 3, + GCM = 32, +} +#[repr(u32)] +#[derive(PartialEq, Debug, Copy, Clone)] +pub enum PaddingMode { + NONE = 1, + RSA_OAEP = 2, + RSA_PSS = 3, + RSA_PKCS1_1_5_ENCRYPT = 4, + RSA_PKCS1_1_5_SIGN = 5, + PKCS7 = 64, +} +#[repr(u32)] +#[derive(PartialEq, Debug, Copy, Clone)] +pub enum Digest { + NONE = 0, + MD5 = 1, + SHA1 = 2, + SHA_2_224 = 3, + SHA_2_256 = 4, + SHA_2_384 = 5, + SHA_2_512 = 6, +} +#[repr(u32)] +#[derive(PartialEq, Debug, Copy, Clone)] +pub enum EcCurve { + P_224 = 0, + P_256 = 1, + P_384 = 2, + P_521 = 3, +} +#[repr(u32)] +#[derive(PartialEq, Debug, Copy, Clone)] +pub enum KeyOrigin { + GENERATED = 0, + DERIVED = 1, + IMPORTED = 2, + UNKNOWN = 3, + SECURELY_IMPORTED = 4, +} +#[repr(u32)] +#[derive(PartialEq, Debug, Copy, Clone)] +pub enum KeyBlobUsageRequirements { + STANDALONE = 0, + REQUIRES_FILE_SYSTEM = 1, +} +#[repr(u32)] +#[derive(PartialEq, Debug, Copy, Clone)] +pub enum KeyPurpose { + ENCRYPT = 0, + DECRYPT = 1, + SIGN = 2, + VERIFY = 3, + WRAP_KEY = 5, +} +#[repr(u32)] +#[derive(PartialEq, Debug, Copy, Clone)] +pub enum HardwareAuthenticatorType { + NONE = 0, + PASSWORD = 1, + FINGERPRINT = 1 << 1, + ANY = (0xFFFFFFFF as u32) as u32, +} +#[repr(u32)] +#[derive(PartialEq, Debug, Copy, Clone)] +pub enum SecurityLevel { + SOFTWARE = 0, + TRUSTED_ENVIRONMENT = 1, + STRONGBOX = 2, +} diff --git a/keystore2/src/lib.rs b/keystore2/src/lib.rs index b37773a1..13ef87d2 100644 --- a/keystore2/src/lib.rs +++ b/keystore2/src/lib.rs @@ -16,4 +16,8 @@ pub mod database; pub mod error; +/// Internal Representation of Key Parameter and convenience functions. +pub mod key_parameter; +/// Internal interface for the code to-be-generated from the keymint AIDL +pub mod keymint_definitions; pub mod permission;