• 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's authentication timeout, if it has one, is automatically expired when the device is
916     /// removed from the user's body. No longer implemented; this tag is no longer enforced.
917     #[key_param(tag = ALLOW_WHILE_ON_BODY, field = BoolValue)]
918     AllowWhileOnBody,
919     /// The key must be unusable except when the user has provided proof of physical presence
920     #[key_param(tag = TRUSTED_USER_PRESENCE_REQUIRED, field = BoolValue)]
921     TrustedUserPresenceRequired,
922     /// Applicable to keys with KeyPurpose SIGN, and specifies that this key must not be usable
923     /// unless the user provides confirmation of the data to be signed
924     #[key_param(tag = TRUSTED_CONFIRMATION_REQUIRED, field = BoolValue)]
925     TrustedConfirmationRequired,
926     /// The key may only be used when the device is unlocked
927     #[key_param(tag = UNLOCKED_DEVICE_REQUIRED, field = BoolValue)]
928     UnlockedDeviceRequired,
929     /// When provided to generateKey or importKey, this tag specifies data
930     /// that is necessary during all uses of the key
931     #[key_param(tag = APPLICATION_ID, field = Blob)]
932     ApplicationID(Vec<u8>),
933     /// When provided to generateKey or importKey, this tag specifies data
934     /// that is necessary during all uses of the key
935     #[key_param(tag = APPLICATION_DATA, field = Blob)]
936     ApplicationData(Vec<u8>),
937     /// Specifies the date and time the key was created
938     #[key_param(tag = CREATION_DATETIME, field = DateTime)]
939     CreationDateTime(i64),
940     /// Specifies where the key was created, if known
941     #[serde(deserialize_with = "deserialize_primitive")]
942     #[serde(serialize_with = "serialize_primitive")]
943     #[key_param(tag = ORIGIN, field = Origin)]
944     KeyOrigin(KeyOrigin),
945     /// The key used by verified boot to validate the operating system booted
946     #[key_param(tag = ROOT_OF_TRUST, field = Blob)]
947     RootOfTrust(Vec<u8>),
948     /// System OS version with which the key may be used
949     #[key_param(tag = OS_VERSION, field = Integer)]
950     OSVersion(i32),
951     /// Specifies the system security patch level with which the key may be used
952     #[key_param(tag = OS_PATCHLEVEL, field = Integer)]
953     OSPatchLevel(i32),
954     /// Specifies a unique, time-based identifier
955     #[key_param(tag = UNIQUE_ID, field = Blob)]
956     UniqueID(Vec<u8>),
957     /// Used to deliver a "challenge" value to the attestKey() method
958     #[key_param(tag = ATTESTATION_CHALLENGE, field = Blob)]
959     AttestationChallenge(Vec<u8>),
960     /// The set of applications which may use a key, used only with attestKey()
961     #[key_param(tag = ATTESTATION_APPLICATION_ID, field = Blob)]
962     AttestationApplicationID(Vec<u8>),
963     /// Provides the device's brand name, to attestKey()
964     #[key_param(tag = ATTESTATION_ID_BRAND, field = Blob)]
965     AttestationIdBrand(Vec<u8>),
966     /// Provides the device's device name, to attestKey()
967     #[key_param(tag = ATTESTATION_ID_DEVICE, field = Blob)]
968     AttestationIdDevice(Vec<u8>),
969     /// Provides the device's product name, to attestKey()
970     #[key_param(tag = ATTESTATION_ID_PRODUCT, field = Blob)]
971     AttestationIdProduct(Vec<u8>),
972     /// Provides the device's serial number, to attestKey()
973     #[key_param(tag = ATTESTATION_ID_SERIAL, field = Blob)]
974     AttestationIdSerial(Vec<u8>),
975     /// Provides the primary IMEI for the device, to attestKey()
976     #[key_param(tag = ATTESTATION_ID_IMEI, field = Blob)]
977     AttestationIdIMEI(Vec<u8>),
978     /// Provides a second IMEI for the device, to attestKey()
979     #[key_param(tag = ATTESTATION_ID_SECOND_IMEI, field = Blob)]
980     AttestationIdSecondIMEI(Vec<u8>),
981     /// Provides the MEIDs for all radios on the device, to attestKey()
982     #[key_param(tag = ATTESTATION_ID_MEID, field = Blob)]
983     AttestationIdMEID(Vec<u8>),
984     /// Provides the device's manufacturer name, to attestKey()
985     #[key_param(tag = ATTESTATION_ID_MANUFACTURER, field = Blob)]
986     AttestationIdManufacturer(Vec<u8>),
987     /// Provides the device's model name, to attestKey()
988     #[key_param(tag = ATTESTATION_ID_MODEL, field = Blob)]
989     AttestationIdModel(Vec<u8>),
990     /// Specifies the vendor image security patch level with which the key may be used
991     #[key_param(tag = VENDOR_PATCHLEVEL, field = Integer)]
992     VendorPatchLevel(i32),
993     /// Specifies the boot image (kernel) security patch level with which the key may be used
994     #[key_param(tag = BOOT_PATCHLEVEL, field = Integer)]
995     BootPatchLevel(i32),
996     /// Provides "associated data" for AES-GCM encryption or decryption
997     #[key_param(tag = ASSOCIATED_DATA, field = Blob)]
998     AssociatedData(Vec<u8>),
999     /// Provides or returns a nonce or Initialization Vector (IV) for AES-GCM,
1000     /// AES-CBC, AES-CTR, or 3DES-CBC encryption or decryption
1001     #[key_param(tag = NONCE, field = Blob)]
1002     Nonce(Vec<u8>),
1003     /// Provides the requested length of a MAC or GCM authentication tag, in bits
1004     #[key_param(tag = MAC_LENGTH, field = Integer)]
1005     MacLength(i32),
1006     /// Specifies whether the device has been factory reset since the
1007     /// last unique ID rotation.  Used for key attestation
1008     #[key_param(tag = RESET_SINCE_ID_ROTATION, field = BoolValue)]
1009     ResetSinceIdRotation,
1010     /// Used to deliver a cryptographic token proving that the user
1011     /// confirmed a signing request
1012     #[key_param(tag = CONFIRMATION_TOKEN, field = Blob)]
1013     ConfirmationToken(Vec<u8>),
1014     /// Used to deliver the certificate serial number to the KeyMint instance
1015     /// certificate generation.
1016     #[key_param(tag = CERTIFICATE_SERIAL, field = Blob)]
1017     CertificateSerial(Vec<u8>),
1018     /// Used to deliver the certificate subject to the KeyMint instance
1019     /// certificate generation. This must be DER encoded X509 name.
1020     #[key_param(tag = CERTIFICATE_SUBJECT, field = Blob)]
1021     CertificateSubject(Vec<u8>),
1022     /// Used to deliver the not before date in milliseconds to KeyMint during key generation/import.
1023     #[key_param(tag = CERTIFICATE_NOT_BEFORE, field = DateTime)]
1024     CertificateNotBefore(i64),
1025     /// Used to deliver the not after date in milliseconds to KeyMint during key generation/import.
1026     #[key_param(tag = CERTIFICATE_NOT_AFTER, field = DateTime)]
1027     CertificateNotAfter(i64),
1028     /// Specifies a maximum boot level at which a key should function
1029     #[key_param(tag = MAX_BOOT_LEVEL, field = Integer)]
1030     MaxBootLevel(i32),
1031 }
1032 }
1033 
1034 impl From<&KmKeyParameter> for KeyParameterValue {
from(kp: &KmKeyParameter) -> Self1035     fn from(kp: &KmKeyParameter) -> Self {
1036         kp.clone().into()
1037     }
1038 }
1039 
1040 /// KeyParameter wraps the KeyParameterValue and the security level at which it is enforced.
1041 #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
1042 pub struct KeyParameter {
1043     value: KeyParameterValue,
1044     #[serde(deserialize_with = "deserialize_primitive")]
1045     #[serde(serialize_with = "serialize_primitive")]
1046     security_level: SecurityLevel,
1047 }
1048 
1049 impl KeyParameter {
1050     /// Create an instance of KeyParameter, given the value and the security level.
new(value: KeyParameterValue, security_level: SecurityLevel) -> Self1051     pub fn new(value: KeyParameterValue, security_level: SecurityLevel) -> Self {
1052         KeyParameter { value, security_level }
1053     }
1054 
1055     /// Construct a KeyParameter from the data from a rusqlite row.
1056     /// Note that following variants of KeyParameterValue should not be stored:
1057     /// IncludeUniqueID, ApplicationID, ApplicationData, RootOfTrust, UniqueID,
1058     /// Attestation*, AssociatedData, Nonce, MacLength, ResetSinceIdRotation, ConfirmationToken.
1059     /// This filtering is enforced at a higher level and here we support conversion for all the
1060     /// variants.
new_from_sql( tag_val: Tag, data: &SqlField, security_level_val: SecurityLevel, ) -> Result<Self>1061     pub fn new_from_sql(
1062         tag_val: Tag,
1063         data: &SqlField,
1064         security_level_val: SecurityLevel,
1065     ) -> Result<Self> {
1066         Ok(Self {
1067             value: KeyParameterValue::new_from_sql(tag_val, data)?,
1068             security_level: security_level_val,
1069         })
1070     }
1071 
1072     /// Get the KeyMint Tag of this this key parameter.
get_tag(&self) -> Tag1073     pub fn get_tag(&self) -> Tag {
1074         self.value.get_tag()
1075     }
1076 
1077     /// Returns key parameter value.
key_parameter_value(&self) -> &KeyParameterValue1078     pub fn key_parameter_value(&self) -> &KeyParameterValue {
1079         &self.value
1080     }
1081 
1082     /// Returns the security level of this key parameter.
security_level(&self) -> &SecurityLevel1083     pub fn security_level(&self) -> &SecurityLevel {
1084         &self.security_level
1085     }
1086 
1087     /// An authorization is a KeyParameter with an associated security level that is used
1088     /// to convey the key characteristics to keystore clients. This function consumes
1089     /// an internal KeyParameter representation to produce the Authorization wire type.
into_authorization(self) -> Authorization1090     pub fn into_authorization(self) -> Authorization {
1091         Authorization { securityLevel: self.security_level, keyParameter: self.value.into() }
1092     }
1093 }
1094 
1095 #[cfg(test)]
1096 mod generated_key_parameter_tests {
1097     use super::*;
1098     use android_hardware_security_keymint::aidl::android::hardware::security::keymint::TagType::TagType;
1099 
get_field_by_tag_type(tag: Tag) -> KmKeyParameterValue1100     fn get_field_by_tag_type(tag: Tag) -> KmKeyParameterValue {
1101         let tag_type = TagType((tag.0 as u32 & 0xF0000000) as i32);
1102         match tag {
1103             Tag::ALGORITHM => return KmKeyParameterValue::Algorithm(Default::default()),
1104             Tag::BLOCK_MODE => return KmKeyParameterValue::BlockMode(Default::default()),
1105             Tag::PADDING => return KmKeyParameterValue::PaddingMode(Default::default()),
1106             Tag::DIGEST => return KmKeyParameterValue::Digest(Default::default()),
1107             Tag::RSA_OAEP_MGF_DIGEST => return KmKeyParameterValue::Digest(Default::default()),
1108             Tag::EC_CURVE => return KmKeyParameterValue::EcCurve(Default::default()),
1109             Tag::ORIGIN => return KmKeyParameterValue::Origin(Default::default()),
1110             Tag::PURPOSE => return KmKeyParameterValue::KeyPurpose(Default::default()),
1111             Tag::USER_AUTH_TYPE => {
1112                 return KmKeyParameterValue::HardwareAuthenticatorType(Default::default())
1113             }
1114             Tag::HARDWARE_TYPE => return KmKeyParameterValue::SecurityLevel(Default::default()),
1115             _ => {}
1116         }
1117         match tag_type {
1118             TagType::INVALID => return KmKeyParameterValue::Invalid(Default::default()),
1119             TagType::ENUM | TagType::ENUM_REP => {}
1120             TagType::UINT | TagType::UINT_REP => {
1121                 return KmKeyParameterValue::Integer(Default::default())
1122             }
1123             TagType::ULONG | TagType::ULONG_REP => {
1124                 return KmKeyParameterValue::LongInteger(Default::default())
1125             }
1126             TagType::DATE => return KmKeyParameterValue::DateTime(Default::default()),
1127             TagType::BOOL => return KmKeyParameterValue::BoolValue(Default::default()),
1128             TagType::BIGNUM | TagType::BYTES => {
1129                 return KmKeyParameterValue::Blob(Default::default())
1130             }
1131             _ => {}
1132         }
1133         panic!("Unknown tag/tag_type: {:?} {:?}", tag, tag_type);
1134     }
1135 
check_field_matches_tag_type(list_o_parameters: &[KmKeyParameter])1136     fn check_field_matches_tag_type(list_o_parameters: &[KmKeyParameter]) {
1137         for kp in list_o_parameters.iter() {
1138             match (&kp.value, get_field_by_tag_type(kp.tag)) {
1139                 (&KmKeyParameterValue::Algorithm(_), KmKeyParameterValue::Algorithm(_))
1140                 | (&KmKeyParameterValue::BlockMode(_), KmKeyParameterValue::BlockMode(_))
1141                 | (&KmKeyParameterValue::PaddingMode(_), KmKeyParameterValue::PaddingMode(_))
1142                 | (&KmKeyParameterValue::Digest(_), KmKeyParameterValue::Digest(_))
1143                 | (&KmKeyParameterValue::EcCurve(_), KmKeyParameterValue::EcCurve(_))
1144                 | (&KmKeyParameterValue::Origin(_), KmKeyParameterValue::Origin(_))
1145                 | (&KmKeyParameterValue::KeyPurpose(_), KmKeyParameterValue::KeyPurpose(_))
1146                 | (
1147                     &KmKeyParameterValue::HardwareAuthenticatorType(_),
1148                     KmKeyParameterValue::HardwareAuthenticatorType(_),
1149                 )
1150                 | (&KmKeyParameterValue::SecurityLevel(_), KmKeyParameterValue::SecurityLevel(_))
1151                 | (&KmKeyParameterValue::Invalid(_), KmKeyParameterValue::Invalid(_))
1152                 | (&KmKeyParameterValue::Integer(_), KmKeyParameterValue::Integer(_))
1153                 | (&KmKeyParameterValue::LongInteger(_), KmKeyParameterValue::LongInteger(_))
1154                 | (&KmKeyParameterValue::DateTime(_), KmKeyParameterValue::DateTime(_))
1155                 | (&KmKeyParameterValue::BoolValue(_), KmKeyParameterValue::BoolValue(_))
1156                 | (&KmKeyParameterValue::Blob(_), KmKeyParameterValue::Blob(_)) => {}
1157                 (actual, expected) => panic!(
1158                     "Tag {:?} associated with variant {:?} expected {:?}",
1159                     kp.tag, actual, expected
1160                 ),
1161             }
1162         }
1163     }
1164 
1165     #[test]
key_parameter_value_field_matches_tag_type()1166     fn key_parameter_value_field_matches_tag_type() {
1167         check_field_matches_tag_type(&KeyParameterValue::make_field_matches_tag_type_test_vector());
1168     }
1169 
1170     #[test]
key_parameter_serialization_test()1171     fn key_parameter_serialization_test() {
1172         let params = KeyParameterValue::make_key_parameter_defaults_vector();
1173         let mut out_buffer: Vec<u8> = Default::default();
1174         serde_cbor::to_writer(&mut out_buffer, &params)
1175             .expect("Failed to serialize key parameters.");
1176         let deserialized_params: Vec<KeyParameter> =
1177             serde_cbor::from_reader(&mut out_buffer.as_slice())
1178                 .expect("Failed to deserialize key parameters.");
1179         assert_eq!(params, deserialized_params);
1180     }
1181 }
1182 
1183 #[cfg(test)]
1184 mod basic_tests {
1185     use crate::key_parameter::*;
1186 
1187     // Test basic functionality of KeyParameter.
1188     #[test]
test_key_parameter()1189     fn test_key_parameter() {
1190         let key_parameter = KeyParameter::new(
1191             KeyParameterValue::Algorithm(Algorithm::RSA),
1192             SecurityLevel::STRONGBOX,
1193         );
1194 
1195         assert_eq!(key_parameter.get_tag(), Tag::ALGORITHM);
1196 
1197         assert_eq!(
1198             *key_parameter.key_parameter_value(),
1199             KeyParameterValue::Algorithm(Algorithm::RSA)
1200         );
1201 
1202         assert_eq!(*key_parameter.security_level(), SecurityLevel::STRONGBOX);
1203     }
1204 }
1205 
1206 /// The storage_tests module first tests the 'new_from_sql' method for KeyParameters of different
1207 /// data types and then tests 'to_sql' method for KeyParameters of those
1208 /// different data types. The five different data types for KeyParameter values are:
1209 /// i) enums of u32
1210 /// ii) u32
1211 /// iii) u64
1212 /// iv) Vec<u8>
1213 /// v) bool
1214 #[cfg(test)]
1215 mod storage_tests {
1216     use crate::error::*;
1217     use crate::key_parameter::*;
1218     use anyhow::Result;
1219     use rusqlite::types::ToSql;
1220     use rusqlite::{params, Connection};
1221 
1222     /// Test initializing a KeyParameter (with key parameter value corresponding to an enum of i32)
1223     /// from a database table row.
1224     #[test]
test_new_from_sql_enum_i32() -> Result<()>1225     fn test_new_from_sql_enum_i32() -> Result<()> {
1226         let db = init_db()?;
1227         insert_into_keyparameter(
1228             &db,
1229             1,
1230             Tag::ALGORITHM.0,
1231             &Algorithm::RSA.0,
1232             SecurityLevel::STRONGBOX.0,
1233         )?;
1234         let key_param = query_from_keyparameter(&db)?;
1235         assert_eq!(Tag::ALGORITHM, key_param.get_tag());
1236         assert_eq!(*key_param.key_parameter_value(), KeyParameterValue::Algorithm(Algorithm::RSA));
1237         assert_eq!(*key_param.security_level(), SecurityLevel::STRONGBOX);
1238         Ok(())
1239     }
1240 
1241     /// Test initializing a KeyParameter (with key parameter value which is of i32)
1242     /// from a database table row.
1243     #[test]
test_new_from_sql_i32() -> Result<()>1244     fn test_new_from_sql_i32() -> Result<()> {
1245         let db = init_db()?;
1246         insert_into_keyparameter(&db, 1, Tag::KEY_SIZE.0, &1024, SecurityLevel::STRONGBOX.0)?;
1247         let key_param = query_from_keyparameter(&db)?;
1248         assert_eq!(Tag::KEY_SIZE, key_param.get_tag());
1249         assert_eq!(*key_param.key_parameter_value(), KeyParameterValue::KeySize(1024));
1250         Ok(())
1251     }
1252 
1253     /// Test initializing a KeyParameter (with key parameter value which is of i64)
1254     /// from a database table row.
1255     #[test]
test_new_from_sql_i64() -> Result<()>1256     fn test_new_from_sql_i64() -> Result<()> {
1257         let db = init_db()?;
1258         // max value for i64, just to test corner cases
1259         insert_into_keyparameter(
1260             &db,
1261             1,
1262             Tag::RSA_PUBLIC_EXPONENT.0,
1263             &(i64::MAX),
1264             SecurityLevel::STRONGBOX.0,
1265         )?;
1266         let key_param = query_from_keyparameter(&db)?;
1267         assert_eq!(Tag::RSA_PUBLIC_EXPONENT, key_param.get_tag());
1268         assert_eq!(
1269             *key_param.key_parameter_value(),
1270             KeyParameterValue::RSAPublicExponent(i64::MAX)
1271         );
1272         Ok(())
1273     }
1274 
1275     /// Test initializing a KeyParameter (with key parameter value which is of bool)
1276     /// from a database table row.
1277     #[test]
test_new_from_sql_bool() -> Result<()>1278     fn test_new_from_sql_bool() -> Result<()> {
1279         let db = init_db()?;
1280         insert_into_keyparameter(&db, 1, Tag::CALLER_NONCE.0, &Null, SecurityLevel::STRONGBOX.0)?;
1281         let key_param = query_from_keyparameter(&db)?;
1282         assert_eq!(Tag::CALLER_NONCE, key_param.get_tag());
1283         assert_eq!(*key_param.key_parameter_value(), KeyParameterValue::CallerNonce);
1284         Ok(())
1285     }
1286 
1287     /// Test initializing a KeyParameter (with key parameter value which is of Vec<u8>)
1288     /// from a database table row.
1289     #[test]
test_new_from_sql_vec_u8() -> Result<()>1290     fn test_new_from_sql_vec_u8() -> Result<()> {
1291         let db = init_db()?;
1292         let app_id = String::from("MyAppID");
1293         let app_id_bytes = app_id.into_bytes();
1294         insert_into_keyparameter(
1295             &db,
1296             1,
1297             Tag::APPLICATION_ID.0,
1298             &app_id_bytes,
1299             SecurityLevel::STRONGBOX.0,
1300         )?;
1301         let key_param = query_from_keyparameter(&db)?;
1302         assert_eq!(Tag::APPLICATION_ID, key_param.get_tag());
1303         assert_eq!(
1304             *key_param.key_parameter_value(),
1305             KeyParameterValue::ApplicationID(app_id_bytes)
1306         );
1307         Ok(())
1308     }
1309 
1310     /// Test storing a KeyParameter (with key parameter value which corresponds to an enum of i32)
1311     /// in the database
1312     #[test]
test_to_sql_enum_i32() -> Result<()>1313     fn test_to_sql_enum_i32() -> Result<()> {
1314         let db = init_db()?;
1315         let kp = KeyParameter::new(
1316             KeyParameterValue::Algorithm(Algorithm::RSA),
1317             SecurityLevel::STRONGBOX,
1318         );
1319         store_keyparameter(&db, 1, &kp)?;
1320         let key_param = query_from_keyparameter(&db)?;
1321         assert_eq!(kp.get_tag(), key_param.get_tag());
1322         assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
1323         assert_eq!(kp.security_level(), key_param.security_level());
1324         Ok(())
1325     }
1326 
1327     /// Test storing a KeyParameter (with key parameter value which is of i32) in the database
1328     #[test]
test_to_sql_i32() -> Result<()>1329     fn test_to_sql_i32() -> Result<()> {
1330         let db = init_db()?;
1331         let kp = KeyParameter::new(KeyParameterValue::KeySize(1024), SecurityLevel::STRONGBOX);
1332         store_keyparameter(&db, 1, &kp)?;
1333         let key_param = query_from_keyparameter(&db)?;
1334         assert_eq!(kp.get_tag(), key_param.get_tag());
1335         assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
1336         assert_eq!(kp.security_level(), key_param.security_level());
1337         Ok(())
1338     }
1339 
1340     /// Test storing a KeyParameter (with key parameter value which is of i64) in the database
1341     #[test]
test_to_sql_i64() -> Result<()>1342     fn test_to_sql_i64() -> Result<()> {
1343         let db = init_db()?;
1344         // max value for i64, just to test corner cases
1345         let kp = KeyParameter::new(
1346             KeyParameterValue::RSAPublicExponent(i64::MAX),
1347             SecurityLevel::STRONGBOX,
1348         );
1349         store_keyparameter(&db, 1, &kp)?;
1350         let key_param = query_from_keyparameter(&db)?;
1351         assert_eq!(kp.get_tag(), key_param.get_tag());
1352         assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
1353         assert_eq!(kp.security_level(), key_param.security_level());
1354         Ok(())
1355     }
1356 
1357     /// Test storing a KeyParameter (with key parameter value which is of Vec<u8>) in the database
1358     #[test]
test_to_sql_vec_u8() -> Result<()>1359     fn test_to_sql_vec_u8() -> Result<()> {
1360         let db = init_db()?;
1361         let kp = KeyParameter::new(
1362             KeyParameterValue::ApplicationID(String::from("MyAppID").into_bytes()),
1363             SecurityLevel::STRONGBOX,
1364         );
1365         store_keyparameter(&db, 1, &kp)?;
1366         let key_param = query_from_keyparameter(&db)?;
1367         assert_eq!(kp.get_tag(), key_param.get_tag());
1368         assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
1369         assert_eq!(kp.security_level(), key_param.security_level());
1370         Ok(())
1371     }
1372 
1373     /// Test storing a KeyParameter (with key parameter value which is of i32) in the database
1374     #[test]
test_to_sql_bool() -> Result<()>1375     fn test_to_sql_bool() -> Result<()> {
1376         let db = init_db()?;
1377         let kp = KeyParameter::new(KeyParameterValue::CallerNonce, SecurityLevel::STRONGBOX);
1378         store_keyparameter(&db, 1, &kp)?;
1379         let key_param = query_from_keyparameter(&db)?;
1380         assert_eq!(kp.get_tag(), key_param.get_tag());
1381         assert_eq!(kp.key_parameter_value(), key_param.key_parameter_value());
1382         assert_eq!(kp.security_level(), key_param.security_level());
1383         Ok(())
1384     }
1385 
1386     #[test]
1387     /// Test Tag::Invalid
test_invalid_tag() -> Result<()>1388     fn test_invalid_tag() -> Result<()> {
1389         let db = init_db()?;
1390         insert_into_keyparameter(&db, 1, 0, &123, 1)?;
1391         let key_param = query_from_keyparameter(&db)?;
1392         assert_eq!(Tag::INVALID, key_param.get_tag());
1393         Ok(())
1394     }
1395 
1396     #[test]
test_non_existing_enum_variant() -> Result<()>1397     fn test_non_existing_enum_variant() -> Result<()> {
1398         let db = init_db()?;
1399         insert_into_keyparameter(&db, 1, 100, &123, 1)?;
1400         let key_param = query_from_keyparameter(&db)?;
1401         assert_eq!(Tag::INVALID, key_param.get_tag());
1402         Ok(())
1403     }
1404 
1405     #[test]
test_invalid_conversion_from_sql() -> Result<()>1406     fn test_invalid_conversion_from_sql() -> Result<()> {
1407         let db = init_db()?;
1408         insert_into_keyparameter(&db, 1, Tag::ALGORITHM.0, &Null, 1)?;
1409         tests::check_result_contains_error_string(
1410             query_from_keyparameter(&db),
1411             "Failed to read sql data for tag: ALGORITHM.",
1412         );
1413         Ok(())
1414     }
1415 
1416     /// Helper method to init database table for key parameter
init_db() -> Result<Connection>1417     fn init_db() -> Result<Connection> {
1418         let db = Connection::open_in_memory().context("Failed to initialize sqlite connection.")?;
1419         db.execute("ATTACH DATABASE ? as 'persistent';", params![""])
1420             .context("Failed to attach databases.")?;
1421         db.execute(
1422             "CREATE TABLE IF NOT EXISTS persistent.keyparameter (
1423                                 keyentryid INTEGER,
1424                                 tag INTEGER,
1425                                 data ANY,
1426                                 security_level INTEGER);",
1427             [],
1428         )
1429         .context("Failed to initialize \"keyparameter\" table.")?;
1430         Ok(db)
1431     }
1432 
1433     /// 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<()>1434     fn insert_into_keyparameter<T: ToSql>(
1435         db: &Connection,
1436         key_id: i64,
1437         tag: i32,
1438         value: &T,
1439         security_level: i32,
1440     ) -> Result<()> {
1441         db.execute(
1442             "INSERT into persistent.keyparameter (keyentryid, tag, data, security_level)
1443                 VALUES(?, ?, ?, ?);",
1444             params![key_id, tag, *value, security_level],
1445         )?;
1446         Ok(())
1447     }
1448 
1449     /// Helper method to store a key parameter instance.
store_keyparameter(db: &Connection, key_id: i64, kp: &KeyParameter) -> Result<()>1450     fn store_keyparameter(db: &Connection, key_id: i64, kp: &KeyParameter) -> Result<()> {
1451         db.execute(
1452             "INSERT into persistent.keyparameter (keyentryid, tag, data, security_level)
1453                 VALUES(?, ?, ?, ?);",
1454             params![key_id, kp.get_tag().0, kp.key_parameter_value(), kp.security_level().0],
1455         )?;
1456         Ok(())
1457     }
1458 
1459     /// Helper method to query a row from keyparameter table
query_from_keyparameter(db: &Connection) -> Result<KeyParameter>1460     fn query_from_keyparameter(db: &Connection) -> Result<KeyParameter> {
1461         let mut stmt =
1462             db.prepare("SELECT tag, data, security_level FROM persistent.keyparameter")?;
1463         let mut rows = stmt.query([])?;
1464         let row = rows.next()?.unwrap();
1465         KeyParameter::new_from_sql(
1466             Tag(row.get(0)?),
1467             &SqlField::new(1, row),
1468             SecurityLevel(row.get(2)?),
1469         )
1470     }
1471 }
1472 
1473 /// The wire_tests module tests the 'convert_to_wire' and 'convert_from_wire' methods for
1474 /// KeyParameter, for the four different types used in KmKeyParameter, in addition to Invalid
1475 /// key parameter.
1476 /// i) bool
1477 /// ii) integer
1478 /// iii) longInteger
1479 /// iv) blob
1480 #[cfg(test)]
1481 mod wire_tests {
1482     use crate::key_parameter::*;
1483     /// unit tests for to conversions
1484     #[test]
test_convert_to_wire_invalid()1485     fn test_convert_to_wire_invalid() {
1486         let kp = KeyParameter::new(KeyParameterValue::Invalid, SecurityLevel::STRONGBOX);
1487         assert_eq!(
1488             KmKeyParameter { tag: Tag::INVALID, value: KmKeyParameterValue::Invalid(0) },
1489             kp.value.into()
1490         );
1491     }
1492     #[test]
test_convert_to_wire_bool()1493     fn test_convert_to_wire_bool() {
1494         let kp = KeyParameter::new(KeyParameterValue::CallerNonce, SecurityLevel::STRONGBOX);
1495         assert_eq!(
1496             KmKeyParameter { tag: Tag::CALLER_NONCE, value: KmKeyParameterValue::BoolValue(true) },
1497             kp.value.into()
1498         );
1499     }
1500     #[test]
test_convert_to_wire_integer()1501     fn test_convert_to_wire_integer() {
1502         let kp = KeyParameter::new(
1503             KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
1504             SecurityLevel::STRONGBOX,
1505         );
1506         assert_eq!(
1507             KmKeyParameter {
1508                 tag: Tag::PURPOSE,
1509                 value: KmKeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT)
1510             },
1511             kp.value.into()
1512         );
1513     }
1514     #[test]
test_convert_to_wire_long_integer()1515     fn test_convert_to_wire_long_integer() {
1516         let kp =
1517             KeyParameter::new(KeyParameterValue::UserSecureID(i64::MAX), SecurityLevel::STRONGBOX);
1518         assert_eq!(
1519             KmKeyParameter {
1520                 tag: Tag::USER_SECURE_ID,
1521                 value: KmKeyParameterValue::LongInteger(i64::MAX)
1522             },
1523             kp.value.into()
1524         );
1525     }
1526     #[test]
test_convert_to_wire_blob()1527     fn test_convert_to_wire_blob() {
1528         let kp = KeyParameter::new(
1529             KeyParameterValue::ConfirmationToken(String::from("ConfirmationToken").into_bytes()),
1530             SecurityLevel::STRONGBOX,
1531         );
1532         assert_eq!(
1533             KmKeyParameter {
1534                 tag: Tag::CONFIRMATION_TOKEN,
1535                 value: KmKeyParameterValue::Blob(String::from("ConfirmationToken").into_bytes())
1536             },
1537             kp.value.into()
1538         );
1539     }
1540 
1541     /// unit tests for from conversion
1542     #[test]
test_convert_from_wire_invalid()1543     fn test_convert_from_wire_invalid() {
1544         let aidl_kp = KmKeyParameter { tag: Tag::INVALID, ..Default::default() };
1545         assert_eq!(KeyParameterValue::Invalid, aidl_kp.into());
1546     }
1547     #[test]
test_convert_from_wire_bool()1548     fn test_convert_from_wire_bool() {
1549         let aidl_kp =
1550             KmKeyParameter { tag: Tag::CALLER_NONCE, value: KmKeyParameterValue::BoolValue(true) };
1551         assert_eq!(KeyParameterValue::CallerNonce, aidl_kp.into());
1552     }
1553     #[test]
test_convert_from_wire_integer()1554     fn test_convert_from_wire_integer() {
1555         let aidl_kp = KmKeyParameter {
1556             tag: Tag::PURPOSE,
1557             value: KmKeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
1558         };
1559         assert_eq!(KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT), aidl_kp.into());
1560     }
1561     #[test]
test_convert_from_wire_long_integer()1562     fn test_convert_from_wire_long_integer() {
1563         let aidl_kp = KmKeyParameter {
1564             tag: Tag::USER_SECURE_ID,
1565             value: KmKeyParameterValue::LongInteger(i64::MAX),
1566         };
1567         assert_eq!(KeyParameterValue::UserSecureID(i64::MAX), aidl_kp.into());
1568     }
1569     #[test]
test_convert_from_wire_blob()1570     fn test_convert_from_wire_blob() {
1571         let aidl_kp = KmKeyParameter {
1572             tag: Tag::CONFIRMATION_TOKEN,
1573             value: KmKeyParameterValue::Blob(String::from("ConfirmationToken").into_bytes()),
1574         };
1575         assert_eq!(
1576             KeyParameterValue::ConfirmationToken(String::from("ConfirmationToken").into_bytes()),
1577             aidl_kp.into()
1578         );
1579     }
1580 }
1581