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