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, ¶ms)
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