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