xref: /aosp_15_r20/system/security/keystore2/src/key_parameter.rs (revision e1997b9af69e3155ead6e072d106a0077849ffba)
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 #[cfg(test)]
115 mod generated_key_parameter_tests;
116 
117 #[cfg(test)]
118 mod basic_tests;
119 
120 #[cfg(test)]
121 mod storage_tests;
122 
123 #[cfg(test)]
124 mod wire_tests;
125 
126 /// This trait is used to associate a primitive to any type that can be stored inside a
127 /// KeyParameterValue, especially the AIDL enum types, e.g., keymint::{Algorithm, Digest, ...}.
128 /// This allows for simplifying the macro rules, e.g., for reading from the SQL database.
129 /// An expression like `KeyParameterValue::Algorithm(row.get(0))` would not work because
130 /// a type of `Algorithm` is expected which does not implement `FromSql` and we cannot
131 /// implement it because we own neither the type nor the trait.
132 /// With AssociatePrimitive we can write an expression
133 /// `KeyParameter::Algorithm(<Algorithm>::from_primitive(row.get(0)))` to inform `get`
134 /// about the expected primitive type that it can convert into. By implementing this
135 /// trait for all inner types we can write a single rule to cover all cases (except where
136 /// there is no wrapped type):
137 /// `KeyParameterValue::$vname(<$vtype>::from_primitive(row.get(0)))`
138 trait AssociatePrimitive {
139     type Primitive: Into<Primitive> + TryFrom<Primitive>;
140 
from_primitive(v: Self::Primitive) -> Self141     fn from_primitive(v: Self::Primitive) -> Self;
to_primitive(&self) -> Self::Primitive142     fn to_primitive(&self) -> Self::Primitive;
143 }
144 
145 /// Associates the given type with i32. The macro assumes that the given type is actually a
146 /// tuple struct wrapping i32, such as AIDL enum types.
147 macro_rules! implement_associate_primitive_for_aidl_enum {
148     ($t:ty) => {
149         impl AssociatePrimitive for $t {
150             type Primitive = i32;
151 
152             fn from_primitive(v: Self::Primitive) -> Self {
153                 Self(v)
154             }
155             fn to_primitive(&self) -> Self::Primitive {
156                 self.0
157             }
158         }
159     };
160 }
161 
162 /// Associates the given type with itself.
163 macro_rules! implement_associate_primitive_identity {
164     ($t:ty) => {
165         impl AssociatePrimitive for $t {
166             type Primitive = $t;
167 
168             fn from_primitive(v: Self::Primitive) -> Self {
169                 v
170             }
171             fn to_primitive(&self) -> Self::Primitive {
172                 self.clone()
173             }
174         }
175     };
176 }
177 
178 implement_associate_primitive_for_aidl_enum! {Algorithm}
179 implement_associate_primitive_for_aidl_enum! {BlockMode}
180 implement_associate_primitive_for_aidl_enum! {Digest}
181 implement_associate_primitive_for_aidl_enum! {EcCurve}
182 implement_associate_primitive_for_aidl_enum! {HardwareAuthenticatorType}
183 implement_associate_primitive_for_aidl_enum! {KeyOrigin}
184 implement_associate_primitive_for_aidl_enum! {KeyPurpose}
185 implement_associate_primitive_for_aidl_enum! {PaddingMode}
186 implement_associate_primitive_for_aidl_enum! {SecurityLevel}
187 
188 implement_associate_primitive_identity! {Vec<u8>}
189 implement_associate_primitive_identity! {i64}
190 implement_associate_primitive_identity! {i32}
191 
192 /// This enum allows passing a primitive value to `KeyParameterValue::new_from_tag_primitive_pair`
193 /// Usually, it is not necessary to use this type directly because the function uses
194 /// `Into<Primitive>` as a trait bound.
195 #[derive(Deserialize, Serialize)]
196 pub enum Primitive {
197     /// Wraps an i64.
198     I64(i64),
199     /// Wraps an i32.
200     I32(i32),
201     /// Wraps a Vec<u8>.
202     Vec(Vec<u8>),
203 }
204 
205 impl From<i64> for Primitive {
from(v: i64) -> Self206     fn from(v: i64) -> Self {
207         Self::I64(v)
208     }
209 }
210 impl From<i32> for Primitive {
from(v: i32) -> Self211     fn from(v: i32) -> Self {
212         Self::I32(v)
213     }
214 }
215 impl From<Vec<u8>> for Primitive {
from(v: Vec<u8>) -> Self216     fn from(v: Vec<u8>) -> Self {
217         Self::Vec(v)
218     }
219 }
220 
221 /// This error is returned by `KeyParameterValue::new_from_tag_primitive_pair`.
222 #[derive(thiserror::Error, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
223 pub enum PrimitiveError {
224     /// Returned if this primitive is unsuitable for the given tag type.
225     #[error("Primitive does not match the expected tag type.")]
226     TypeMismatch,
227     /// Return if the tag type is unknown.
228     #[error("Unknown tag.")]
229     UnknownTag,
230 }
231 
232 impl TryFrom<Primitive> for i64 {
233     type Error = PrimitiveError;
234 
try_from(p: Primitive) -> Result<i64, Self::Error>235     fn try_from(p: Primitive) -> Result<i64, Self::Error> {
236         match p {
237             Primitive::I64(v) => Ok(v),
238             _ => Err(Self::Error::TypeMismatch),
239         }
240     }
241 }
242 impl TryFrom<Primitive> for i32 {
243     type Error = PrimitiveError;
244 
try_from(p: Primitive) -> Result<i32, Self::Error>245     fn try_from(p: Primitive) -> Result<i32, Self::Error> {
246         match p {
247             Primitive::I32(v) => Ok(v),
248             _ => Err(Self::Error::TypeMismatch),
249         }
250     }
251 }
252 impl TryFrom<Primitive> for Vec<u8> {
253     type Error = PrimitiveError;
254 
try_from(p: Primitive) -> Result<Vec<u8>, Self::Error>255     fn try_from(p: Primitive) -> Result<Vec<u8>, Self::Error> {
256         match p {
257             Primitive::Vec(v) => Ok(v),
258             _ => Err(Self::Error::TypeMismatch),
259         }
260     }
261 }
262 
serialize_primitive<S, P>(v: &P, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, P: AssociatePrimitive,263 fn serialize_primitive<S, P>(v: &P, serializer: S) -> Result<S::Ok, S::Error>
264 where
265     S: Serializer,
266     P: AssociatePrimitive,
267 {
268     let primitive: Primitive = v.to_primitive().into();
269     primitive.serialize(serializer)
270 }
271 
deserialize_primitive<'de, D, T>(deserializer: D) -> Result<T, D::Error> where D: Deserializer<'de>, T: AssociatePrimitive,272 fn deserialize_primitive<'de, D, T>(deserializer: D) -> Result<T, D::Error>
273 where
274     D: Deserializer<'de>,
275     T: AssociatePrimitive,
276 {
277     let primitive: Primitive = serde::de::Deserialize::deserialize(deserializer)?;
278     Ok(T::from_primitive(
279         primitive.try_into().map_err(|_| serde::de::Error::custom("Type Mismatch"))?,
280     ))
281 }
282 
283 /// Expands the list of KeyParameterValue variants as follows:
284 ///
285 /// Input:
286 /// Invalid with tag INVALID and field Invalid,
287 /// Algorithm(Algorithm) with tag ALGORITHM and field Algorithm,
288 ///
289 /// Output:
290 /// ```
291 /// pub fn new_from_tag_primitive_pair<T: Into<Primitive>>(
292 ///     tag: Tag,
293 ///     v: T
294 /// ) -> Result<KeyParameterValue, PrimitiveError> {
295 ///     let p: Primitive = v.into();
296 ///     Ok(match tag {
297 ///         Tag::INVALID => KeyParameterValue::Invalid,
298 ///         Tag::ALGORITHM => KeyParameterValue::Algorithm(
299 ///             <Algorithm>::from_primitive(p.try_into()?)
300 ///         ),
301 ///         _ => return Err(PrimitiveError::UnknownTag),
302 ///     })
303 /// }
304 /// ```
305 macro_rules! implement_from_tag_primitive_pair {
306     ($enum_name:ident; $($vname:ident$(($vtype:ty))? $tag_name:ident),*) => {
307         /// Returns the an instance of $enum_name or an error if the given primitive does not match
308         /// the tag type or the tag is unknown.
309         pub fn new_from_tag_primitive_pair<T: Into<Primitive>>(
310             tag: Tag,
311             v: T
312         ) -> Result<$enum_name, PrimitiveError> {
313             let p: Primitive = v.into();
314             Ok(match tag {
315                 $(Tag::$tag_name => $enum_name::$vname$((
316                     <$vtype>::from_primitive(p.try_into()?)
317                 ))?,)*
318                 _ => return Err(PrimitiveError::UnknownTag),
319             })
320         }
321     };
322 }
323 
324 /// Expands the list of KeyParameterValue variants as follows:
325 ///
326 /// Input:
327 /// pub enum KeyParameterValue {
328 ///     Invalid with tag INVALID and field Invalid,
329 ///     Algorithm(Algorithm) with tag ALGORITHM and field Algorithm,
330 /// }
331 ///
332 /// Output:
333 /// ```
334 /// pub enum KeyParameterValue {
335 ///     Invalid,
336 ///     Algorithm(Algorithm),
337 /// }
338 /// ```
339 macro_rules! implement_enum {
340     (
341         $(#[$enum_meta:meta])*
342         $enum_vis:vis enum $enum_name:ident {
343              $($(#[$emeta:meta])* $vname:ident$(($vtype:ty))?),* $(,)?
344         }
345     ) => {
346         $(#[$enum_meta])*
347         $enum_vis enum $enum_name {
348             $(
349                 $(#[$emeta])*
350                 $vname$(($vtype))?
351             ),*
352         }
353     };
354 }
355 
356 /// Expands the list of KeyParameterValue variants as follows:
357 ///
358 /// Input:
359 /// Invalid with tag INVALID and field Invalid,
360 /// Algorithm(Algorithm) with tag ALGORITHM and field Algorithm,
361 ///
362 /// Output:
363 /// ```
364 /// pub fn get_tag(&self) -> Tag {
365 ///     match self {
366 ///         KeyParameterValue::Invalid => Tag::INVALID,
367 ///         KeyParameterValue::Algorithm(_) => Tag::ALGORITHM,
368 ///     }
369 /// }
370 /// ```
371 macro_rules! implement_get_tag {
372     (
373         @replace_type_spec
374         $enum_name:ident,
375         [$($out:tt)*],
376         [$vname:ident($vtype:ty) $tag_name:ident, $($in:tt)*]
377     ) => {
378         implement_get_tag!{@replace_type_spec $enum_name, [$($out)*
379             $enum_name::$vname(_) => Tag::$tag_name,
380         ], [$($in)*]}
381     };
382     (
383         @replace_type_spec
384         $enum_name:ident,
385         [$($out:tt)*],
386         [$vname:ident $tag_name:ident, $($in:tt)*]
387     ) => {
388         implement_get_tag!{@replace_type_spec $enum_name, [$($out)*
389             $enum_name::$vname => Tag::$tag_name,
390         ], [$($in)*]}
391     };
392     (@replace_type_spec $enum_name:ident, [$($out:tt)*], []) => {
393         /// Returns the tag of the given instance.
394         pub fn get_tag(&self) -> Tag {
395             match self {
396                 $($out)*
397             }
398         }
399     };
400 
401     ($enum_name:ident; $($vname:ident$(($vtype:ty))? $tag_name:ident),*) => {
402         implement_get_tag!{@replace_type_spec $enum_name, [], [$($vname$(($vtype))? $tag_name,)*]}
403     };
404 }
405 
406 /// Expands the list of KeyParameterValue variants as follows:
407 ///
408 /// Input:
409 /// Invalid with tag INVALID and field Invalid,
410 /// Algorithm(Algorithm) with tag ALGORITHM and field Algorithm,
411 ///
412 /// Output:
413 /// ```
414 /// fn to_sql(&self) -> SqlResult<ToSqlOutput> {
415 ///     match self {
416 ///         KeyParameterValue::Invalid => Ok(ToSqlOutput::from(Null)),
417 ///         KeyParameterValue::Algorithm(v) => Ok(ToSqlOutput::from(v.to_primitive())),
418 ///     }
419 /// }
420 /// ```
421 macro_rules! implement_to_sql {
422     (
423         @replace_type_spec
424         $enum_name:ident,
425         [$($out:tt)*],
426         [$vname:ident($vtype:ty), $($in:tt)*]
427     ) => {
428         implement_to_sql!{@replace_type_spec $enum_name, [ $($out)*
429             $enum_name::$vname(v) => Ok(ToSqlOutput::from(v.to_primitive())),
430         ], [$($in)*]}
431     };
432     (
433         @replace_type_spec
434         $enum_name:ident,
435         [$($out:tt)*],
436         [$vname:ident, $($in:tt)*]
437     ) => {
438         implement_to_sql!{@replace_type_spec $enum_name, [ $($out)*
439             $enum_name::$vname => Ok(ToSqlOutput::from(Null)),
440         ], [$($in)*]}
441     };
442     (@replace_type_spec $enum_name:ident, [$($out:tt)*], []) => {
443         /// Converts $enum_name to be stored in a rusqlite database.
444         fn to_sql(&self) -> SqlResult<ToSqlOutput> {
445             match self {
446                 $($out)*
447             }
448         }
449     };
450 
451 
452     ($enum_name:ident; $($vname:ident$(($vtype:ty))?),*) => {
453         impl ToSql for $enum_name {
454             implement_to_sql!{@replace_type_spec $enum_name, [], [$($vname$(($vtype))?,)*]}
455         }
456 
457     }
458 }
459 
460 /// Expands the list of KeyParameterValue variants as follows:
461 ///
462 /// Input:
463 /// Invalid with tag INVALID and field Invalid,
464 /// Algorithm(Algorithm) with tag ALGORITHM and field Algorithm,
465 ///
466 /// Output:
467 /// ```
468 /// pub fn new_from_sql(
469 ///     tag: Tag,
470 ///     data: &SqlField,
471 /// ) -> Result<Self> {
472 ///     Ok(match self {
473 ///         Tag::Invalid => KeyParameterValue::Invalid,
474 ///         Tag::ALGORITHM => {
475 ///             KeyParameterValue::Algorithm(<Algorithm>::from_primitive(data
476 ///                 .get()
477 ///                 .map_err(|_| KeystoreError::Rc(ResponseCode::VALUE_CORRUPTED))
478 ///                 .context(concat!("Failed to read sql data for tag: ", "ALGORITHM", "."))?
479 ///             ))
480 ///         },
481 ///     })
482 /// }
483 /// ```
484 macro_rules! implement_new_from_sql {
485     ($enum_name:ident; $($vname:ident$(($vtype:ty))? $tag_name:ident),*) => {
486         /// Takes a tag and an SqlField and attempts to construct a KeyParameter value.
487         /// This function may fail if the parameter value cannot be extracted from the
488         /// database cell.
489         pub fn new_from_sql(
490             tag: Tag,
491             data: &SqlField,
492         ) -> Result<Self> {
493             Ok(match tag {
494                 $(
495                     Tag::$tag_name => {
496                         $enum_name::$vname$((<$vtype>::from_primitive(data
497                             .get()
498                             .map_err(|_| KeystoreError::Rc(ResponseCode::VALUE_CORRUPTED))
499                             .context(concat!(
500                                 "Failed to read sql data for tag: ",
501                                 stringify!($tag_name),
502                                 "."
503                             ))?
504                         )))?
505                     },
506                 )*
507                 _ => $enum_name::Invalid,
508             })
509         }
510     };
511 }
512 
513 /// This key parameter default is used during the conversion from KeyParameterValue
514 /// to keymint::KeyParameterValue. Keystore's version does not have wrapped types
515 /// for boolean tags and the tag Invalid. The AIDL version uses bool and integer
516 /// variants respectively. This default function is invoked in these cases to
517 /// homogenize the rules for boolean and invalid tags.
518 /// The bool variant returns true because boolean parameters are implicitly true
519 /// if present.
520 trait KpDefault {
default() -> Self521     fn default() -> Self;
522 }
523 
524 impl KpDefault for i32 {
default() -> Self525     fn default() -> Self {
526         0
527     }
528 }
529 
530 impl KpDefault for bool {
default() -> Self531     fn default() -> Self {
532         true
533     }
534 }
535 
536 /// Expands the list of KeyParameterValue variants as follows:
537 ///
538 /// Input:
539 /// Invalid with tag INVALID and field Invalid,
540 /// Algorithm(Algorithm) with tag ALGORITHM and field Algorithm,
541 ///
542 /// Output:
543 /// ```
544 /// impl From<KmKeyParameter> for KeyParameterValue {
545 ///     fn from(kp: KmKeyParameter) -> Self {
546 ///         match kp {
547 ///             KmKeyParameter { tag: Tag::INVALID, value: KmKeyParameterValue::Invalid(_) }
548 ///                 => $enum_name::$vname,
549 ///             KmKeyParameter { tag: Tag::Algorithm, value: KmKeyParameterValue::Algorithm(v) }
550 ///                 => $enum_name::Algorithm(v),
551 ///             _ => $enum_name::Invalid,
552 ///         }
553 ///     }
554 /// }
555 ///
556 /// impl Into<KmKeyParameter> for KeyParameterValue {
557 ///     fn into(self) -> KmKeyParameter {
558 ///         match self {
559 ///             KeyParameterValue::Invalid => KmKeyParameter {
560 ///                 tag: Tag::INVALID,
561 ///                 value: KmKeyParameterValue::Invalid(KpDefault::default())
562 ///             },
563 ///             KeyParameterValue::Algorithm(v) => KmKeyParameter {
564 ///                 tag: Tag::ALGORITHM,
565 ///                 value: KmKeyParameterValue::Algorithm(v)
566 ///             },
567 ///         }
568 ///     }
569 /// }
570 /// ```
571 macro_rules! implement_try_from_to_km_parameter {
572     // The first three rules expand From<KmKeyParameter>.
573     (
574         @from
575         $enum_name:ident,
576         [$($out:tt)*],
577         [$vname:ident($vtype:ty) $tag_name:ident $field_name:ident, $($in:tt)*]
578     ) => {
579         implement_try_from_to_km_parameter!{@from $enum_name, [$($out)*
580             KmKeyParameter {
581                 tag: Tag::$tag_name,
582                 value: KmKeyParameterValue::$field_name(v)
583             } => $enum_name::$vname(v),
584         ], [$($in)*]
585     }};
586     (
587         @from
588         $enum_name:ident,
589         [$($out:tt)*],
590         [$vname:ident $tag_name:ident $field_name:ident, $($in:tt)*]
591     ) => {
592         implement_try_from_to_km_parameter!{@from $enum_name, [$($out)*
593             KmKeyParameter {
594                 tag: Tag::$tag_name,
595                 value: KmKeyParameterValue::$field_name(_)
596             } => $enum_name::$vname,
597         ], [$($in)*]
598     }};
599     (@from $enum_name:ident, [$($out:tt)*], []) => {
600         impl From<KmKeyParameter> for $enum_name {
601             fn from(kp: KmKeyParameter) -> Self {
602                 match kp {
603                     $($out)*
604                     _ => $enum_name::Invalid,
605                 }
606             }
607         }
608     };
609 
610     // The next three rules expand Into<KmKeyParameter>.
611     (
612         @into
613         $enum_name:ident,
614         [$($out:tt)*],
615         [$vname:ident($vtype:ty) $tag_name:ident $field_name:ident, $($in:tt)*]
616     ) => {
617         implement_try_from_to_km_parameter!{@into $enum_name, [$($out)*
618             $enum_name::$vname(v) => KmKeyParameter {
619                 tag: Tag::$tag_name,
620                 value: KmKeyParameterValue::$field_name(v)
621             },
622         ], [$($in)*]
623     }};
624     (
625         @into
626         $enum_name:ident,
627         [$($out:tt)*],
628         [$vname:ident $tag_name:ident $field_name:ident, $($in:tt)*]
629     ) => {
630         implement_try_from_to_km_parameter!{@into $enum_name, [$($out)*
631             $enum_name::$vname => KmKeyParameter {
632                 tag: Tag::$tag_name,
633                 value: KmKeyParameterValue::$field_name(KpDefault::default())
634             },
635         ], [$($in)*]
636     }};
637     (@into $enum_name:ident, [$($out:tt)*], []) => {
638         impl From<$enum_name> for KmKeyParameter {
639             fn from(x: $enum_name) -> Self {
640                 match x {
641                     $($out)*
642                 }
643             }
644         }
645     };
646 
647 
648     ($enum_name:ident; $($vname:ident$(($vtype:ty))? $tag_name:ident $field_name:ident),*) => {
649         implement_try_from_to_km_parameter!(
650             @from $enum_name,
651             [],
652             [$($vname$(($vtype))? $tag_name $field_name,)*]
653         );
654         implement_try_from_to_km_parameter!(
655             @into $enum_name,
656             [],
657             [$($vname$(($vtype))? $tag_name $field_name,)*]
658         );
659     };
660 }
661 
662 /// This is the top level macro. While the other macros do most of the heavy lifting, this takes
663 /// the key parameter list and passes it on to the other macros to generate all of the conversion
664 /// functions. In addition, it generates an important test vector for verifying that tag type of the
665 /// keymint tag matches the associated keymint KeyParameterValue field.
666 macro_rules! implement_key_parameter_value {
667     (
668         $(#[$enum_meta:meta])*
669         $enum_vis:vis enum $enum_name:ident {
670             $(
671                 $(#[$($emeta:tt)+])*
672                 $vname:ident$(($vtype:ty))?
673             ),* $(,)?
674         }
675     ) => {
676         implement_key_parameter_value!{
677             @extract_attr
678             $(#[$enum_meta])*
679             $enum_vis enum $enum_name {
680                 []
681                 [$(
682                     [] [$(#[$($emeta)+])*]
683                     $vname$(($vtype))?,
684                 )*]
685             }
686         }
687     };
688 
689     (
690         @extract_attr
691         $(#[$enum_meta:meta])*
692         $enum_vis:vis enum $enum_name:ident {
693             [$($out:tt)*]
694             [
695                 [$(#[$mout:meta])*]
696                 [
697                     #[key_param(tag = $tag_name:ident, field = $field_name:ident)]
698                     $(#[$($mtail:tt)+])*
699                 ]
700                 $vname:ident$(($vtype:ty))?,
701                 $($tail:tt)*
702             ]
703         }
704     ) => {
705         implement_key_parameter_value!{
706             @extract_attr
707             $(#[$enum_meta])*
708             $enum_vis enum $enum_name {
709                 [
710                     $($out)*
711                     $(#[$mout])*
712                     $(#[$($mtail)+])*
713                     $tag_name $field_name $vname$(($vtype))?,
714                 ]
715                 [$($tail)*]
716             }
717         }
718     };
719 
720     (
721         @extract_attr
722         $(#[$enum_meta:meta])*
723         $enum_vis:vis enum $enum_name:ident {
724             [$($out:tt)*]
725             [
726                 [$(#[$mout:meta])*]
727                 [
728                     #[$front:meta]
729                     $(#[$($mtail:tt)+])*
730                 ]
731                 $vname:ident$(($vtype:ty))?,
732                 $($tail:tt)*
733             ]
734         }
735     ) => {
736         implement_key_parameter_value!{
737             @extract_attr
738             $(#[$enum_meta])*
739             $enum_vis enum $enum_name {
740                 [$($out)*]
741                 [
742                     [
743                         $(#[$mout])*
744                         #[$front]
745                     ]
746                     [$(#[$($mtail)+])*]
747                     $vname$(($vtype))?,
748                     $($tail)*
749                 ]
750             }
751         }
752     };
753 
754     (
755         @extract_attr
756         $(#[$enum_meta:meta])*
757         $enum_vis:vis enum $enum_name:ident {
758             [$($out:tt)*]
759             []
760         }
761     ) => {
762         implement_key_parameter_value!{
763             @spill
764             $(#[$enum_meta])*
765             $enum_vis enum $enum_name {
766                 $($out)*
767             }
768         }
769     };
770 
771     (
772         @spill
773         $(#[$enum_meta:meta])*
774         $enum_vis:vis enum $enum_name:ident {
775             $(
776                 $(#[$emeta:meta])*
777                 $tag_name:ident $field_name:ident $vname:ident$(($vtype:ty))?,
778             )*
779         }
780     ) => {
781         implement_enum!(
782             $(#[$enum_meta])*
783             $enum_vis enum $enum_name {
784             $(
785                 $(#[$emeta])*
786                 $vname$(($vtype))?
787             ),*
788         });
789 
790         impl $enum_name {
791             implement_new_from_sql!($enum_name; $($vname$(($vtype))? $tag_name),*);
792             implement_get_tag!($enum_name; $($vname$(($vtype))? $tag_name),*);
793             implement_from_tag_primitive_pair!($enum_name; $($vname$(($vtype))? $tag_name),*);
794 
795             #[cfg(test)]
796             fn make_field_matches_tag_type_test_vector() -> Vec<KmKeyParameter> {
797                 vec![$(KmKeyParameter{
798                     tag: Tag::$tag_name,
799                     value: KmKeyParameterValue::$field_name(Default::default())}
800                 ),*]
801             }
802 
803             #[cfg(test)]
804             fn make_key_parameter_defaults_vector() -> Vec<KeyParameter> {
805                 vec![$(KeyParameter{
806                     value: KeyParameterValue::$vname$((<$vtype as Default>::default()))?,
807                     security_level: SecurityLevel(100),
808                 }),*]
809             }
810         }
811 
812         implement_try_from_to_km_parameter!(
813             $enum_name;
814             $($vname$(($vtype))? $tag_name $field_name),*
815         );
816 
817         implement_to_sql!($enum_name; $($vname$(($vtype))?),*);
818     };
819 }
820 
821 implement_key_parameter_value! {
822 /// KeyParameterValue holds a value corresponding to one of the Tags defined in
823 /// the AIDL spec at hardware/interfaces/security/keymint
824 #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Deserialize, Serialize)]
825 pub enum KeyParameterValue {
826     /// Associated with Tag:INVALID
827     #[key_param(tag = INVALID, field = Invalid)]
828     Invalid,
829     /// Set of purposes for which the key may be used
830     #[serde(deserialize_with = "deserialize_primitive")]
831     #[serde(serialize_with = "serialize_primitive")]
832     #[key_param(tag = PURPOSE, field = KeyPurpose)]
833     KeyPurpose(KeyPurpose),
834     /// Cryptographic algorithm with which the key is used
835     #[serde(deserialize_with = "deserialize_primitive")]
836     #[serde(serialize_with = "serialize_primitive")]
837     #[key_param(tag = ALGORITHM, field = Algorithm)]
838     Algorithm(Algorithm),
839     /// Size of the key , in bits
840     #[key_param(tag = KEY_SIZE, field = Integer)]
841     KeySize(i32),
842     /// Block cipher mode(s) with which the key may be used
843     #[serde(deserialize_with = "deserialize_primitive")]
844     #[serde(serialize_with = "serialize_primitive")]
845     #[key_param(tag = BLOCK_MODE, field = BlockMode)]
846     BlockMode(BlockMode),
847     /// Digest algorithms that may be used with the key to perform signing and verification
848     #[serde(deserialize_with = "deserialize_primitive")]
849     #[serde(serialize_with = "serialize_primitive")]
850     #[key_param(tag = DIGEST, field = Digest)]
851     Digest(Digest),
852     /// Digest algorithms that can be used for MGF in RSA-OAEP.
853     #[serde(deserialize_with = "deserialize_primitive")]
854     #[serde(serialize_with = "serialize_primitive")]
855     #[key_param(tag = RSA_OAEP_MGF_DIGEST, field = Digest)]
856     RsaOaepMgfDigest(Digest),
857     /// Padding modes that may be used with the key.  Relevant to RSA, AES and 3DES keys.
858     #[serde(deserialize_with = "deserialize_primitive")]
859     #[serde(serialize_with = "serialize_primitive")]
860     #[key_param(tag = PADDING, field = PaddingMode)]
861     PaddingMode(PaddingMode),
862     /// Can the caller provide a nonce for nonce-requiring operations
863     #[key_param(tag = CALLER_NONCE, field = BoolValue)]
864     CallerNonce,
865     /// Minimum length of MAC for HMAC keys and AES keys that support GCM mode
866     #[key_param(tag = MIN_MAC_LENGTH, field = Integer)]
867     MinMacLength(i32),
868     /// The elliptic curve
869     #[serde(deserialize_with = "deserialize_primitive")]
870     #[serde(serialize_with = "serialize_primitive")]
871     #[key_param(tag = EC_CURVE, field = EcCurve)]
872     EcCurve(EcCurve),
873     /// Value of the public exponent for an RSA key pair
874     #[key_param(tag = RSA_PUBLIC_EXPONENT, field = LongInteger)]
875     RSAPublicExponent(i64),
876     /// An attestation certificate for the generated key should contain an application-scoped
877     /// and time-bounded device-unique ID
878     #[key_param(tag = INCLUDE_UNIQUE_ID, field = BoolValue)]
879     IncludeUniqueID,
880     //TODO: find out about this
881     // /// Necessary system environment conditions for the generated key to be used
882     // KeyBlobUsageRequirements(KeyBlobUsageRequirements),
883     /// Only the boot loader can use the key
884     #[key_param(tag = BOOTLOADER_ONLY, field = BoolValue)]
885     BootLoaderOnly,
886     /// When deleted, the key is guaranteed to be permanently deleted and unusable
887     #[key_param(tag = ROLLBACK_RESISTANCE, field = BoolValue)]
888     RollbackResistance,
889     /// The Key shall only be used during the early boot stage
890     #[key_param(tag = EARLY_BOOT_ONLY, field = BoolValue)]
891     EarlyBootOnly,
892     /// The date and time at which the key becomes active
893     #[key_param(tag = ACTIVE_DATETIME, field = DateTime)]
894     ActiveDateTime(i64),
895     /// The date and time at which the key expires for signing and encryption
896     #[key_param(tag = ORIGINATION_EXPIRE_DATETIME, field = DateTime)]
897     OriginationExpireDateTime(i64),
898     /// The date and time at which the key expires for verification and decryption
899     #[key_param(tag = USAGE_EXPIRE_DATETIME, field = DateTime)]
900     UsageExpireDateTime(i64),
901     /// Minimum amount of time that elapses between allowed operations
902     #[key_param(tag = MIN_SECONDS_BETWEEN_OPS, field = Integer)]
903     MinSecondsBetweenOps(i32),
904     /// Maximum number of times that a key may be used between system reboots
905     #[key_param(tag = MAX_USES_PER_BOOT, field = Integer)]
906     MaxUsesPerBoot(i32),
907     /// The number of times that a limited use key can be used
908     #[key_param(tag = USAGE_COUNT_LIMIT, field = Integer)]
909     UsageCountLimit(i32),
910     /// ID of the Android user that is permitted to use the key
911     #[key_param(tag = USER_ID, field = Integer)]
912     UserID(i32),
913     /// A key may only be used under a particular secure user authentication state
914     #[key_param(tag = USER_SECURE_ID, field = LongInteger)]
915     UserSecureID(i64),
916     /// No authentication is required to use this key
917     #[key_param(tag = NO_AUTH_REQUIRED, field = BoolValue)]
918     NoAuthRequired,
919     /// The types of user authenticators that may be used to authorize this key
920     #[serde(deserialize_with = "deserialize_primitive")]
921     #[serde(serialize_with = "serialize_primitive")]
922     #[key_param(tag = USER_AUTH_TYPE, field = HardwareAuthenticatorType)]
923     HardwareAuthenticatorType(HardwareAuthenticatorType),
924     /// The time in seconds for which the key is authorized for use, after user authentication
925     #[key_param(tag = AUTH_TIMEOUT, field = Integer)]
926     AuthTimeout(i32),
927     /// The key's authentication timeout, if it has one, is automatically expired when the device is
928     /// removed from the user's body. No longer implemented; this tag is no longer enforced.
929     #[key_param(tag = ALLOW_WHILE_ON_BODY, field = BoolValue)]
930     AllowWhileOnBody,
931     /// The key must be unusable except when the user has provided proof of physical presence
932     #[key_param(tag = TRUSTED_USER_PRESENCE_REQUIRED, field = BoolValue)]
933     TrustedUserPresenceRequired,
934     /// Applicable to keys with KeyPurpose SIGN, and specifies that this key must not be usable
935     /// unless the user provides confirmation of the data to be signed
936     #[key_param(tag = TRUSTED_CONFIRMATION_REQUIRED, field = BoolValue)]
937     TrustedConfirmationRequired,
938     /// The key may only be used when the device is unlocked
939     #[key_param(tag = UNLOCKED_DEVICE_REQUIRED, field = BoolValue)]
940     UnlockedDeviceRequired,
941     /// When provided to generateKey or importKey, this tag specifies data
942     /// that is necessary during all uses of the key
943     #[key_param(tag = APPLICATION_ID, field = Blob)]
944     ApplicationID(Vec<u8>),
945     /// When provided to generateKey or importKey, this tag specifies data
946     /// that is necessary during all uses of the key
947     #[key_param(tag = APPLICATION_DATA, field = Blob)]
948     ApplicationData(Vec<u8>),
949     /// Specifies the date and time the key was created
950     #[key_param(tag = CREATION_DATETIME, field = DateTime)]
951     CreationDateTime(i64),
952     /// Specifies where the key was created, if known
953     #[serde(deserialize_with = "deserialize_primitive")]
954     #[serde(serialize_with = "serialize_primitive")]
955     #[key_param(tag = ORIGIN, field = Origin)]
956     KeyOrigin(KeyOrigin),
957     /// The key used by verified boot to validate the operating system booted
958     #[key_param(tag = ROOT_OF_TRUST, field = Blob)]
959     RootOfTrust(Vec<u8>),
960     /// System OS version with which the key may be used
961     #[key_param(tag = OS_VERSION, field = Integer)]
962     OSVersion(i32),
963     /// Specifies the system security patch level with which the key may be used
964     #[key_param(tag = OS_PATCHLEVEL, field = Integer)]
965     OSPatchLevel(i32),
966     /// Specifies a unique, time-based identifier
967     #[key_param(tag = UNIQUE_ID, field = Blob)]
968     UniqueID(Vec<u8>),
969     /// Used to deliver a "challenge" value to the attestKey() method
970     #[key_param(tag = ATTESTATION_CHALLENGE, field = Blob)]
971     AttestationChallenge(Vec<u8>),
972     /// The set of applications which may use a key, used only with attestKey()
973     #[key_param(tag = ATTESTATION_APPLICATION_ID, field = Blob)]
974     AttestationApplicationID(Vec<u8>),
975     /// Provides the device's brand name, to attestKey()
976     #[key_param(tag = ATTESTATION_ID_BRAND, field = Blob)]
977     AttestationIdBrand(Vec<u8>),
978     /// Provides the device's device name, to attestKey()
979     #[key_param(tag = ATTESTATION_ID_DEVICE, field = Blob)]
980     AttestationIdDevice(Vec<u8>),
981     /// Provides the device's product name, to attestKey()
982     #[key_param(tag = ATTESTATION_ID_PRODUCT, field = Blob)]
983     AttestationIdProduct(Vec<u8>),
984     /// Provides the device's serial number, to attestKey()
985     #[key_param(tag = ATTESTATION_ID_SERIAL, field = Blob)]
986     AttestationIdSerial(Vec<u8>),
987     /// Provides the primary IMEI for the device, to attestKey()
988     #[key_param(tag = ATTESTATION_ID_IMEI, field = Blob)]
989     AttestationIdIMEI(Vec<u8>),
990     /// Provides a second IMEI for the device, to attestKey()
991     #[key_param(tag = ATTESTATION_ID_SECOND_IMEI, field = Blob)]
992     AttestationIdSecondIMEI(Vec<u8>),
993     /// Provides the MEIDs for all radios on the device, to attestKey()
994     #[key_param(tag = ATTESTATION_ID_MEID, field = Blob)]
995     AttestationIdMEID(Vec<u8>),
996     /// Provides the device's manufacturer name, to attestKey()
997     #[key_param(tag = ATTESTATION_ID_MANUFACTURER, field = Blob)]
998     AttestationIdManufacturer(Vec<u8>),
999     /// Provides the device's model name, to attestKey()
1000     #[key_param(tag = ATTESTATION_ID_MODEL, field = Blob)]
1001     AttestationIdModel(Vec<u8>),
1002     /// Specifies the vendor image security patch level with which the key may be used
1003     #[key_param(tag = VENDOR_PATCHLEVEL, field = Integer)]
1004     VendorPatchLevel(i32),
1005     /// Specifies the boot image (kernel) security patch level with which the key may be used
1006     #[key_param(tag = BOOT_PATCHLEVEL, field = Integer)]
1007     BootPatchLevel(i32),
1008     /// Provides "associated data" for AES-GCM encryption or decryption
1009     #[key_param(tag = ASSOCIATED_DATA, field = Blob)]
1010     AssociatedData(Vec<u8>),
1011     /// Provides or returns a nonce or Initialization Vector (IV) for AES-GCM,
1012     /// AES-CBC, AES-CTR, or 3DES-CBC encryption or decryption
1013     #[key_param(tag = NONCE, field = Blob)]
1014     Nonce(Vec<u8>),
1015     /// Provides the requested length of a MAC or GCM authentication tag, in bits
1016     #[key_param(tag = MAC_LENGTH, field = Integer)]
1017     MacLength(i32),
1018     /// Specifies whether the device has been factory reset since the
1019     /// last unique ID rotation.  Used for key attestation
1020     #[key_param(tag = RESET_SINCE_ID_ROTATION, field = BoolValue)]
1021     ResetSinceIdRotation,
1022     /// Used to deliver a cryptographic token proving that the user
1023     /// confirmed a signing request
1024     #[key_param(tag = CONFIRMATION_TOKEN, field = Blob)]
1025     ConfirmationToken(Vec<u8>),
1026     /// Used to deliver the certificate serial number to the KeyMint instance
1027     /// certificate generation.
1028     #[key_param(tag = CERTIFICATE_SERIAL, field = Blob)]
1029     CertificateSerial(Vec<u8>),
1030     /// Used to deliver the certificate subject to the KeyMint instance
1031     /// certificate generation. This must be DER encoded X509 name.
1032     #[key_param(tag = CERTIFICATE_SUBJECT, field = Blob)]
1033     CertificateSubject(Vec<u8>),
1034     /// Used to deliver the not before date in milliseconds to KeyMint during key generation/import.
1035     #[key_param(tag = CERTIFICATE_NOT_BEFORE, field = DateTime)]
1036     CertificateNotBefore(i64),
1037     /// Used to deliver the not after date in milliseconds to KeyMint during key generation/import.
1038     #[key_param(tag = CERTIFICATE_NOT_AFTER, field = DateTime)]
1039     CertificateNotAfter(i64),
1040     /// Specifies a maximum boot level at which a key should function
1041     #[key_param(tag = MAX_BOOT_LEVEL, field = Integer)]
1042     MaxBootLevel(i32),
1043 }
1044 }
1045 
1046 impl From<&KmKeyParameter> for KeyParameterValue {
from(kp: &KmKeyParameter) -> Self1047     fn from(kp: &KmKeyParameter) -> Self {
1048         kp.clone().into()
1049     }
1050 }
1051 
1052 /// KeyParameter wraps the KeyParameterValue and the security level at which it is enforced.
1053 #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
1054 pub struct KeyParameter {
1055     value: KeyParameterValue,
1056     #[serde(deserialize_with = "deserialize_primitive")]
1057     #[serde(serialize_with = "serialize_primitive")]
1058     security_level: SecurityLevel,
1059 }
1060 
1061 impl KeyParameter {
1062     /// Create an instance of KeyParameter, given the value and the security level.
new(value: KeyParameterValue, security_level: SecurityLevel) -> Self1063     pub fn new(value: KeyParameterValue, security_level: SecurityLevel) -> Self {
1064         KeyParameter { value, security_level }
1065     }
1066 
1067     /// Construct a KeyParameter from the data from a rusqlite row.
1068     /// Note that following variants of KeyParameterValue should not be stored:
1069     /// IncludeUniqueID, ApplicationID, ApplicationData, RootOfTrust, UniqueID,
1070     /// Attestation*, AssociatedData, Nonce, MacLength, ResetSinceIdRotation, ConfirmationToken.
1071     /// This filtering is enforced at a higher level and here we support conversion for all the
1072     /// variants.
new_from_sql( tag_val: Tag, data: &SqlField, security_level_val: SecurityLevel, ) -> Result<Self>1073     pub fn new_from_sql(
1074         tag_val: Tag,
1075         data: &SqlField,
1076         security_level_val: SecurityLevel,
1077     ) -> Result<Self> {
1078         Ok(Self {
1079             value: KeyParameterValue::new_from_sql(tag_val, data)?,
1080             security_level: security_level_val,
1081         })
1082     }
1083 
1084     /// Get the KeyMint Tag of this this key parameter.
get_tag(&self) -> Tag1085     pub fn get_tag(&self) -> Tag {
1086         self.value.get_tag()
1087     }
1088 
1089     /// Returns key parameter value.
key_parameter_value(&self) -> &KeyParameterValue1090     pub fn key_parameter_value(&self) -> &KeyParameterValue {
1091         &self.value
1092     }
1093 
1094     /// Returns the security level of this key parameter.
security_level(&self) -> &SecurityLevel1095     pub fn security_level(&self) -> &SecurityLevel {
1096         &self.security_level
1097     }
1098 
1099     /// An authorization is a KeyParameter with an associated security level that is used
1100     /// to convey the key characteristics to keystore clients. This function consumes
1101     /// an internal KeyParameter representation to produce the Authorization wire type.
into_authorization(self) -> Authorization1102     pub fn into_authorization(self) -> Authorization {
1103         Authorization { securityLevel: self.security_level, keyParameter: self.value.into() }
1104     }
1105 }
1106