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 //! Key parameters are declared by KeyMint to describe properties of keys and operations. 16 //! During key generation and import, key parameters are used to characterize a key, its usage 17 //! restrictions, and additional parameters for attestation. During the lifetime of the key, 18 //! the key characteristics are expressed as set of key parameters. During cryptographic 19 //! operations, clients may specify additional operation specific parameters. 20 //! This module provides a Keystore 2.0 internal representation for key parameters and 21 //! implements traits to convert it from and into KeyMint KeyParameters and store it in 22 //! the SQLite database. 23 //! 24 //! ## Synopsis 25 //! 26 //! enum KeyParameterValue { 27 //! Invalid, 28 //! Algorithm(Algorithm), 29 //! ... 30 //! } 31 //! 32 //! impl KeyParameterValue { 33 //! pub fn get_tag(&self) -> Tag; 34 //! pub fn new_from_sql(tag: Tag, data: &SqlField) -> Result<Self>; 35 //! pub fn new_from_tag_primitive_pair<T: Into<Primitive>>(tag: Tag, v: T) 36 //! -> Result<Self, PrimitiveError>; 37 //! fn to_sql(&self) -> SqlResult<ToSqlOutput> 38 //! } 39 //! 40 //! use ...::keymint::KeyParameter as KmKeyParameter; 41 //! impl Into<KmKeyParameter> for KeyParameterValue {} 42 //! impl From<KmKeyParameter> for KeyParameterValue {} 43 //! 44 //! ## Implementation 45 //! Each of the six functions is implemented as match statement over each key parameter variant. 46 //! We bootstrap these function as well as the KeyParameterValue enum itself from a single list 47 //! of key parameters, that needs to be kept in sync with the KeyMint AIDL specification. 48 //! 49 //! The list resembles an enum declaration with a few extra fields. 50 //! enum KeyParameterValue { 51 //! Invalid with tag INVALID and field Invalid, 52 //! Algorithm(Algorithm) with tag ALGORITHM and field Algorithm, 53 //! ... 54 //! } 55 //! The tag corresponds to the variant of the keymint::Tag, and the field corresponds to the 56 //! variant of the keymint::KeyParameterValue union. There is no one to one mapping between 57 //! tags and union fields, e.g., the values of both tags BOOT_PATCHLEVEL and VENDOR_PATCHLEVEL 58 //! are stored in the Integer field. 59 //! 60 //! The macros interpreting them all follow a similar pattern and follow the following fragment 61 //! naming scheme: 62 //! 63 //! Algorithm(Algorithm) with tag ALGORITHM and field Algorithm, 64 //! $vname $(($vtype ))? with tag $tag_name and field $field_name, 65 //! 66 //! Further, KeyParameterValue appears in the macro as $enum_name. 67 //! Note that $vtype is optional to accommodate variants like Invalid which don't wrap a value. 68 //! 69 //! In some cases $vtype is not part of the expansion, but we still have to modify the expansion 70 //! depending on the presence of $vtype. In these cases we recurse through the list following the 71 //! following pattern: 72 //! 73 //! (@<marker> <non repeating args>, [<out list>], [<in list>]) 74 //! 75 //! These macros usually have four rules: 76 //! * Two main recursive rules, of the form: 77 //! ( 78 //! @<marker> 79 //! <non repeating args>, 80 //! [<out list>], 81 //! [<one element pattern> <in tail>] 82 //! ) => { 83 //! macro!{@<marker> <non repeating args>, [<out list> 84 //! <one element expansion> 85 //! ], [<in tail>]} 86 //! }; 87 //! They pop one element off the <in list> and add one expansion to the out list. 88 //! The element expansion is kept on a separate line (or lines) for better readability. 89 //! The two variants differ in whether or not $vtype is expected. 90 //! * The termination condition which has an empty in list. 91 //! * The public interface, which does not have @marker and calls itself with an empty out list. 92 93 use std::convert::TryInto; 94 95 use crate::database::utils::SqlField; 96 use crate::error::Error as KeystoreError; 97 use crate::error::ResponseCode; 98 99 pub use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{ 100 Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve, 101 HardwareAuthenticatorType::HardwareAuthenticatorType, KeyOrigin::KeyOrigin, 102 KeyParameter::KeyParameter as KmKeyParameter, 103 KeyParameterValue::KeyParameterValue as KmKeyParameterValue, KeyPurpose::KeyPurpose, 104 PaddingMode::PaddingMode, SecurityLevel::SecurityLevel, Tag::Tag, 105 }; 106 use android_system_keystore2::aidl::android::system::keystore2::Authorization::Authorization; 107 use anyhow::{Context, Result}; 108 use rusqlite::types::{Null, ToSql, ToSqlOutput}; 109 use rusqlite::Result as SqlResult; 110 111 /// This trait is used to associate a primitive to any type that can be stored inside a 112 /// KeyParameterValue, especially the AIDL enum types, e.g., keymint::{Algorithm, Digest, ...}. 113 /// This allows for simplifying the macro rules, e.g., for reading from the SQL database. 114 /// An expression like `KeyParameterValue::Algorithm(row.get(0))` would not work because 115 /// a type of `Algorithm` is expected which does not implement `FromSql` and we cannot 116 /// implement it because we own neither the type nor the trait. 117 /// With AssociatePrimitive we can write an expression 118 /// `KeyParameter::Algorithm(<Algorithm>::from_primitive(row.get(0)))` to inform `get` 119 /// about the expected primitive type that it can convert into. By implementing this 120 /// trait for all inner types we can write a single rule to cover all cases (except where 121 /// there is no wrapped type): 122 /// `KeyParameterValue::$vname(<$vtype>::from_primitive(row.get(0)))` 123 trait AssociatePrimitive { 124 type Primitive; 125 from_primitive(v: Self::Primitive) -> Self126 fn from_primitive(v: Self::Primitive) -> Self; to_primitive(&self) -> Self::Primitive127 fn to_primitive(&self) -> Self::Primitive; 128 } 129 130 /// Associates the given type with i32. The macro assumes that the given type is actually a 131 /// tuple struct wrapping i32, such as AIDL enum types. 132 macro_rules! implement_associate_primitive_for_aidl_enum { 133 ($t:ty) => { 134 impl AssociatePrimitive for $t { 135 type Primitive = i32; 136 137 fn from_primitive(v: Self::Primitive) -> Self { 138 Self(v) 139 } 140 fn to_primitive(&self) -> Self::Primitive { 141 self.0 142 } 143 } 144 }; 145 } 146 147 /// Associates the given type with itself. 148 macro_rules! implement_associate_primitive_identity { 149 ($t:ty) => { 150 impl AssociatePrimitive for $t { 151 type Primitive = $t; 152 153 fn from_primitive(v: Self::Primitive) -> Self { 154 v 155 } 156 fn to_primitive(&self) -> Self::Primitive { 157 self.clone() 158 } 159 } 160 }; 161 } 162 163 implement_associate_primitive_for_aidl_enum! {Algorithm} 164 implement_associate_primitive_for_aidl_enum! {BlockMode} 165 implement_associate_primitive_for_aidl_enum! {Digest} 166 implement_associate_primitive_for_aidl_enum! {EcCurve} 167 implement_associate_primitive_for_aidl_enum! {HardwareAuthenticatorType} 168 implement_associate_primitive_for_aidl_enum! {KeyOrigin} 169 implement_associate_primitive_for_aidl_enum! {KeyPurpose} 170 implement_associate_primitive_for_aidl_enum! {PaddingMode} 171 implement_associate_primitive_for_aidl_enum! {SecurityLevel} 172 173 implement_associate_primitive_identity! {Vec<u8>} 174 implement_associate_primitive_identity! {i64} 175 implement_associate_primitive_identity! {i32} 176 177 /// This enum allows passing a primitive value to `KeyParameterValue::new_from_tag_primitive_pair` 178 /// Usually, it is not necessary to use this type directly because the function uses 179 /// `Into<Primitive>` as a trait bound. 180 pub enum Primitive { 181 /// Wraps an i64. 182 I64(i64), 183 /// Wraps an i32. 184 I32(i32), 185 /// Wraps a Vec<u8>. 186 Vec(Vec<u8>), 187 } 188 189 impl From<i64> for Primitive { from(v: i64) -> Self190 fn from(v: i64) -> Self { 191 Self::I64(v) 192 } 193 } 194 impl From<i32> for Primitive { from(v: i32) -> Self195 fn from(v: i32) -> Self { 196 Self::I32(v) 197 } 198 } 199 impl From<Vec<u8>> for Primitive { from(v: Vec<u8>) -> Self200 fn from(v: Vec<u8>) -> Self { 201 Self::Vec(v) 202 } 203 } 204 205 /// This error is returned by `KeyParameterValue::new_from_tag_primitive_pair`. 206 #[derive(thiserror::Error, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] 207 pub enum PrimitiveError { 208 /// Returned if this primitive is unsuitable for the given tag type. 209 #[error("Primitive does not match the expected tag type.")] 210 TypeMismatch, 211 /// Return if the tag type is unknown. 212 #[error("Unknown tag.")] 213 UnknownTag, 214 } 215 216 impl TryInto<i64> for Primitive { 217 type Error = PrimitiveError; 218 try_into(self) -> Result<i64, Self::Error>219 fn try_into(self) -> Result<i64, Self::Error> { 220 match self { 221 Self::I64(v) => Ok(v), 222 _ => Err(Self::Error::TypeMismatch), 223 } 224 } 225 } 226 impl TryInto<i32> for Primitive { 227 type Error = PrimitiveError; 228 try_into(self) -> Result<i32, Self::Error>229 fn try_into(self) -> Result<i32, Self::Error> { 230 match self { 231 Self::I32(v) => Ok(v), 232 _ => Err(Self::Error::TypeMismatch), 233 } 234 } 235 } 236 impl TryInto<Vec<u8>> for Primitive { 237 type Error = PrimitiveError; 238 try_into(self) -> Result<Vec<u8>, Self::Error>239 fn try_into(self) -> Result<Vec<u8>, Self::Error> { 240 match self { 241 Self::Vec(v) => Ok(v), 242 _ => Err(Self::Error::TypeMismatch), 243 } 244 } 245 } 246 247 /// Expands the list of KeyParameterValue variants as follows: 248 /// 249 /// Input: 250 /// Invalid with tag INVALID and field Invalid, 251 /// Algorithm(Algorithm) with tag ALGORITHM and field Algorithm, 252 /// 253 /// Output: 254 /// ``` 255 /// pub fn new_from_tag_primitive_pair<T: Into<Primitive>>( 256 /// tag: Tag, 257 /// v: T 258 /// ) -> Result<KeyParameterValue, PrimitiveError> { 259 /// let p: Primitive = v.into(); 260 /// Ok(match tag { 261 /// Tag::INVALID => KeyParameterValue::Invalid, 262 /// Tag::ALGORITHM => KeyParameterValue::Algorithm( 263 /// <Algorithm>::from_primitive(p.try_into()?) 264 /// ), 265 /// _ => return Err(PrimitiveError::UnknownTag), 266 /// }) 267 /// } 268 /// ``` 269 macro_rules! implement_from_tag_primitive_pair { 270 ($enum_name:ident; $($vname:ident$(($vtype:ty))? $tag_name:ident),*) => { 271 /// Returns the an instance of $enum_name or an error if the given primitive does not match 272 /// the tag type or the tag is unknown. 273 pub fn new_from_tag_primitive_pair<T: Into<Primitive>>( 274 tag: Tag, 275 v: T 276 ) -> Result<$enum_name, PrimitiveError> { 277 let p: Primitive = v.into(); 278 Ok(match tag { 279 $(Tag::$tag_name => $enum_name::$vname$(( 280 <$vtype>::from_primitive(p.try_into()?) 281 ))?,)* 282 _ => return Err(PrimitiveError::UnknownTag), 283 }) 284 } 285 }; 286 } 287 288 /// Expands the list of KeyParameterValue variants as follows: 289 /// 290 /// Input: 291 /// pub enum KeyParameterValue { 292 /// Invalid with tag INVALID and field Invalid, 293 /// Algorithm(Algorithm) with tag ALGORITHM and field Algorithm, 294 /// } 295 /// 296 /// Output: 297 /// ``` 298 /// pub enum KeyParameterValue { 299 /// Invalid, 300 /// Algorithm(Algorithm), 301 /// } 302 /// ``` 303 macro_rules! implement_enum { 304 ( 305 $(#[$enum_meta:meta])* 306 $enum_vis:vis enum $enum_name:ident { 307 $($(#[$emeta:meta])* $vname:ident$(($vtype:ty))?),* $(,)? 308 } 309 ) => { 310 $(#[$enum_meta])* 311 $enum_vis enum $enum_name { 312 $( 313 $(#[$emeta])* 314 $vname$(($vtype))? 315 ),* 316 } 317 }; 318 } 319 320 /// Expands the list of KeyParameterValue variants as follows: 321 /// 322 /// Input: 323 /// Invalid with tag INVALID and field Invalid, 324 /// Algorithm(Algorithm) with tag ALGORITHM and field Algorithm, 325 /// 326 /// Output: 327 /// ``` 328 /// pub fn get_tag(&self) -> Tag { 329 /// match self { 330 /// KeyParameterValue::Invalid => Tag::INVALID, 331 /// KeyParameterValue::Algorithm(_) => Tag::ALGORITHM, 332 /// } 333 /// } 334 /// ``` 335 macro_rules! implement_get_tag { 336 ( 337 @replace_type_spec 338 $enum_name:ident, 339 [$($out:tt)*], 340 [$vname:ident($vtype:ty) $tag_name:ident, $($in:tt)*] 341 ) => { 342 implement_get_tag!{@replace_type_spec $enum_name, [$($out)* 343 $enum_name::$vname(_) => Tag::$tag_name, 344 ], [$($in)*]} 345 }; 346 ( 347 @replace_type_spec 348 $enum_name:ident, 349 [$($out:tt)*], 350 [$vname:ident $tag_name:ident, $($in:tt)*] 351 ) => { 352 implement_get_tag!{@replace_type_spec $enum_name, [$($out)* 353 $enum_name::$vname => Tag::$tag_name, 354 ], [$($in)*]} 355 }; 356 (@replace_type_spec $enum_name:ident, [$($out:tt)*], []) => { 357 /// Returns the tag of the given instance. 358 pub fn get_tag(&self) -> Tag { 359 match self { 360 $($out)* 361 } 362 } 363 }; 364 365 ($enum_name:ident; $($vname:ident$(($vtype:ty))? $tag_name:ident),*) => { 366 implement_get_tag!{@replace_type_spec $enum_name, [], [$($vname$(($vtype))? $tag_name,)*]} 367 }; 368 } 369 370 /// Expands the list of KeyParameterValue variants as follows: 371 /// 372 /// Input: 373 /// Invalid with tag INVALID and field Invalid, 374 /// Algorithm(Algorithm) with tag ALGORITHM and field Algorithm, 375 /// 376 /// Output: 377 /// ``` 378 /// fn to_sql(&self) -> SqlResult<ToSqlOutput> { 379 /// match self { 380 /// KeyParameterValue::Invalid => Ok(ToSqlOutput::from(Null)), 381 /// KeyParameterValue::Algorithm(v) => Ok(ToSqlOutput::from(v.to_primitive())), 382 /// } 383 /// } 384 /// ``` 385 macro_rules! implement_to_sql { 386 ( 387 @replace_type_spec 388 $enum_name:ident, 389 [$($out:tt)*], 390 [$vname:ident($vtype:ty), $($in:tt)*] 391 ) => { 392 implement_to_sql!{@replace_type_spec $enum_name, [ $($out)* 393 $enum_name::$vname(v) => Ok(ToSqlOutput::from(v.to_primitive())), 394 ], [$($in)*]} 395 }; 396 ( 397 @replace_type_spec 398 $enum_name:ident, 399 [$($out:tt)*], 400 [$vname:ident, $($in:tt)*] 401 ) => { 402 implement_to_sql!{@replace_type_spec $enum_name, [ $($out)* 403 $enum_name::$vname => Ok(ToSqlOutput::from(Null)), 404 ], [$($in)*]} 405 }; 406 (@replace_type_spec $enum_name:ident, [$($out:tt)*], []) => { 407 /// Converts $enum_name to be stored in a rusqlite database. 408 fn to_sql(&self) -> SqlResult<ToSqlOutput> { 409 match self { 410 $($out)* 411 } 412 } 413 }; 414 415 416 ($enum_name:ident; $($vname:ident$(($vtype:ty))?),*) => { 417 impl ToSql for $enum_name { 418 implement_to_sql!{@replace_type_spec $enum_name, [], [$($vname$(($vtype))?,)*]} 419 } 420 421 } 422 } 423 424 /// Expands the list of KeyParameterValue variants as follows: 425 /// 426 /// Input: 427 /// Invalid with tag INVALID and field Invalid, 428 /// Algorithm(Algorithm) with tag ALGORITHM and field Algorithm, 429 /// 430 /// Output: 431 /// ``` 432 /// pub fn new_from_sql( 433 /// tag: Tag, 434 /// data: &SqlField, 435 /// ) -> Result<Self> { 436 /// Ok(match self { 437 /// Tag::Invalid => KeyParameterValue::Invalid, 438 /// Tag::ALGORITHM => { 439 /// KeyParameterValue::Algorithm(<Algorithm>::from_primitive(data 440 /// .get() 441 /// .map_err(|_| KeystoreError::Rc(ResponseCode::VALUE_CORRUPTED)) 442 /// .context(concat!("Failed to read sql data for tag: ", "ALGORITHM", "."))? 443 /// )) 444 /// }, 445 /// }) 446 /// } 447 /// ``` 448 macro_rules! implement_new_from_sql { 449 ($enum_name:ident; $($vname:ident$(($vtype:ty))? $tag_name:ident),*) => { 450 /// Takes a tag and an SqlField and attempts to construct a KeyParameter value. 451 /// This function may fail if the parameter value cannot be extracted from the 452 /// database cell. 453 pub fn new_from_sql( 454 tag: Tag, 455 data: &SqlField, 456 ) -> Result<Self> { 457 Ok(match tag { 458 $( 459 Tag::$tag_name => { 460 $enum_name::$vname$((<$vtype>::from_primitive(data 461 .get() 462 .map_err(|_| KeystoreError::Rc(ResponseCode::VALUE_CORRUPTED)) 463 .context(concat!( 464 "Failed to read sql data for tag: ", 465 stringify!($tag_name), 466 "." 467 ))? 468 )))? 469 }, 470 )* 471 _ => $enum_name::Invalid, 472 }) 473 } 474 }; 475 } 476 477 /// This key parameter default is used during the conversion from KeyParameterValue 478 /// to keymint::KeyParameterValue. Keystore's version does not have wrapped types 479 /// for boolean tags and the tag Invalid. The AIDL version uses bool and integer 480 /// variants respectively. This default function is invoked in these cases to 481 /// homogenize the rules for boolean and invalid tags. 482 /// The bool variant returns true because boolean parameters are implicitly true 483 /// if present. 484 trait KpDefault { default() -> Self485 fn default() -> Self; 486 } 487 488 impl KpDefault for i32 { default() -> Self489 fn default() -> Self { 490 0 491 } 492 } 493 494 impl KpDefault for bool { default() -> Self495 fn default() -> Self { 496 true 497 } 498 } 499 500 /// Expands the list of KeyParameterValue variants as follows: 501 /// 502 /// Input: 503 /// Invalid with tag INVALID and field Invalid, 504 /// Algorithm(Algorithm) with tag ALGORITHM and field Algorithm, 505 /// 506 /// Output: 507 /// ``` 508 /// impl From<KmKeyParameter> for KeyParameterValue { 509 /// fn from(kp: KmKeyParameter) -> Self { 510 /// match kp { 511 /// KmKeyParameter { tag: Tag::INVALID, value: KmKeyParameterValue::Invalid(_) } 512 /// => $enum_name::$vname, 513 /// KmKeyParameter { tag: Tag::Algorithm, value: KmKeyParameterValue::Algorithm(v) } 514 /// => $enum_name::Algorithm(v), 515 /// _ => $enum_name::Invalid, 516 /// } 517 /// } 518 /// } 519 /// 520 /// impl Into<KmKeyParameter> for KeyParameterValue { 521 /// fn into(self) -> KmKeyParameter { 522 /// match self { 523 /// KeyParameterValue::Invalid => KmKeyParameter { 524 /// tag: Tag::INVALID, 525 /// value: KmKeyParameterValue::Invalid(KpDefault::default()) 526 /// }, 527 /// KeyParameterValue::Algorithm(v) => KmKeyParameter { 528 /// tag: Tag::ALGORITHM, 529 /// value: KmKeyParameterValue::Algorithm(v) 530 /// }, 531 /// } 532 /// } 533 /// } 534 /// ``` 535 macro_rules! implement_try_from_to_km_parameter { 536 // The first three rules expand From<KmKeyParameter>. 537 ( 538 @from 539 $enum_name:ident, 540 [$($out:tt)*], 541 [$vname:ident($vtype:ty) $tag_name:ident $field_name:ident, $($in:tt)*] 542 ) => { 543 implement_try_from_to_km_parameter!{@from $enum_name, [$($out)* 544 KmKeyParameter { 545 tag: Tag::$tag_name, 546 value: KmKeyParameterValue::$field_name(v) 547 } => $enum_name::$vname(v), 548 ], [$($in)*] 549 }}; 550 ( 551 @from 552 $enum_name:ident, 553 [$($out:tt)*], 554 [$vname:ident $tag_name:ident $field_name:ident, $($in:tt)*] 555 ) => { 556 implement_try_from_to_km_parameter!{@from $enum_name, [$($out)* 557 KmKeyParameter { 558 tag: Tag::$tag_name, 559 value: KmKeyParameterValue::$field_name(_) 560 } => $enum_name::$vname, 561 ], [$($in)*] 562 }}; 563 (@from $enum_name:ident, [$($out:tt)*], []) => { 564 impl From<KmKeyParameter> for $enum_name { 565 fn from(kp: KmKeyParameter) -> Self { 566 match kp { 567 $($out)* 568 _ => $enum_name::Invalid, 569 } 570 } 571 } 572 }; 573 574 // The next three rules expand Into<KmKeyParameter>. 575 ( 576 @into 577 $enum_name:ident, 578 [$($out:tt)*], 579 [$vname:ident($vtype:ty) $tag_name:ident $field_name:ident, $($in:tt)*] 580 ) => { 581 implement_try_from_to_km_parameter!{@into $enum_name, [$($out)* 582 $enum_name::$vname(v) => KmKeyParameter { 583 tag: Tag::$tag_name, 584 value: KmKeyParameterValue::$field_name(v) 585 }, 586 ], [$($in)*] 587 }}; 588 ( 589 @into 590 $enum_name:ident, 591 [$($out:tt)*], 592 [$vname:ident $tag_name:ident $field_name:ident, $($in:tt)*] 593 ) => { 594 implement_try_from_to_km_parameter!{@into $enum_name, [$($out)* 595 $enum_name::$vname => KmKeyParameter { 596 tag: Tag::$tag_name, 597 value: KmKeyParameterValue::$field_name(KpDefault::default()) 598 }, 599 ], [$($in)*] 600 }}; 601 (@into $enum_name:ident, [$($out:tt)*], []) => { 602 impl From<$enum_name> for KmKeyParameter { 603 fn from(x: $enum_name) -> Self { 604 match x { 605 $($out)* 606 } 607 } 608 } 609 }; 610 611 612 ($enum_name:ident; $($vname:ident$(($vtype:ty))? $tag_name:ident $field_name:ident),*) => { 613 implement_try_from_to_km_parameter!( 614 @from $enum_name, 615 [], 616 [$($vname$(($vtype))? $tag_name $field_name,)*] 617 ); 618 implement_try_from_to_km_parameter!( 619 @into $enum_name, 620 [], 621 [$($vname$(($vtype))? $tag_name $field_name,)*] 622 ); 623 }; 624 } 625 626 /// This is the top level macro. While the other macros do most of the heavy lifting, this takes 627 /// the key parameter list and passes it on to the other macros to generate all of the conversion 628 /// functions. In addition, it generates an important test vector for verifying that tag type of the 629 /// keymint tag matches the associated keymint KeyParameterValue field. 630 macro_rules! implement_key_parameter_value { 631 ( 632 $(#[$enum_meta:meta])* 633 $enum_vis:vis enum $enum_name:ident { 634 $( 635 $(#[$($emeta:tt)+])* 636 $vname:ident$(($vtype:ty))? 637 ),* $(,)? 638 } 639 ) => { 640 implement_key_parameter_value!{ 641 @extract_attr 642 $(#[$enum_meta])* 643 $enum_vis enum $enum_name { 644 [] 645 [$( 646 [] [$(#[$($emeta)+])*] 647 $vname$(($vtype))?, 648 )*] 649 } 650 } 651 }; 652 653 ( 654 @extract_attr 655 $(#[$enum_meta:meta])* 656 $enum_vis:vis enum $enum_name:ident { 657 [$($out:tt)*] 658 [ 659 [$(#[$mout:meta])*] 660 [ 661 #[key_param(tag = $tag_name:ident, field = $field_name:ident)] 662 $(#[$($mtail:tt)+])* 663 ] 664 $vname:ident$(($vtype:ty))?, 665 $($tail:tt)* 666 ] 667 } 668 ) => { 669 implement_key_parameter_value!{ 670 @extract_attr 671 $(#[$enum_meta])* 672 $enum_vis enum $enum_name { 673 [ 674 $($out)* 675 $(#[$mout])* 676 $(#[$($mtail)+])* 677 $tag_name $field_name $vname$(($vtype))?, 678 ] 679 [$($tail)*] 680 } 681 } 682 }; 683 684 ( 685 @extract_attr 686 $(#[$enum_meta:meta])* 687 $enum_vis:vis enum $enum_name:ident { 688 [$($out:tt)*] 689 [ 690 [$(#[$mout:meta])*] 691 [ 692 #[$front:meta] 693 $(#[$($mtail:tt)+])* 694 ] 695 $vname:ident$(($vtype:ty))?, 696 $($tail:tt)* 697 ] 698 } 699 ) => { 700 implement_key_parameter_value!{ 701 @extract_attr 702 $(#[$enum_meta])* 703 $enum_vis enum $enum_name { 704 [$($out)*] 705 [ 706 [ 707 $(#[$mout])* 708 #[$front] 709 ] 710 [$(#[$($mtail)+])*] 711 $vname$(($vtype))?, 712 $($tail)* 713 ] 714 } 715 } 716 }; 717 718 ( 719 @extract_attr 720 $(#[$enum_meta:meta])* 721 $enum_vis:vis enum $enum_name:ident { 722 [$($out:tt)*] 723 [] 724 } 725 ) => { 726 implement_key_parameter_value!{ 727 @spill 728 $(#[$enum_meta])* 729 $enum_vis enum $enum_name { 730 $($out)* 731 } 732 } 733 }; 734 735 ( 736 @spill 737 $(#[$enum_meta:meta])* 738 $enum_vis:vis enum $enum_name:ident { 739 $( 740 $(#[$emeta:meta])* 741 $tag_name:ident $field_name:ident $vname:ident$(($vtype:ty))?, 742 )* 743 } 744 ) => { 745 implement_enum!( 746 $(#[$enum_meta])* 747 $enum_vis enum $enum_name { 748 $( 749 $(#[$emeta])* 750 $vname$(($vtype))? 751 ),* 752 }); 753 754 impl $enum_name { 755 implement_new_from_sql!($enum_name; $($vname$(($vtype))? $tag_name),*); 756 implement_get_tag!($enum_name; $($vname$(($vtype))? $tag_name),*); 757 implement_from_tag_primitive_pair!($enum_name; $($vname$(($vtype))? $tag_name),*); 758 759 #[cfg(test)] 760 fn make_field_matches_tag_type_test_vector() -> Vec<KmKeyParameter> { 761 vec![$(KmKeyParameter{ 762 tag: Tag::$tag_name, 763 value: KmKeyParameterValue::$field_name(Default::default())} 764 ),*] 765 } 766 } 767 768 implement_try_from_to_km_parameter!( 769 $enum_name; 770 $($vname$(($vtype))? $tag_name $field_name),* 771 ); 772 773 implement_to_sql!($enum_name; $($vname$(($vtype))?),*); 774 }; 775 } 776 777 implement_key_parameter_value! { 778 /// KeyParameterValue holds a value corresponding to one of the Tags defined in 779 /// the AIDL spec at hardware/interfaces/security/keymint 780 #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] 781 pub enum KeyParameterValue { 782 /// Associated with Tag:INVALID 783 #[key_param(tag = INVALID, field = Invalid)] 784 Invalid, 785 /// Set of purposes for which the key may be used 786 #[key_param(tag = PURPOSE, field = KeyPurpose)] 787 KeyPurpose(KeyPurpose), 788 /// Cryptographic algorithm with which the key is used 789 #[key_param(tag = ALGORITHM, field = Algorithm)] 790 Algorithm(Algorithm), 791 /// Size of the key , in bits 792 #[key_param(tag = KEY_SIZE, field = Integer)] 793 KeySize(i32), 794 /// Block cipher mode(s) with which the key may be used 795 #[key_param(tag = BLOCK_MODE, field = BlockMode)] 796 BlockMode(BlockMode), 797 /// Digest algorithms that may be used with the key to perform signing and verification 798 #[key_param(tag = DIGEST, field = Digest)] 799 Digest(Digest), 800 /// Padding modes that may be used with the key. Relevant to RSA, AES and 3DES keys. 801 #[key_param(tag = PADDING, field = PaddingMode)] 802 PaddingMode(PaddingMode), 803 /// Can the caller provide a nonce for nonce-requiring operations 804 #[key_param(tag = CALLER_NONCE, field = BoolValue)] 805 CallerNonce, 806 /// Minimum length of MAC for HMAC keys and AES keys that support GCM mode 807 #[key_param(tag = MIN_MAC_LENGTH, field = Integer)] 808 MinMacLength(i32), 809 /// The elliptic curve 810 #[key_param(tag = EC_CURVE, field = EcCurve)] 811 EcCurve(EcCurve), 812 /// Value of the public exponent for an RSA key pair 813 #[key_param(tag = RSA_PUBLIC_EXPONENT, field = LongInteger)] 814 RSAPublicExponent(i64), 815 /// An attestation certificate for the generated key should contain an application-scoped 816 /// and time-bounded device-unique ID 817 #[key_param(tag = INCLUDE_UNIQUE_ID, field = BoolValue)] 818 IncludeUniqueID, 819 //TODO: find out about this 820 // /// Necessary system environment conditions for the generated key to be used 821 // KeyBlobUsageRequirements(KeyBlobUsageRequirements), 822 /// Only the boot loader can use the key 823 #[key_param(tag = BOOTLOADER_ONLY, field = BoolValue)] 824 BootLoaderOnly, 825 /// When deleted, the key is guaranteed to be permanently deleted and unusable 826 #[key_param(tag = ROLLBACK_RESISTANCE, field = BoolValue)] 827 RollbackResistance, 828 /// The Key shall only be used during the early boot stage 829 #[key_param(tag = EARLY_BOOT_ONLY, field = BoolValue)] 830 EarlyBootOnly, 831 /// The date and time at which the key becomes active 832 #[key_param(tag = ACTIVE_DATETIME, field = DateTime)] 833 ActiveDateTime(i64), 834 /// The date and time at which the key expires for signing and encryption 835 #[key_param(tag = ORIGINATION_EXPIRE_DATETIME, field = DateTime)] 836 OriginationExpireDateTime(i64), 837 /// The date and time at which the key expires for verification and decryption 838 #[key_param(tag = USAGE_EXPIRE_DATETIME, field = DateTime)] 839 UsageExpireDateTime(i64), 840 /// Minimum amount of time that elapses between allowed operations 841 #[key_param(tag = MIN_SECONDS_BETWEEN_OPS, field = Integer)] 842 MinSecondsBetweenOps(i32), 843 /// Maximum number of times that a key may be used between system reboots 844 #[key_param(tag = MAX_USES_PER_BOOT, field = Integer)] 845 MaxUsesPerBoot(i32), 846 /// The number of times that a limited use key can be used 847 #[key_param(tag = USAGE_COUNT_LIMIT, field = Integer)] 848 UsageCountLimit(i32), 849 /// ID of the Android user that is permitted to use the key 850 #[key_param(tag = USER_ID, field = Integer)] 851 UserID(i32), 852 /// A key may only be used under a particular secure user authentication state 853 #[key_param(tag = USER_SECURE_ID, field = LongInteger)] 854 UserSecureID(i64), 855 /// No authentication is required to use this key 856 #[key_param(tag = NO_AUTH_REQUIRED, field = BoolValue)] 857 NoAuthRequired, 858 /// The types of user authenticators that may be used to authorize this key 859 #[key_param(tag = USER_AUTH_TYPE, field = HardwareAuthenticatorType)] 860 HardwareAuthenticatorType(HardwareAuthenticatorType), 861 /// The time in seconds for which the key is authorized for use, after user authentication 862 #[key_param(tag = AUTH_TIMEOUT, field = Integer)] 863 AuthTimeout(i32), 864 /// The key may be used after authentication timeout if device is still on-body 865 #[key_param(tag = ALLOW_WHILE_ON_BODY, field = BoolValue)] 866 AllowWhileOnBody, 867 /// The key must be unusable except when the user has provided proof of physical presence 868 #[key_param(tag = TRUSTED_USER_PRESENCE_REQUIRED, field = BoolValue)] 869 TrustedUserPresenceRequired, 870 /// Applicable to keys with KeyPurpose SIGN, and specifies that this key must not be usable 871 /// unless the user provides confirmation of the data to be signed 872 #[key_param(tag = TRUSTED_CONFIRMATION_REQUIRED, field = BoolValue)] 873 TrustedConfirmationRequired, 874 /// The key may only be used when the device is unlocked 875 #[key_param(tag = UNLOCKED_DEVICE_REQUIRED, field = BoolValue)] 876 UnlockedDeviceRequired, 877 /// When provided to generateKey or importKey, this tag specifies data 878 /// that is necessary during all uses of the key 879 #[key_param(tag = APPLICATION_ID, field = Blob)] 880 ApplicationID(Vec<u8>), 881 /// When provided to generateKey or importKey, this tag specifies data 882 /// that is necessary during all uses of the key 883 #[key_param(tag = APPLICATION_DATA, field = Blob)] 884 ApplicationData(Vec<u8>), 885 /// Specifies the date and time the key was created 886 #[key_param(tag = CREATION_DATETIME, field = DateTime)] 887 CreationDateTime(i64), 888 /// Specifies where the key was created, if known 889 #[key_param(tag = ORIGIN, field = Origin)] 890 KeyOrigin(KeyOrigin), 891 /// The key used by verified boot to validate the operating system booted 892 #[key_param(tag = ROOT_OF_TRUST, field = Blob)] 893 RootOfTrust(Vec<u8>), 894 /// System OS version with which the key may be used 895 #[key_param(tag = OS_VERSION, field = Integer)] 896 OSVersion(i32), 897 /// Specifies the system security patch level with which the key may be used 898 #[key_param(tag = OS_PATCHLEVEL, field = Integer)] 899 OSPatchLevel(i32), 900 /// Specifies a unique, time-based identifier 901 #[key_param(tag = UNIQUE_ID, field = Blob)] 902 UniqueID(Vec<u8>), 903 /// Used to deliver a "challenge" value to the attestKey() method 904 #[key_param(tag = ATTESTATION_CHALLENGE, field = Blob)] 905 AttestationChallenge(Vec<u8>), 906 /// The set of applications which may use a key, used only with attestKey() 907 #[key_param(tag = ATTESTATION_APPLICATION_ID, field = Blob)] 908 AttestationApplicationID(Vec<u8>), 909 /// Provides the device's brand name, to attestKey() 910 #[key_param(tag = ATTESTATION_ID_BRAND, field = Blob)] 911 AttestationIdBrand(Vec<u8>), 912 /// Provides the device's device name, to attestKey() 913 #[key_param(tag = ATTESTATION_ID_DEVICE, field = Blob)] 914 AttestationIdDevice(Vec<u8>), 915 /// Provides the device's product name, to attestKey() 916 #[key_param(tag = ATTESTATION_ID_PRODUCT, field = Blob)] 917 AttestationIdProduct(Vec<u8>), 918 /// Provides the device's serial number, to attestKey() 919 #[key_param(tag = ATTESTATION_ID_SERIAL, field = Blob)] 920 AttestationIdSerial(Vec<u8>), 921 /// Provides the IMEIs for all radios on the device, to attestKey() 922 #[key_param(tag = ATTESTATION_ID_IMEI, field = Blob)] 923 AttestationIdIMEI(Vec<u8>), 924 /// Provides the MEIDs for all radios on the device, to attestKey() 925 #[key_param(tag = ATTESTATION_ID_MEID, field = Blob)] 926 AttestationIdMEID(Vec<u8>), 927 /// Provides the device's manufacturer name, to attestKey() 928 #[key_param(tag = ATTESTATION_ID_MANUFACTURER, field = Blob)] 929 AttestationIdManufacturer(Vec<u8>), 930 /// Provides the device's model name, to attestKey() 931 #[key_param(tag = ATTESTATION_ID_MODEL, field = Blob)] 932 AttestationIdModel(Vec<u8>), 933 /// Specifies the vendor image security patch level with which the key may be used 934 #[key_param(tag = VENDOR_PATCHLEVEL, field = Integer)] 935 VendorPatchLevel(i32), 936 /// Specifies the boot image (kernel) security patch level with which the key may be used 937 #[key_param(tag = BOOT_PATCHLEVEL, field = Integer)] 938 BootPatchLevel(i32), 939 /// Provides "associated data" for AES-GCM encryption or decryption 940 #[key_param(tag = ASSOCIATED_DATA, field = Blob)] 941 AssociatedData(Vec<u8>), 942 /// Provides or returns a nonce or Initialization Vector (IV) for AES-GCM, 943 /// AES-CBC, AES-CTR, or 3DES-CBC encryption or decryption 944 #[key_param(tag = NONCE, field = Blob)] 945 Nonce(Vec<u8>), 946 /// Provides the requested length of a MAC or GCM authentication tag, in bits 947 #[key_param(tag = MAC_LENGTH, field = Integer)] 948 MacLength(i32), 949 /// Specifies whether the device has been factory reset since the 950 /// last unique ID rotation. Used for key attestation 951 #[key_param(tag = RESET_SINCE_ID_ROTATION, field = BoolValue)] 952 ResetSinceIdRotation, 953 /// Used to deliver a cryptographic token proving that the user 954 /// confirmed a signing request 955 #[key_param(tag = CONFIRMATION_TOKEN, field = Blob)] 956 ConfirmationToken(Vec<u8>), 957 /// Used to deliver the certificate serial number to the KeyMint instance 958 /// certificate generation. 959 #[key_param(tag = CERTIFICATE_SERIAL, field = Blob)] 960 CertificateSerial(Vec<u8>), 961 /// Used to deliver the certificate subject to the KeyMint instance 962 /// certificate generation. This must be DER encoded X509 name. 963 #[key_param(tag = CERTIFICATE_SUBJECT, field = Blob)] 964 CertificateSubject(Vec<u8>), 965 /// Used to deliver the not before date in milliseconds to KeyMint during key generation/import. 966 #[key_param(tag = CERTIFICATE_NOT_BEFORE, field = DateTime)] 967 CertificateNotBefore(i64), 968 /// Used to deliver the not after date in milliseconds to KeyMint during key generation/import. 969 #[key_param(tag = CERTIFICATE_NOT_AFTER, field = DateTime)] 970 CertificateNotAfter(i64), 971 /// Specifies a maximum boot level at which a key should function 972 #[key_param(tag = MAX_BOOT_LEVEL, field = Integer)] 973 MaxBootLevel(i32), 974 } 975 } 976 977 impl From<&KmKeyParameter> for KeyParameterValue { from(kp: &KmKeyParameter) -> Self978 fn from(kp: &KmKeyParameter) -> Self { 979 kp.clone().into() 980 } 981 } 982 983 /// KeyParameter wraps the KeyParameterValue and the security level at which it is enforced. 984 #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] 985 pub struct KeyParameter { 986 value: KeyParameterValue, 987 security_level: SecurityLevel, 988 } 989 990 impl KeyParameter { 991 /// Create an instance of KeyParameter, given the value and the security level. new(value: KeyParameterValue, security_level: SecurityLevel) -> Self992 pub fn new(value: KeyParameterValue, security_level: SecurityLevel) -> Self { 993 KeyParameter { value, security_level } 994 } 995 996 /// Construct a KeyParameter from the data from a rusqlite row. 997 /// Note that following variants of KeyParameterValue should not be stored: 998 /// IncludeUniqueID, ApplicationID, ApplicationData, RootOfTrust, UniqueID, 999 /// Attestation*, AssociatedData, Nonce, MacLength, ResetSinceIdRotation, ConfirmationToken. 1000 /// This filtering is enforced at a higher level and here we support conversion for all the 1001 /// variants. new_from_sql( tag_val: Tag, data: &SqlField, security_level_val: SecurityLevel, ) -> Result<Self>1002 pub fn new_from_sql( 1003 tag_val: Tag, 1004 data: &SqlField, 1005 security_level_val: SecurityLevel, 1006 ) -> Result<Self> { 1007 Ok(Self { 1008 value: KeyParameterValue::new_from_sql(tag_val, data)?, 1009 security_level: security_level_val, 1010 }) 1011 } 1012 1013 /// Get the KeyMint Tag of this this key parameter. get_tag(&self) -> Tag1014 pub fn get_tag(&self) -> Tag { 1015 self.value.get_tag() 1016 } 1017 1018 /// Returns key parameter value. key_parameter_value(&self) -> &KeyParameterValue1019 pub fn key_parameter_value(&self) -> &KeyParameterValue { 1020 &self.value 1021 } 1022 1023 /// Returns the security level of this key parameter. security_level(&self) -> &SecurityLevel1024 pub fn security_level(&self) -> &SecurityLevel { 1025 &self.security_level 1026 } 1027 1028 /// An authorization is a KeyParameter with an associated security level that is used 1029 /// to convey the key characteristics to keystore clients. This function consumes 1030 /// an internal KeyParameter representation to produce the Authorization wire type. into_authorization(self) -> Authorization1031 pub fn into_authorization(self) -> Authorization { 1032 Authorization { securityLevel: self.security_level, keyParameter: self.value.into() } 1033 } 1034 } 1035 1036 #[cfg(test)] 1037 mod generated_key_parameter_tests { 1038 use super::*; 1039 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::TagType::TagType; 1040 get_field_by_tag_type(tag: Tag) -> KmKeyParameterValue1041 fn get_field_by_tag_type(tag: Tag) -> KmKeyParameterValue { 1042 let tag_type = TagType((tag.0 as u32 & 0xF0000000) as i32); 1043 match tag { 1044 Tag::ALGORITHM => return KmKeyParameterValue::Algorithm(Default::default()), 1045 Tag::BLOCK_MODE => return KmKeyParameterValue::BlockMode(Default::default()), 1046 Tag::PADDING => return KmKeyParameterValue::PaddingMode(Default::default()), 1047 Tag::DIGEST => return KmKeyParameterValue::Digest(Default::default()), 1048 Tag::EC_CURVE => return KmKeyParameterValue::EcCurve(Default::default()), 1049 Tag::ORIGIN => return KmKeyParameterValue::Origin(Default::default()), 1050 Tag::PURPOSE => return KmKeyParameterValue::KeyPurpose(Default::default()), 1051 Tag::USER_AUTH_TYPE => { 1052 return KmKeyParameterValue::HardwareAuthenticatorType(Default::default()) 1053 } 1054 Tag::HARDWARE_TYPE => return KmKeyParameterValue::SecurityLevel(Default::default()), 1055 _ => {} 1056 } 1057 match tag_type { 1058 TagType::INVALID => return KmKeyParameterValue::Invalid(Default::default()), 1059 TagType::ENUM | TagType::ENUM_REP => {} 1060 TagType::UINT | TagType::UINT_REP => { 1061 return KmKeyParameterValue::Integer(Default::default()) 1062 } 1063 TagType::ULONG | TagType::ULONG_REP => { 1064 return KmKeyParameterValue::LongInteger(Default::default()) 1065 } 1066 TagType::DATE => return KmKeyParameterValue::DateTime(Default::default()), 1067 TagType::BOOL => return KmKeyParameterValue::BoolValue(Default::default()), 1068 TagType::BIGNUM | TagType::BYTES => { 1069 return KmKeyParameterValue::Blob(Default::default()) 1070 } 1071 _ => {} 1072 } 1073 panic!("Unknown tag/tag_type: {:?} {:?}", tag, tag_type); 1074 } 1075 check_field_matches_tag_type(list_o_parameters: &[KmKeyParameter])1076 fn check_field_matches_tag_type(list_o_parameters: &[KmKeyParameter]) { 1077 for kp in list_o_parameters.iter() { 1078 match (&kp.value, get_field_by_tag_type(kp.tag)) { 1079 (&KmKeyParameterValue::Algorithm(_), KmKeyParameterValue::Algorithm(_)) 1080 | (&KmKeyParameterValue::BlockMode(_), KmKeyParameterValue::BlockMode(_)) 1081 | (&KmKeyParameterValue::PaddingMode(_), KmKeyParameterValue::PaddingMode(_)) 1082 | (&KmKeyParameterValue::Digest(_), KmKeyParameterValue::Digest(_)) 1083 | (&KmKeyParameterValue::EcCurve(_), KmKeyParameterValue::EcCurve(_)) 1084 | (&KmKeyParameterValue::Origin(_), KmKeyParameterValue::Origin(_)) 1085 | (&KmKeyParameterValue::KeyPurpose(_), KmKeyParameterValue::KeyPurpose(_)) 1086 | ( 1087 &KmKeyParameterValue::HardwareAuthenticatorType(_), 1088 KmKeyParameterValue::HardwareAuthenticatorType(_), 1089 ) 1090 | (&KmKeyParameterValue::SecurityLevel(_), KmKeyParameterValue::SecurityLevel(_)) 1091 | (&KmKeyParameterValue::Invalid(_), KmKeyParameterValue::Invalid(_)) 1092 | (&KmKeyParameterValue::Integer(_), KmKeyParameterValue::Integer(_)) 1093 | (&KmKeyParameterValue::LongInteger(_), KmKeyParameterValue::LongInteger(_)) 1094 | (&KmKeyParameterValue::DateTime(_), KmKeyParameterValue::DateTime(_)) 1095 | (&KmKeyParameterValue::BoolValue(_), KmKeyParameterValue::BoolValue(_)) 1096 | (&KmKeyParameterValue::Blob(_), KmKeyParameterValue::Blob(_)) => {} 1097 (actual, expected) => panic!( 1098 "Tag {:?} associated with variant {:?} expected {:?}", 1099 kp.tag, actual, expected 1100 ), 1101 } 1102 } 1103 } 1104 1105 #[test] key_parameter_value_field_matches_tag_type()1106 fn key_parameter_value_field_matches_tag_type() { 1107 check_field_matches_tag_type(&KeyParameterValue::make_field_matches_tag_type_test_vector()); 1108 } 1109 } 1110 1111 #[cfg(test)] 1112 mod basic_tests { 1113 use crate::key_parameter::*; 1114 1115 // Test basic functionality of KeyParameter. 1116 #[test] test_key_parameter()1117 fn test_key_parameter() { 1118 let key_parameter = KeyParameter::new( 1119 KeyParameterValue::Algorithm(Algorithm::RSA), 1120 SecurityLevel::STRONGBOX, 1121 ); 1122 1123 assert_eq!(key_parameter.get_tag(), Tag::ALGORITHM); 1124 1125 assert_eq!( 1126 *key_parameter.key_parameter_value(), 1127 KeyParameterValue::Algorithm(Algorithm::RSA) 1128 ); 1129 1130 assert_eq!(*key_parameter.security_level(), SecurityLevel::STRONGBOX); 1131 } 1132 } 1133 1134 /// The storage_tests module first tests the 'new_from_sql' method for KeyParameters of different 1135 /// data types and then tests 'to_sql' method for KeyParameters of those 1136 /// different data types. The five different data types for KeyParameter values are: 1137 /// i) enums of u32 1138 /// ii) u32 1139 /// iii) u64 1140 /// iv) Vec<u8> 1141 /// v) bool 1142 #[cfg(test)] 1143 mod storage_tests { 1144 use crate::error::*; 1145 use crate::key_parameter::*; 1146 use anyhow::Result; 1147 use rusqlite::types::ToSql; 1148 use rusqlite::{params, Connection, NO_PARAMS}; 1149 1150 /// Test initializing a KeyParameter (with key parameter value corresponding to an enum of i32) 1151 /// from a database table row. 1152 #[test] test_new_from_sql_enum_i32() -> Result<()>1153 fn test_new_from_sql_enum_i32() -> Result<()> { 1154 let db = init_db()?; 1155 insert_into_keyparameter( 1156 &db, 1157 1, 1158 Tag::ALGORITHM.0, 1159 &Algorithm::RSA.0, 1160 SecurityLevel::STRONGBOX.0, 1161 )?; 1162 let key_param = query_from_keyparameter(&db)?; 1163 assert_eq!(Tag::ALGORITHM, key_param.get_tag()); 1164 assert_eq!(*key_param.key_parameter_value(), KeyParameterValue::Algorithm(Algorithm::RSA)); 1165 assert_eq!(*key_param.security_level(), SecurityLevel::STRONGBOX); 1166 Ok(()) 1167 } 1168 1169 /// Test initializing a KeyParameter (with key parameter value which is of i32) 1170 /// from a database table row. 1171 #[test] test_new_from_sql_i32() -> Result<()>1172 fn test_new_from_sql_i32() -> Result<()> { 1173 let db = init_db()?; 1174 insert_into_keyparameter(&db, 1, Tag::KEY_SIZE.0, &1024, SecurityLevel::STRONGBOX.0)?; 1175 let key_param = query_from_keyparameter(&db)?; 1176 assert_eq!(Tag::KEY_SIZE, key_param.get_tag()); 1177 assert_eq!(*key_param.key_parameter_value(), KeyParameterValue::KeySize(1024)); 1178 Ok(()) 1179 } 1180 1181 /// Test initializing a KeyParameter (with key parameter value which is of i64) 1182 /// from a database table row. 1183 #[test] test_new_from_sql_i64() -> Result<()>1184 fn test_new_from_sql_i64() -> Result<()> { 1185 let db = init_db()?; 1186 // max value for i64, just to test corner cases 1187 insert_into_keyparameter( 1188 &db, 1189 1, 1190 Tag::RSA_PUBLIC_EXPONENT.0, 1191 &(i64::MAX), 1192 SecurityLevel::STRONGBOX.0, 1193 )?; 1194 let key_param = query_from_keyparameter(&db)?; 1195 assert_eq!(Tag::RSA_PUBLIC_EXPONENT, key_param.get_tag()); 1196 assert_eq!( 1197 *key_param.key_parameter_value(), 1198 KeyParameterValue::RSAPublicExponent(i64::MAX) 1199 ); 1200 Ok(()) 1201 } 1202 1203 /// Test initializing a KeyParameter (with key parameter value which is of bool) 1204 /// from a database table row. 1205 #[test] test_new_from_sql_bool() -> Result<()>1206 fn test_new_from_sql_bool() -> Result<()> { 1207 let db = init_db()?; 1208 insert_into_keyparameter(&db, 1, Tag::CALLER_NONCE.0, &Null, SecurityLevel::STRONGBOX.0)?; 1209 let key_param = query_from_keyparameter(&db)?; 1210 assert_eq!(Tag::CALLER_NONCE, key_param.get_tag()); 1211 assert_eq!(*key_param.key_parameter_value(), KeyParameterValue::CallerNonce); 1212 Ok(()) 1213 } 1214 1215 /// Test initializing a KeyParameter (with key parameter value which is of Vec<u8>) 1216 /// from a database table row. 1217 #[test] test_new_from_sql_vec_u8() -> Result<()>1218 fn test_new_from_sql_vec_u8() -> Result<()> { 1219 let db = init_db()?; 1220 let app_id = String::from("MyAppID"); 1221 let app_id_bytes = app_id.into_bytes(); 1222 insert_into_keyparameter( 1223 &db, 1224 1, 1225 Tag::APPLICATION_ID.0, 1226 &app_id_bytes, 1227 SecurityLevel::STRONGBOX.0, 1228 )?; 1229 let key_param = query_from_keyparameter(&db)?; 1230 assert_eq!(Tag::APPLICATION_ID, key_param.get_tag()); 1231 assert_eq!( 1232 *key_param.key_parameter_value(), 1233 KeyParameterValue::ApplicationID(app_id_bytes) 1234 ); 1235 Ok(()) 1236 } 1237 1238 /// Test storing a KeyParameter (with key parameter value which corresponds to an enum of i32) 1239 /// in the database 1240 #[test] test_to_sql_enum_i32() -> Result<()>1241 fn test_to_sql_enum_i32() -> Result<()> { 1242 let db = init_db()?; 1243 let kp = KeyParameter::new( 1244 KeyParameterValue::Algorithm(Algorithm::RSA), 1245 SecurityLevel::STRONGBOX, 1246 ); 1247 store_keyparameter(&db, 1, &kp)?; 1248 let key_param = query_from_keyparameter(&db)?; 1249 assert_eq!(kp.get_tag(), key_param.get_tag()); 1250 assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value()); 1251 assert_eq!(kp.security_level(), key_param.security_level()); 1252 Ok(()) 1253 } 1254 1255 /// Test storing a KeyParameter (with key parameter value which is of i32) in the database 1256 #[test] test_to_sql_i32() -> Result<()>1257 fn test_to_sql_i32() -> Result<()> { 1258 let db = init_db()?; 1259 let kp = KeyParameter::new(KeyParameterValue::KeySize(1024), SecurityLevel::STRONGBOX); 1260 store_keyparameter(&db, 1, &kp)?; 1261 let key_param = query_from_keyparameter(&db)?; 1262 assert_eq!(kp.get_tag(), key_param.get_tag()); 1263 assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value()); 1264 assert_eq!(kp.security_level(), key_param.security_level()); 1265 Ok(()) 1266 } 1267 1268 /// Test storing a KeyParameter (with key parameter value which is of i64) in the database 1269 #[test] test_to_sql_i64() -> Result<()>1270 fn test_to_sql_i64() -> Result<()> { 1271 let db = init_db()?; 1272 // max value for i64, just to test corner cases 1273 let kp = KeyParameter::new( 1274 KeyParameterValue::RSAPublicExponent(i64::MAX), 1275 SecurityLevel::STRONGBOX, 1276 ); 1277 store_keyparameter(&db, 1, &kp)?; 1278 let key_param = query_from_keyparameter(&db)?; 1279 assert_eq!(kp.get_tag(), key_param.get_tag()); 1280 assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value()); 1281 assert_eq!(kp.security_level(), key_param.security_level()); 1282 Ok(()) 1283 } 1284 1285 /// Test storing a KeyParameter (with key parameter value which is of Vec<u8>) in the database 1286 #[test] test_to_sql_vec_u8() -> Result<()>1287 fn test_to_sql_vec_u8() -> Result<()> { 1288 let db = init_db()?; 1289 let kp = KeyParameter::new( 1290 KeyParameterValue::ApplicationID(String::from("MyAppID").into_bytes()), 1291 SecurityLevel::STRONGBOX, 1292 ); 1293 store_keyparameter(&db, 1, &kp)?; 1294 let key_param = query_from_keyparameter(&db)?; 1295 assert_eq!(kp.get_tag(), key_param.get_tag()); 1296 assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value()); 1297 assert_eq!(kp.security_level(), key_param.security_level()); 1298 Ok(()) 1299 } 1300 1301 /// Test storing a KeyParameter (with key parameter value which is of i32) in the database 1302 #[test] test_to_sql_bool() -> Result<()>1303 fn test_to_sql_bool() -> Result<()> { 1304 let db = init_db()?; 1305 let kp = KeyParameter::new(KeyParameterValue::CallerNonce, SecurityLevel::STRONGBOX); 1306 store_keyparameter(&db, 1, &kp)?; 1307 let key_param = query_from_keyparameter(&db)?; 1308 assert_eq!(kp.get_tag(), key_param.get_tag()); 1309 assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value()); 1310 assert_eq!(kp.security_level(), key_param.security_level()); 1311 Ok(()) 1312 } 1313 1314 #[test] 1315 /// Test Tag::Invalid test_invalid_tag() -> Result<()>1316 fn test_invalid_tag() -> Result<()> { 1317 let db = init_db()?; 1318 insert_into_keyparameter(&db, 1, 0, &123, 1)?; 1319 let key_param = query_from_keyparameter(&db)?; 1320 assert_eq!(Tag::INVALID, key_param.get_tag()); 1321 Ok(()) 1322 } 1323 1324 #[test] test_non_existing_enum_variant() -> Result<()>1325 fn test_non_existing_enum_variant() -> Result<()> { 1326 let db = init_db()?; 1327 insert_into_keyparameter(&db, 1, 100, &123, 1)?; 1328 let key_param = query_from_keyparameter(&db)?; 1329 assert_eq!(Tag::INVALID, key_param.get_tag()); 1330 Ok(()) 1331 } 1332 1333 #[test] test_invalid_conversion_from_sql() -> Result<()>1334 fn test_invalid_conversion_from_sql() -> Result<()> { 1335 let db = init_db()?; 1336 insert_into_keyparameter(&db, 1, Tag::ALGORITHM.0, &Null, 1)?; 1337 tests::check_result_contains_error_string( 1338 query_from_keyparameter(&db), 1339 "Failed to read sql data for tag: ALGORITHM.", 1340 ); 1341 Ok(()) 1342 } 1343 1344 /// Helper method to init database table for key parameter init_db() -> Result<Connection>1345 fn init_db() -> Result<Connection> { 1346 let db = Connection::open_in_memory().context("Failed to initialize sqlite connection.")?; 1347 db.execute("ATTACH DATABASE ? as 'persistent';", params![""]) 1348 .context("Failed to attach databases.")?; 1349 db.execute( 1350 "CREATE TABLE IF NOT EXISTS persistent.keyparameter ( 1351 keyentryid INTEGER, 1352 tag INTEGER, 1353 data ANY, 1354 security_level INTEGER);", 1355 NO_PARAMS, 1356 ) 1357 .context("Failed to initialize \"keyparameter\" table.")?; 1358 Ok(db) 1359 } 1360 1361 /// Helper method to insert an entry into key parameter table, with individual parameters insert_into_keyparameter<T: ToSql>( db: &Connection, key_id: i64, tag: i32, value: &T, security_level: i32, ) -> Result<()>1362 fn insert_into_keyparameter<T: ToSql>( 1363 db: &Connection, 1364 key_id: i64, 1365 tag: i32, 1366 value: &T, 1367 security_level: i32, 1368 ) -> Result<()> { 1369 db.execute( 1370 "INSERT into persistent.keyparameter (keyentryid, tag, data, security_level) 1371 VALUES(?, ?, ?, ?);", 1372 params![key_id, tag, *value, security_level], 1373 )?; 1374 Ok(()) 1375 } 1376 1377 /// Helper method to store a key parameter instance. store_keyparameter(db: &Connection, key_id: i64, kp: &KeyParameter) -> Result<()>1378 fn store_keyparameter(db: &Connection, key_id: i64, kp: &KeyParameter) -> Result<()> { 1379 db.execute( 1380 "INSERT into persistent.keyparameter (keyentryid, tag, data, security_level) 1381 VALUES(?, ?, ?, ?);", 1382 params![key_id, kp.get_tag().0, kp.key_parameter_value(), kp.security_level().0], 1383 )?; 1384 Ok(()) 1385 } 1386 1387 /// Helper method to query a row from keyparameter table query_from_keyparameter(db: &Connection) -> Result<KeyParameter>1388 fn query_from_keyparameter(db: &Connection) -> Result<KeyParameter> { 1389 let mut stmt = 1390 db.prepare("SELECT tag, data, security_level FROM persistent.keyparameter")?; 1391 let mut rows = stmt.query(NO_PARAMS)?; 1392 let row = rows.next()?.unwrap(); 1393 KeyParameter::new_from_sql( 1394 Tag(row.get(0)?), 1395 &SqlField::new(1, row), 1396 SecurityLevel(row.get(2)?), 1397 ) 1398 } 1399 } 1400 1401 /// The wire_tests module tests the 'convert_to_wire' and 'convert_from_wire' methods for 1402 /// KeyParameter, for the four different types used in KmKeyParameter, in addition to Invalid 1403 /// key parameter. 1404 /// i) bool 1405 /// ii) integer 1406 /// iii) longInteger 1407 /// iv) blob 1408 #[cfg(test)] 1409 mod wire_tests { 1410 use crate::key_parameter::*; 1411 /// unit tests for to conversions 1412 #[test] test_convert_to_wire_invalid()1413 fn test_convert_to_wire_invalid() { 1414 let kp = KeyParameter::new(KeyParameterValue::Invalid, SecurityLevel::STRONGBOX); 1415 assert_eq!( 1416 KmKeyParameter { tag: Tag::INVALID, value: KmKeyParameterValue::Invalid(0) }, 1417 kp.value.into() 1418 ); 1419 } 1420 #[test] test_convert_to_wire_bool()1421 fn test_convert_to_wire_bool() { 1422 let kp = KeyParameter::new(KeyParameterValue::CallerNonce, SecurityLevel::STRONGBOX); 1423 assert_eq!( 1424 KmKeyParameter { tag: Tag::CALLER_NONCE, value: KmKeyParameterValue::BoolValue(true) }, 1425 kp.value.into() 1426 ); 1427 } 1428 #[test] test_convert_to_wire_integer()1429 fn test_convert_to_wire_integer() { 1430 let kp = KeyParameter::new( 1431 KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT), 1432 SecurityLevel::STRONGBOX, 1433 ); 1434 assert_eq!( 1435 KmKeyParameter { 1436 tag: Tag::PURPOSE, 1437 value: KmKeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT) 1438 }, 1439 kp.value.into() 1440 ); 1441 } 1442 #[test] test_convert_to_wire_long_integer()1443 fn test_convert_to_wire_long_integer() { 1444 let kp = 1445 KeyParameter::new(KeyParameterValue::UserSecureID(i64::MAX), SecurityLevel::STRONGBOX); 1446 assert_eq!( 1447 KmKeyParameter { 1448 tag: Tag::USER_SECURE_ID, 1449 value: KmKeyParameterValue::LongInteger(i64::MAX) 1450 }, 1451 kp.value.into() 1452 ); 1453 } 1454 #[test] test_convert_to_wire_blob()1455 fn test_convert_to_wire_blob() { 1456 let kp = KeyParameter::new( 1457 KeyParameterValue::ConfirmationToken(String::from("ConfirmationToken").into_bytes()), 1458 SecurityLevel::STRONGBOX, 1459 ); 1460 assert_eq!( 1461 KmKeyParameter { 1462 tag: Tag::CONFIRMATION_TOKEN, 1463 value: KmKeyParameterValue::Blob(String::from("ConfirmationToken").into_bytes()) 1464 }, 1465 kp.value.into() 1466 ); 1467 } 1468 1469 /// unit tests for from conversion 1470 #[test] test_convert_from_wire_invalid()1471 fn test_convert_from_wire_invalid() { 1472 let aidl_kp = KmKeyParameter { tag: Tag::INVALID, ..Default::default() }; 1473 assert_eq!(KeyParameterValue::Invalid, aidl_kp.into()); 1474 } 1475 #[test] test_convert_from_wire_bool()1476 fn test_convert_from_wire_bool() { 1477 let aidl_kp = 1478 KmKeyParameter { tag: Tag::CALLER_NONCE, value: KmKeyParameterValue::BoolValue(true) }; 1479 assert_eq!(KeyParameterValue::CallerNonce, aidl_kp.into()); 1480 } 1481 #[test] test_convert_from_wire_integer()1482 fn test_convert_from_wire_integer() { 1483 let aidl_kp = KmKeyParameter { 1484 tag: Tag::PURPOSE, 1485 value: KmKeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT), 1486 }; 1487 assert_eq!(KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT), aidl_kp.into()); 1488 } 1489 #[test] test_convert_from_wire_long_integer()1490 fn test_convert_from_wire_long_integer() { 1491 let aidl_kp = KmKeyParameter { 1492 tag: Tag::USER_SECURE_ID, 1493 value: KmKeyParameterValue::LongInteger(i64::MAX), 1494 }; 1495 assert_eq!(KeyParameterValue::UserSecureID(i64::MAX), aidl_kp.into()); 1496 } 1497 #[test] test_convert_from_wire_blob()1498 fn test_convert_from_wire_blob() { 1499 let aidl_kp = KmKeyParameter { 1500 tag: Tag::CONFIRMATION_TOKEN, 1501 value: KmKeyParameterValue::Blob(String::from("ConfirmationToken").into_bytes()), 1502 }; 1503 assert_eq!( 1504 KeyParameterValue::ConfirmationToken(String::from("ConfirmationToken").into_bytes()), 1505 aidl_kp.into() 1506 ); 1507 } 1508 } 1509