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