blob: 466fb505987ac3043c44e3fac91a8cfc3253b761 [file] [log] [blame]
Hasini Gunasinghe12486362020-07-24 18:40:20 +00001// 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
Janis Danisevskise6efb242020-12-19 13:58:01 -080015//! 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>;
Janis Danisevskis6b00e252020-12-22 11:36:45 -080035//! pub fn new_from_tag_primitive_pair<T: Into<Primitive>>(tag: Tag, v: T)
36//! -> Result<Self, PrimitiveError>;
Janis Danisevskise6efb242020-12-19 13:58:01 -080037//! 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
Janis Danisevskis6b00e252020-12-22 11:36:45 -080045//! Each of the six functions is implemented as match statement over each key parameter variant.
Janis Danisevskise6efb242020-12-19 13:58:01 -080046//! 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.
Hasini Gunasinghe12486362020-07-24 18:40:20 +000092
Janis Danisevskis6b00e252020-12-22 11:36:45 -080093use std::convert::TryInto;
94
Janis Danisevskis030ba022021-05-26 11:15:30 -070095use crate::database::utils::SqlField;
Hasini Gunasingheaf993662020-07-24 18:40:20 +000096use crate::error::Error as KeystoreError;
Janis Danisevskisc5b210b2020-09-11 13:27:37 -070097use crate::error::ResponseCode;
98
Shawn Willden708744a2020-12-11 13:05:27 +000099pub use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
Janis Danisevskisc5b210b2020-09-11 13:27:37 -0700100 Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve,
101 HardwareAuthenticatorType::HardwareAuthenticatorType, KeyOrigin::KeyOrigin,
Janis Danisevskis398e6be2020-12-17 09:29:25 -0800102 KeyParameter::KeyParameter as KmKeyParameter,
103 KeyParameterValue::KeyParameterValue as KmKeyParameterValue, KeyPurpose::KeyPurpose,
104 PaddingMode::PaddingMode, SecurityLevel::SecurityLevel, Tag::Tag,
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000105};
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700106use android_system_keystore2::aidl::android::system::keystore2::Authorization::Authorization;
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000107use anyhow::{Context, Result};
Janis Danisevskis4522c2b2020-11-27 18:04:58 -0800108use rusqlite::types::{Null, ToSql, ToSqlOutput};
109use rusqlite::Result as SqlResult;
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700110use serde::de::Deserializer;
111use serde::ser::Serializer;
112use serde::{Deserialize, Serialize};
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000113
David Drysdale2566fb32024-07-09 14:46:37 +0100114#[cfg(test)]
115mod generated_key_parameter_tests;
116
117#[cfg(test)]
118mod basic_tests;
119
120#[cfg(test)]
121mod storage_tests;
122
123#[cfg(test)]
124mod wire_tests;
125
Janis Danisevskise6efb242020-12-19 13:58:01 -0800126/// 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)))`
138trait AssociatePrimitive {
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700139 type Primitive: Into<Primitive> + TryFrom<Primitive>;
Janis Danisevskise6efb242020-12-19 13:58:01 -0800140
141 fn from_primitive(v: Self::Primitive) -> Self;
142 fn to_primitive(&self) -> Self::Primitive;
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000143}
144
Janis Danisevskise6efb242020-12-19 13:58:01 -0800145/// 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.
147macro_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.
163macro_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
178implement_associate_primitive_for_aidl_enum! {Algorithm}
179implement_associate_primitive_for_aidl_enum! {BlockMode}
180implement_associate_primitive_for_aidl_enum! {Digest}
181implement_associate_primitive_for_aidl_enum! {EcCurve}
182implement_associate_primitive_for_aidl_enum! {HardwareAuthenticatorType}
183implement_associate_primitive_for_aidl_enum! {KeyOrigin}
184implement_associate_primitive_for_aidl_enum! {KeyPurpose}
185implement_associate_primitive_for_aidl_enum! {PaddingMode}
186implement_associate_primitive_for_aidl_enum! {SecurityLevel}
187
188implement_associate_primitive_identity! {Vec<u8>}
189implement_associate_primitive_identity! {i64}
190implement_associate_primitive_identity! {i32}
191
Janis Danisevskis6b00e252020-12-22 11:36:45 -0800192/// 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.
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700195#[derive(Deserialize, Serialize)]
Janis Danisevskis6b00e252020-12-22 11:36:45 -0800196pub 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
205impl From<i64> for Primitive {
206 fn from(v: i64) -> Self {
207 Self::I64(v)
208 }
209}
210impl From<i32> for Primitive {
211 fn from(v: i32) -> Self {
212 Self::I32(v)
213 }
214}
215impl From<Vec<u8>> for Primitive {
216 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)]
223pub 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
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700232impl TryFrom<Primitive> for i64 {
Janis Danisevskis6b00e252020-12-22 11:36:45 -0800233 type Error = PrimitiveError;
234
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700235 fn try_from(p: Primitive) -> Result<i64, Self::Error> {
236 match p {
237 Primitive::I64(v) => Ok(v),
Janis Danisevskis6b00e252020-12-22 11:36:45 -0800238 _ => Err(Self::Error::TypeMismatch),
239 }
240 }
241}
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700242impl TryFrom<Primitive> for i32 {
Janis Danisevskis6b00e252020-12-22 11:36:45 -0800243 type Error = PrimitiveError;
244
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700245 fn try_from(p: Primitive) -> Result<i32, Self::Error> {
246 match p {
247 Primitive::I32(v) => Ok(v),
Janis Danisevskis6b00e252020-12-22 11:36:45 -0800248 _ => Err(Self::Error::TypeMismatch),
249 }
250 }
251}
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700252impl TryFrom<Primitive> for Vec<u8> {
Janis Danisevskis6b00e252020-12-22 11:36:45 -0800253 type Error = PrimitiveError;
254
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700255 fn try_from(p: Primitive) -> Result<Vec<u8>, Self::Error> {
256 match p {
257 Primitive::Vec(v) => Ok(v),
Janis Danisevskis6b00e252020-12-22 11:36:45 -0800258 _ => Err(Self::Error::TypeMismatch),
259 }
260 }
261}
262
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700263fn serialize_primitive<S, P>(v: &P, serializer: S) -> Result<S::Ok, S::Error>
264where
265 S: Serializer,
266 P: AssociatePrimitive,
267{
268 let primitive: Primitive = v.to_primitive().into();
269 primitive.serialize(serializer)
270}
271
272fn deserialize_primitive<'de, D, T>(deserializer: D) -> Result<T, D::Error>
273where
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
Janis Danisevskis6b00e252020-12-22 11:36:45 -0800283/// 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/// ```
305macro_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
Janis Danisevskise6efb242020-12-19 13:58:01 -0800324/// 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/// ```
339macro_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/// ```
371macro_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/// ```
421macro_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/// ```
484macro_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.
520trait KpDefault {
521 fn default() -> Self;
522}
523
524impl KpDefault for i32 {
525 fn default() -> Self {
526 0
527 }
528}
529
530impl KpDefault for bool {
531 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/// ```
571macro_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)*], []) => {
Matthew Maurerb77a28d2021-05-07 16:08:20 -0700638 impl From<$enum_name> for KmKeyParameter {
639 fn from(x: $enum_name) -> Self {
640 match x {
Janis Danisevskise6efb242020-12-19 13:58:01 -0800641 $($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.
666macro_rules! implement_key_parameter_value {
667 (
668 $(#[$enum_meta:meta])*
669 $enum_vis:vis enum $enum_name:ident {
670 $(
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800671 $(#[$($emeta:tt)+])*
672 $vname:ident$(($vtype:ty))?
Janis Danisevskise6efb242020-12-19 13:58:01 -0800673 ),* $(,)?
674 }
675 ) => {
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800676 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 ) => {
Janis Danisevskise6efb242020-12-19 13:58:01 -0800781 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),*);
Janis Danisevskis6b00e252020-12-22 11:36:45 -0800793 implement_from_tag_primitive_pair!($enum_name; $($vname$(($vtype))? $tag_name),*);
Janis Danisevskise6efb242020-12-19 13:58:01 -0800794
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 }
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700802
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 }
Janis Danisevskise6efb242020-12-19 13:58:01 -0800810 }
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
821implement_key_parameter_value! {
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000822/// KeyParameterValue holds a value corresponding to one of the Tags defined in
Shawn Willden525c0032021-03-29 13:58:33 +0000823/// the AIDL spec at hardware/interfaces/security/keymint
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700824#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Deserialize, Serialize)]
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000825pub enum KeyParameterValue {
826 /// Associated with Tag:INVALID
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800827 #[key_param(tag = INVALID, field = Invalid)]
828 Invalid,
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000829 /// Set of purposes for which the key may be used
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700830 #[serde(deserialize_with = "deserialize_primitive")]
831 #[serde(serialize_with = "serialize_primitive")]
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800832 #[key_param(tag = PURPOSE, field = KeyPurpose)]
833 KeyPurpose(KeyPurpose),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000834 /// Cryptographic algorithm with which the key is used
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700835 #[serde(deserialize_with = "deserialize_primitive")]
836 #[serde(serialize_with = "serialize_primitive")]
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800837 #[key_param(tag = ALGORITHM, field = Algorithm)]
838 Algorithm(Algorithm),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000839 /// Size of the key , in bits
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800840 #[key_param(tag = KEY_SIZE, field = Integer)]
841 KeySize(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000842 /// Block cipher mode(s) with which the key may be used
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700843 #[serde(deserialize_with = "deserialize_primitive")]
844 #[serde(serialize_with = "serialize_primitive")]
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800845 #[key_param(tag = BLOCK_MODE, field = BlockMode)]
846 BlockMode(BlockMode),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000847 /// Digest algorithms that may be used with the key to perform signing and verification
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700848 #[serde(deserialize_with = "deserialize_primitive")]
849 #[serde(serialize_with = "serialize_primitive")]
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800850 #[key_param(tag = DIGEST, field = Digest)]
851 Digest(Digest),
David Drysdalebf00b4a2023-04-24 17:24:30 +0100852 /// 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),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000857 /// Padding modes that may be used with the key. Relevant to RSA, AES and 3DES keys.
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700858 #[serde(deserialize_with = "deserialize_primitive")]
859 #[serde(serialize_with = "serialize_primitive")]
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800860 #[key_param(tag = PADDING, field = PaddingMode)]
861 PaddingMode(PaddingMode),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000862 /// Can the caller provide a nonce for nonce-requiring operations
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800863 #[key_param(tag = CALLER_NONCE, field = BoolValue)]
864 CallerNonce,
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000865 /// Minimum length of MAC for HMAC keys and AES keys that support GCM mode
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800866 #[key_param(tag = MIN_MAC_LENGTH, field = Integer)]
867 MinMacLength(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000868 /// The elliptic curve
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700869 #[serde(deserialize_with = "deserialize_primitive")]
870 #[serde(serialize_with = "serialize_primitive")]
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800871 #[key_param(tag = EC_CURVE, field = EcCurve)]
872 EcCurve(EcCurve),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000873 /// Value of the public exponent for an RSA key pair
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800874 #[key_param(tag = RSA_PUBLIC_EXPONENT, field = LongInteger)]
875 RSAPublicExponent(i64),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000876 /// An attestation certificate for the generated key should contain an application-scoped
877 /// and time-bounded device-unique ID
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800878 #[key_param(tag = INCLUDE_UNIQUE_ID, field = BoolValue)]
879 IncludeUniqueID,
Hasini Gunasingheaf993662020-07-24 18:40:20 +0000880 //TODO: find out about this
881 // /// Necessary system environment conditions for the generated key to be used
882 // KeyBlobUsageRequirements(KeyBlobUsageRequirements),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000883 /// Only the boot loader can use the key
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800884 #[key_param(tag = BOOTLOADER_ONLY, field = BoolValue)]
885 BootLoaderOnly,
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000886 /// When deleted, the key is guaranteed to be permanently deleted and unusable
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800887 #[key_param(tag = ROLLBACK_RESISTANCE, field = BoolValue)]
888 RollbackResistance,
Janis Danisevskis5c748212021-05-17 17:13:56 -0700889 /// The Key shall only be used during the early boot stage
890 #[key_param(tag = EARLY_BOOT_ONLY, field = BoolValue)]
891 EarlyBootOnly,
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000892 /// The date and time at which the key becomes active
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800893 #[key_param(tag = ACTIVE_DATETIME, field = DateTime)]
894 ActiveDateTime(i64),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000895 /// The date and time at which the key expires for signing and encryption
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800896 #[key_param(tag = ORIGINATION_EXPIRE_DATETIME, field = DateTime)]
897 OriginationExpireDateTime(i64),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000898 /// The date and time at which the key expires for verification and decryption
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800899 #[key_param(tag = USAGE_EXPIRE_DATETIME, field = DateTime)]
900 UsageExpireDateTime(i64),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000901 /// Minimum amount of time that elapses between allowed operations
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800902 #[key_param(tag = MIN_SECONDS_BETWEEN_OPS, field = Integer)]
903 MinSecondsBetweenOps(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000904 /// Maximum number of times that a key may be used between system reboots
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800905 #[key_param(tag = MAX_USES_PER_BOOT, field = Integer)]
906 MaxUsesPerBoot(i32),
Qi Wub9433b52020-12-01 14:52:46 +0800907 /// The number of times that a limited use key can be used
908 #[key_param(tag = USAGE_COUNT_LIMIT, field = Integer)]
909 UsageCountLimit(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000910 /// ID of the Android user that is permitted to use the key
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800911 #[key_param(tag = USER_ID, field = Integer)]
912 UserID(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000913 /// A key may only be used under a particular secure user authentication state
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800914 #[key_param(tag = USER_SECURE_ID, field = LongInteger)]
915 UserSecureID(i64),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000916 /// No authentication is required to use this key
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800917 #[key_param(tag = NO_AUTH_REQUIRED, field = BoolValue)]
918 NoAuthRequired,
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000919 /// The types of user authenticators that may be used to authorize this key
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700920 #[serde(deserialize_with = "deserialize_primitive")]
921 #[serde(serialize_with = "serialize_primitive")]
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800922 #[key_param(tag = USER_AUTH_TYPE, field = HardwareAuthenticatorType)]
923 HardwareAuthenticatorType(HardwareAuthenticatorType),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000924 /// The time in seconds for which the key is authorized for use, after user authentication
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800925 #[key_param(tag = AUTH_TIMEOUT, field = Integer)]
926 AuthTimeout(i32),
Eric Biggersb5613da2024-03-13 19:31:42 +0000927 /// 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.
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800929 #[key_param(tag = ALLOW_WHILE_ON_BODY, field = BoolValue)]
930 AllowWhileOnBody,
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000931 /// The key must be unusable except when the user has provided proof of physical presence
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800932 #[key_param(tag = TRUSTED_USER_PRESENCE_REQUIRED, field = BoolValue)]
933 TrustedUserPresenceRequired,
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000934 /// 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
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800936 #[key_param(tag = TRUSTED_CONFIRMATION_REQUIRED, field = BoolValue)]
937 TrustedConfirmationRequired,
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000938 /// The key may only be used when the device is unlocked
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800939 #[key_param(tag = UNLOCKED_DEVICE_REQUIRED, field = BoolValue)]
940 UnlockedDeviceRequired,
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000941 /// When provided to generateKey or importKey, this tag specifies data
942 /// that is necessary during all uses of the key
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800943 #[key_param(tag = APPLICATION_ID, field = Blob)]
944 ApplicationID(Vec<u8>),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000945 /// When provided to generateKey or importKey, this tag specifies data
946 /// that is necessary during all uses of the key
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800947 #[key_param(tag = APPLICATION_DATA, field = Blob)]
948 ApplicationData(Vec<u8>),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000949 /// Specifies the date and time the key was created
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800950 #[key_param(tag = CREATION_DATETIME, field = DateTime)]
951 CreationDateTime(i64),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000952 /// Specifies where the key was created, if known
Janis Danisevskis5d772ef2022-03-17 20:06:33 -0700953 #[serde(deserialize_with = "deserialize_primitive")]
954 #[serde(serialize_with = "serialize_primitive")]
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800955 #[key_param(tag = ORIGIN, field = Origin)]
956 KeyOrigin(KeyOrigin),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000957 /// The key used by verified boot to validate the operating system booted
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800958 #[key_param(tag = ROOT_OF_TRUST, field = Blob)]
959 RootOfTrust(Vec<u8>),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000960 /// System OS version with which the key may be used
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800961 #[key_param(tag = OS_VERSION, field = Integer)]
962 OSVersion(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000963 /// Specifies the system security patch level with which the key may be used
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800964 #[key_param(tag = OS_PATCHLEVEL, field = Integer)]
965 OSPatchLevel(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000966 /// Specifies a unique, time-based identifier
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800967 #[key_param(tag = UNIQUE_ID, field = Blob)]
968 UniqueID(Vec<u8>),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000969 /// Used to deliver a "challenge" value to the attestKey() method
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800970 #[key_param(tag = ATTESTATION_CHALLENGE, field = Blob)]
971 AttestationChallenge(Vec<u8>),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000972 /// The set of applications which may use a key, used only with attestKey()
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800973 #[key_param(tag = ATTESTATION_APPLICATION_ID, field = Blob)]
974 AttestationApplicationID(Vec<u8>),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000975 /// Provides the device's brand name, to attestKey()
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800976 #[key_param(tag = ATTESTATION_ID_BRAND, field = Blob)]
977 AttestationIdBrand(Vec<u8>),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000978 /// Provides the device's device name, to attestKey()
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800979 #[key_param(tag = ATTESTATION_ID_DEVICE, field = Blob)]
980 AttestationIdDevice(Vec<u8>),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000981 /// Provides the device's product name, to attestKey()
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800982 #[key_param(tag = ATTESTATION_ID_PRODUCT, field = Blob)]
983 AttestationIdProduct(Vec<u8>),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000984 /// Provides the device's serial number, to attestKey()
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800985 #[key_param(tag = ATTESTATION_ID_SERIAL, field = Blob)]
986 AttestationIdSerial(Vec<u8>),
Eran Messeri637259c2022-10-31 12:23:36 +0000987 /// Provides the primary IMEI for the device, to attestKey()
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800988 #[key_param(tag = ATTESTATION_ID_IMEI, field = Blob)]
989 AttestationIdIMEI(Vec<u8>),
Eran Messeri637259c2022-10-31 12:23:36 +0000990 /// Provides a second IMEI for the device, to attestKey()
991 #[key_param(tag = ATTESTATION_ID_SECOND_IMEI, field = Blob)]
992 AttestationIdSecondIMEI(Vec<u8>),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000993 /// Provides the MEIDs for all radios on the device, to attestKey()
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800994 #[key_param(tag = ATTESTATION_ID_MEID, field = Blob)]
995 AttestationIdMEID(Vec<u8>),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000996 /// Provides the device's manufacturer name, to attestKey()
Janis Danisevskis6f1bb562020-12-28 15:52:41 -0800997 #[key_param(tag = ATTESTATION_ID_MANUFACTURER, field = Blob)]
998 AttestationIdManufacturer(Vec<u8>),
Hasini Gunasinghe12486362020-07-24 18:40:20 +0000999 /// Provides the device's model name, to attestKey()
Janis Danisevskis6f1bb562020-12-28 15:52:41 -08001000 #[key_param(tag = ATTESTATION_ID_MODEL, field = Blob)]
1001 AttestationIdModel(Vec<u8>),
Hasini Gunasinghe12486362020-07-24 18:40:20 +00001002 /// Specifies the vendor image security patch level with which the key may be used
Janis Danisevskis6f1bb562020-12-28 15:52:41 -08001003 #[key_param(tag = VENDOR_PATCHLEVEL, field = Integer)]
1004 VendorPatchLevel(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +00001005 /// Specifies the boot image (kernel) security patch level with which the key may be used
Janis Danisevskis6f1bb562020-12-28 15:52:41 -08001006 #[key_param(tag = BOOT_PATCHLEVEL, field = Integer)]
1007 BootPatchLevel(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +00001008 /// Provides "associated data" for AES-GCM encryption or decryption
Janis Danisevskis6f1bb562020-12-28 15:52:41 -08001009 #[key_param(tag = ASSOCIATED_DATA, field = Blob)]
1010 AssociatedData(Vec<u8>),
Hasini Gunasinghe12486362020-07-24 18:40:20 +00001011 /// Provides or returns a nonce or Initialization Vector (IV) for AES-GCM,
1012 /// AES-CBC, AES-CTR, or 3DES-CBC encryption or decryption
Janis Danisevskis6f1bb562020-12-28 15:52:41 -08001013 #[key_param(tag = NONCE, field = Blob)]
1014 Nonce(Vec<u8>),
Hasini Gunasinghe12486362020-07-24 18:40:20 +00001015 /// Provides the requested length of a MAC or GCM authentication tag, in bits
Janis Danisevskis6f1bb562020-12-28 15:52:41 -08001016 #[key_param(tag = MAC_LENGTH, field = Integer)]
1017 MacLength(i32),
Hasini Gunasinghe12486362020-07-24 18:40:20 +00001018 /// Specifies whether the device has been factory reset since the
1019 /// last unique ID rotation. Used for key attestation
Janis Danisevskis6f1bb562020-12-28 15:52:41 -08001020 #[key_param(tag = RESET_SINCE_ID_ROTATION, field = BoolValue)]
1021 ResetSinceIdRotation,
Hasini Gunasinghe12486362020-07-24 18:40:20 +00001022 /// Used to deliver a cryptographic token proving that the user
Janis Danisevskis2c084012021-01-31 22:23:17 -08001023 /// confirmed a signing request
Janis Danisevskis6f1bb562020-12-28 15:52:41 -08001024 #[key_param(tag = CONFIRMATION_TOKEN, field = Blob)]
1025 ConfirmationToken(Vec<u8>),
Janis Danisevskis2c084012021-01-31 22:23:17 -08001026 /// 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),
Paul Crowley7c57bf12021-02-02 16:26:57 -08001040 /// Specifies a maximum boot level at which a key should function
1041 #[key_param(tag = MAX_BOOT_LEVEL, field = Integer)]
1042 MaxBootLevel(i32),
Janis Danisevskise6efb242020-12-19 13:58:01 -08001043}
1044}
1045
1046impl From<&KmKeyParameter> for KeyParameterValue {
1047 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.
Janis Danisevskis5d772ef2022-03-17 20:06:33 -07001053#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
Janis Danisevskise6efb242020-12-19 13:58:01 -08001054pub struct KeyParameter {
1055 value: KeyParameterValue,
Janis Danisevskis5d772ef2022-03-17 20:06:33 -07001056 #[serde(deserialize_with = "deserialize_primitive")]
1057 #[serde(serialize_with = "serialize_primitive")]
Janis Danisevskise6efb242020-12-19 13:58:01 -08001058 security_level: SecurityLevel,
Hasini Gunasinghe12486362020-07-24 18:40:20 +00001059}
1060
1061impl KeyParameter {
1062 /// Create an instance of KeyParameter, given the value and the security level.
Janis Danisevskise6efb242020-12-19 13:58:01 -08001063 pub fn new(value: KeyParameterValue, security_level: SecurityLevel) -> Self {
1064 KeyParameter { value, security_level }
Hasini Gunasinghe12486362020-07-24 18:40:20 +00001065 }
1066
Hasini Gunasingheaf993662020-07-24 18:40:20 +00001067 /// 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.
1073 pub fn new_from_sql(
Janis Danisevskisc5b210b2020-09-11 13:27:37 -07001074 tag_val: Tag,
Hasini Gunasingheaf993662020-07-24 18:40:20 +00001075 data: &SqlField,
Janis Danisevskisc5b210b2020-09-11 13:27:37 -07001076 security_level_val: SecurityLevel,
Hasini Gunasingheaf993662020-07-24 18:40:20 +00001077 ) -> Result<Self> {
Janis Danisevskise6efb242020-12-19 13:58:01 -08001078 Ok(Self {
1079 value: KeyParameterValue::new_from_sql(tag_val, data)?,
1080 security_level: security_level_val,
1081 })
1082 }
Hasini Gunasingheaf993662020-07-24 18:40:20 +00001083
Janis Danisevskise6efb242020-12-19 13:58:01 -08001084 /// Get the KeyMint Tag of this this key parameter.
1085 pub fn get_tag(&self) -> Tag {
1086 self.value.get_tag()
1087 }
1088
1089 /// Returns key parameter value.
1090 pub fn key_parameter_value(&self) -> &KeyParameterValue {
1091 &self.value
1092 }
1093
1094 /// Returns the security level of this key parameter.
1095 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.
1102 pub fn into_authorization(self) -> Authorization {
1103 Authorization { securityLevel: self.security_level, keyParameter: self.value.into() }
Hasini Gunasingheaf993662020-07-24 18:40:20 +00001104 }
1105}