1 // Copyright 2022, 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 //! Abstractions and related types for accessing cryptographic primitives
16 //! and related functionality.
17 
18 // derive(N) generates a method that is missing a docstring.
19 #![allow(missing_docs)]
20 
21 use crate::{km_err, vec_try, vec_try_with_capacity, Error, FallibleAllocExt};
22 use alloc::{
23     format,
24     string::{String, ToString},
25     vec::Vec,
26 };
27 use core::convert::{From, TryInto};
28 use enumn::N;
29 use kmr_derive::AsCborValue;
30 use kmr_wire::keymint::{Algorithm, Digest, EcCurve};
31 use kmr_wire::{cbor, cbor_type_error, AsCborValue, CborError, KeySizeInBits, RsaExponent};
32 use log::error;
33 use spki::SubjectPublicKeyInfoRef;
34 use zeroize::ZeroizeOnDrop;
35 
36 pub mod aes;
37 pub mod des;
38 pub mod ec;
39 pub mod hmac;
40 pub mod rsa;
41 mod traits;
42 pub use traits::*;
43 
44 /// Size of SHA-256 output in bytes.
45 pub const SHA256_DIGEST_LEN: usize = 32;
46 
47 /// Function that mimics `slice.to_vec()` but which detects allocation failures.  This version emits
48 /// `CborError` (instead of the `Error` that `crate::try_to_vec` emits).
49 #[inline]
try_to_vec<T: Clone>(s: &[T]) -> Result<Vec<T>, CborError>50 pub fn try_to_vec<T: Clone>(s: &[T]) -> Result<Vec<T>, CborError> {
51     let mut v = vec_try_with_capacity!(s.len()).map_err(|_e| CborError::AllocationFailed)?;
52     v.extend_from_slice(s);
53     Ok(v)
54 }
55 
56 /// Milliseconds since an arbitrary epoch.
57 #[repr(transparent)]
58 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
59 pub struct MillisecondsSinceEpoch(pub i64);
60 
61 impl From<MillisecondsSinceEpoch> for kmr_wire::secureclock::Timestamp {
from(value: MillisecondsSinceEpoch) -> Self62     fn from(value: MillisecondsSinceEpoch) -> Self {
63         kmr_wire::secureclock::Timestamp { milliseconds: value.0 }
64     }
65 }
66 
67 /// Information for key generation.
68 #[derive(Clone)]
69 pub enum KeyGenInfo {
70     /// Generate an AES key of the given size.
71     Aes(aes::Variant),
72     /// Generate a 3-DES key.
73     TripleDes,
74     /// Generate an HMAC key of the given size.
75     Hmac(KeySizeInBits),
76     /// Generate an RSA keypair of the given size using the given exponent.
77     Rsa(KeySizeInBits, RsaExponent),
78     /// Generate a NIST EC keypair using the given curve.
79     NistEc(ec::NistCurve),
80     /// Generate an Ed25519 keypair.
81     Ed25519,
82     /// Generate an X25519 keypair.
83     X25519,
84 }
85 
86 /// Type of elliptic curve.
87 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, AsCborValue, N)]
88 #[repr(i32)]
89 pub enum CurveType {
90     /// NIST curve.
91     Nist = 0,
92     /// EdDSA curve.
93     EdDsa = 1,
94     /// XDH curve.
95     Xdh = 2,
96 }
97 
98 /// Raw key material used for deriving other keys.
99 #[derive(PartialEq, Eq, ZeroizeOnDrop)]
100 pub struct RawKeyMaterial(pub Vec<u8>);
101 
102 /// Opaque key material whose structure is only known/accessible to the crypto implementation.
103 /// The contents of this are assumed to be encrypted (and so are not `ZeroizeOnDrop`).
104 #[derive(Clone, PartialEq, Eq)]
105 pub struct OpaqueKeyMaterial(pub Vec<u8>);
106 
107 /// Wrapper that holds either a key of explicit type `T`, or an opaque blob of key material.
108 #[derive(Clone, PartialEq, Eq)]
109 pub enum OpaqueOr<T> {
110     /// Explicit key material of the given type, available in plaintext.
111     Explicit(T),
112     /// Opaque key material, either encrypted or an opaque key handle.
113     Opaque(OpaqueKeyMaterial),
114 }
115 
116 /// Macro to provide `impl From<SomeKey> for OpaqueOr<SomeKey>`, so that explicit key material
117 /// automatically converts into the equivalent `OpaqueOr` variant.
118 macro_rules! opaque_from_key {
119     { $t:ty } => {
120         impl From<$t> for OpaqueOr<$t> {
121             fn from(k: $t) -> Self {
122                 Self::Explicit(k)
123             }
124         }
125     }
126 }
127 
128 opaque_from_key!(aes::Key);
129 opaque_from_key!(des::Key);
130 opaque_from_key!(hmac::Key);
131 opaque_from_key!(rsa::Key);
132 opaque_from_key!(ec::Key);
133 
134 impl<T> From<OpaqueKeyMaterial> for OpaqueOr<T> {
from(k: OpaqueKeyMaterial) -> Self135     fn from(k: OpaqueKeyMaterial) -> Self {
136         Self::Opaque(k)
137     }
138 }
139 
140 /// Key material that is held in plaintext (or is alternatively an opaque blob that is only
141 /// known/accessible to the crypto implementation, indicated by the `OpaqueOr::Opaque` variant).
142 #[derive(Clone, PartialEq, Eq)]
143 pub enum KeyMaterial {
144     /// AES symmetric key.
145     Aes(OpaqueOr<aes::Key>),
146     /// 3-DES symmetric key.
147     TripleDes(OpaqueOr<des::Key>),
148     /// HMAC symmetric key.
149     Hmac(OpaqueOr<hmac::Key>),
150     /// RSA asymmetric key.
151     Rsa(OpaqueOr<rsa::Key>),
152     /// Elliptic curve asymmetric key.
153     Ec(EcCurve, CurveType, OpaqueOr<ec::Key>),
154 }
155 
156 /// Macro that extracts the explicit key from an [`OpaqueOr`] wrapper.
157 #[macro_export]
158 macro_rules! explicit {
159     { $key:expr } => {
160         if let $crate::crypto::OpaqueOr::Explicit(k) = $key {
161             Ok(k)
162         } else {
163             Err($crate::km_err!(IncompatibleKeyFormat, "Expected explicit key but found opaque key!"))
164         }
165     }
166 }
167 
168 impl KeyMaterial {
169     /// Indicate whether the key material is for an asymmetric key.
is_asymmetric(&self) -> bool170     pub fn is_asymmetric(&self) -> bool {
171         match self {
172             Self::Aes(_) | Self::TripleDes(_) | Self::Hmac(_) => false,
173             Self::Ec(_, _, _) | Self::Rsa(_) => true,
174         }
175     }
176 
177     /// Indicate whether the key material is for a symmetric key.
is_symmetric(&self) -> bool178     pub fn is_symmetric(&self) -> bool {
179         !self.is_asymmetric()
180     }
181 
182     /// Return the public key information as an ASN.1 DER encodable `SubjectPublicKeyInfo`, as
183     /// described in RFC 5280 section 4.1.
184     ///
185     /// ```asn1
186     /// SubjectPublicKeyInfo  ::=  SEQUENCE  {
187     ///    algorithm            AlgorithmIdentifier,
188     ///    subjectPublicKey     BIT STRING  }
189     ///
190     /// AlgorithmIdentifier  ::=  SEQUENCE  {
191     ///    algorithm               OBJECT IDENTIFIER,
192     ///    parameters              ANY DEFINED BY algorithm OPTIONAL  }
193     /// ```
194     ///
195     /// Returns `None` for a symmetric key.
subject_public_key_info<'a>( &'a self, buf: &'a mut Vec<u8>, ec: &dyn Ec, rsa: &dyn Rsa, ) -> Result<Option<SubjectPublicKeyInfoRef<'a>>, Error>196     pub fn subject_public_key_info<'a>(
197         &'a self,
198         buf: &'a mut Vec<u8>,
199         ec: &dyn Ec,
200         rsa: &dyn Rsa,
201     ) -> Result<Option<SubjectPublicKeyInfoRef<'a>>, Error> {
202         Ok(match self {
203             Self::Rsa(key) => Some(key.subject_public_key_info(buf, rsa)?),
204             Self::Ec(curve, curve_type, key) => {
205                 Some(key.subject_public_key_info(buf, ec, curve, curve_type)?)
206             }
207             _ => None,
208         })
209     }
210 }
211 
212 /// Manual implementation of [`Debug`] that skips emitting plaintext key material.
213 impl core::fmt::Debug for KeyMaterial {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result214     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
215         match self {
216             Self::Aes(k) => match k {
217                 OpaqueOr::Explicit(aes::Key::Aes128(_)) => f.write_str("Aes128(...)"),
218                 OpaqueOr::Explicit(aes::Key::Aes192(_)) => f.write_str("Aes192(...)"),
219                 OpaqueOr::Explicit(aes::Key::Aes256(_)) => f.write_str("Aes256(...)"),
220                 OpaqueOr::Opaque(_) => f.write_str("Aes(opaque)"),
221             },
222             Self::TripleDes(_) => f.write_str("TripleDes(...)"),
223             Self::Hmac(_) => f.write_str("Hmac(...)"),
224             Self::Rsa(_) => f.write_str("Rsa(...)"),
225             Self::Ec(c, _, _) => f.write_fmt(format_args!("Ec({:?}, ...)", c)),
226         }
227     }
228 }
229 
230 impl AsCborValue for KeyMaterial {
from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError>231     fn from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError> {
232         let mut a = match value {
233             cbor::value::Value::Array(a) if a.len() == 3 => a,
234             _ => return cbor_type_error(&value, "arr len 3"),
235         };
236         let raw_key_value = a.remove(2);
237         let opaque = match a.remove(1) {
238             cbor::value::Value::Bool(b) => b,
239             v => return cbor_type_error(&v, "bool"),
240         };
241         let algo: i32 = match a.remove(0) {
242             cbor::value::Value::Integer(i) => i.try_into()?,
243             v => return cbor_type_error(&v, "uint"),
244         };
245 
246         match algo {
247             x if x == Algorithm::Aes as i32 => {
248                 let raw_key = <Vec<u8>>::from_cbor_value(raw_key_value)?;
249                 if opaque {
250                     Ok(Self::Aes(OpaqueKeyMaterial(raw_key).into()))
251                 } else {
252                     match aes::Key::new(raw_key) {
253                         Ok(k) => Ok(Self::Aes(k.into())),
254                         Err(_e) => Err(CborError::UnexpectedItem("bstr", "bstr len 16/24/32")),
255                     }
256                 }
257             }
258             x if x == Algorithm::TripleDes as i32 => {
259                 let raw_key = <Vec<u8>>::from_cbor_value(raw_key_value)?;
260                 if opaque {
261                     Ok(Self::TripleDes(OpaqueKeyMaterial(raw_key).into()))
262                 } else {
263                     Ok(Self::TripleDes(
264                         des::Key(
265                             raw_key
266                                 .try_into()
267                                 .map_err(|_e| CborError::UnexpectedItem("bstr", "bstr len 24"))?,
268                         )
269                         .into(),
270                     ))
271                 }
272             }
273             x if x == Algorithm::Hmac as i32 => {
274                 let raw_key = <Vec<u8>>::from_cbor_value(raw_key_value)?;
275                 if opaque {
276                     Ok(Self::Hmac(OpaqueKeyMaterial(raw_key).into()))
277                 } else {
278                     Ok(Self::Hmac(hmac::Key(raw_key).into()))
279                 }
280             }
281             x if x == Algorithm::Rsa as i32 => {
282                 let raw_key = <Vec<u8>>::from_cbor_value(raw_key_value)?;
283                 if opaque {
284                     Ok(Self::Rsa(OpaqueKeyMaterial(raw_key).into()))
285                 } else {
286                     Ok(Self::Rsa(rsa::Key(raw_key).into()))
287                 }
288             }
289             x if x == Algorithm::Ec as i32 => {
290                 let mut a = match raw_key_value {
291                     cbor::value::Value::Array(a) if a.len() == 3 => a,
292                     _ => return cbor_type_error(&raw_key_value, "arr len 2"),
293                 };
294                 let raw_key_value = a.remove(2);
295                 let raw_key = <Vec<u8>>::from_cbor_value(raw_key_value)?;
296                 let curve_type = CurveType::from_cbor_value(a.remove(1))?;
297                 let curve = <EcCurve>::from_cbor_value(a.remove(0))?;
298                 if opaque {
299                     Ok(Self::Ec(curve, curve_type, OpaqueKeyMaterial(raw_key).into()))
300                 } else {
301                     let key = match (curve, curve_type) {
302                         (EcCurve::P224, CurveType::Nist) => ec::Key::P224(ec::NistKey(raw_key)),
303                         (EcCurve::P256, CurveType::Nist) => ec::Key::P256(ec::NistKey(raw_key)),
304                         (EcCurve::P384, CurveType::Nist) => ec::Key::P384(ec::NistKey(raw_key)),
305                         (EcCurve::P521, CurveType::Nist) => ec::Key::P521(ec::NistKey(raw_key)),
306                         (EcCurve::Curve25519, CurveType::EdDsa) => {
307                             let key = raw_key.try_into().map_err(|_e| {
308                                 error!("decoding Ed25519 key of incorrect len");
309                                 CborError::OutOfRangeIntegerValue
310                             })?;
311                             ec::Key::Ed25519(ec::Ed25519Key(key))
312                         }
313                         (EcCurve::Curve25519, CurveType::Xdh) => {
314                             let key = raw_key.try_into().map_err(|_e| {
315                                 error!("decoding X25519 key of incorrect len");
316                                 CborError::OutOfRangeIntegerValue
317                             })?;
318                             ec::Key::X25519(ec::X25519Key(key))
319                         }
320                         (_, _) => {
321                             error!("Unexpected EC combination ({:?}, {:?})", curve, curve_type);
322                             return Err(CborError::NonEnumValue);
323                         }
324                     };
325                     Ok(Self::Ec(curve, curve_type, key.into()))
326                 }
327             }
328             _ => Err(CborError::UnexpectedItem("unknown enum", "algo enum")),
329         }
330     }
331 
to_cbor_value(self) -> Result<cbor::value::Value, CborError>332     fn to_cbor_value(self) -> Result<cbor::value::Value, CborError> {
333         let cbor_alloc_err = |_e| CborError::AllocationFailed;
334         Ok(cbor::value::Value::Array(match self {
335             Self::Aes(OpaqueOr::Opaque(OpaqueKeyMaterial(k))) => vec_try![
336                 cbor::value::Value::Integer((Algorithm::Aes as i32).into()),
337                 cbor::value::Value::Bool(true),
338                 cbor::value::Value::Bytes(try_to_vec(&k)?),
339             ]
340             .map_err(cbor_alloc_err)?,
341             Self::TripleDes(OpaqueOr::Opaque(OpaqueKeyMaterial(k))) => vec_try![
342                 cbor::value::Value::Integer((Algorithm::TripleDes as i32).into()),
343                 cbor::value::Value::Bool(true),
344                 cbor::value::Value::Bytes(try_to_vec(&k)?),
345             ]
346             .map_err(cbor_alloc_err)?,
347             Self::Hmac(OpaqueOr::Opaque(OpaqueKeyMaterial(k))) => vec_try![
348                 cbor::value::Value::Integer((Algorithm::Hmac as i32).into()),
349                 cbor::value::Value::Bool(true),
350                 cbor::value::Value::Bytes(try_to_vec(&k)?),
351             ]
352             .map_err(cbor_alloc_err)?,
353             Self::Rsa(OpaqueOr::Opaque(OpaqueKeyMaterial(k))) => vec_try![
354                 cbor::value::Value::Integer((Algorithm::Rsa as i32).into()),
355                 cbor::value::Value::Bool(true),
356                 cbor::value::Value::Bytes(try_to_vec(&k)?),
357             ]
358             .map_err(cbor_alloc_err)?,
359             Self::Ec(curve, curve_type, OpaqueOr::Opaque(OpaqueKeyMaterial(k))) => vec_try![
360                 cbor::value::Value::Integer((Algorithm::Ec as i32).into()),
361                 cbor::value::Value::Bool(true),
362                 cbor::value::Value::Array(
363                     vec_try![
364                         cbor::value::Value::Integer((curve as i32).into()),
365                         cbor::value::Value::Integer((curve_type as i32).into()),
366                         cbor::value::Value::Bytes(try_to_vec(&k)?),
367                     ]
368                     .map_err(cbor_alloc_err)?
369                 ),
370             ]
371             .map_err(cbor_alloc_err)?,
372 
373             Self::Aes(OpaqueOr::Explicit(k)) => vec_try![
374                 cbor::value::Value::Integer((Algorithm::Aes as i32).into()),
375                 cbor::value::Value::Bool(false),
376                 match k {
377                     aes::Key::Aes128(k) => cbor::value::Value::Bytes(try_to_vec(&k)?),
378                     aes::Key::Aes192(k) => cbor::value::Value::Bytes(try_to_vec(&k)?),
379                     aes::Key::Aes256(k) => cbor::value::Value::Bytes(try_to_vec(&k)?),
380                 },
381             ]
382             .map_err(cbor_alloc_err)?,
383 
384             Self::TripleDes(OpaqueOr::Explicit(k)) => vec_try![
385                 cbor::value::Value::Integer((Algorithm::TripleDes as i32).into()),
386                 cbor::value::Value::Bool(false),
387                 cbor::value::Value::Bytes(k.0.to_vec()),
388             ]
389             .map_err(cbor_alloc_err)?,
390             Self::Hmac(OpaqueOr::Explicit(k)) => vec_try![
391                 cbor::value::Value::Integer((Algorithm::Hmac as i32).into()),
392                 cbor::value::Value::Bool(false),
393                 cbor::value::Value::Bytes(k.0.clone()),
394             ]
395             .map_err(cbor_alloc_err)?,
396             Self::Rsa(OpaqueOr::Explicit(k)) => vec_try![
397                 cbor::value::Value::Integer((Algorithm::Rsa as i32).into()),
398                 cbor::value::Value::Bool(false),
399                 cbor::value::Value::Bytes(k.0.clone()),
400             ]
401             .map_err(cbor_alloc_err)?,
402             Self::Ec(curve, curve_type, OpaqueOr::Explicit(k)) => vec_try![
403                 cbor::value::Value::Integer((Algorithm::Ec as i32).into()),
404                 cbor::value::Value::Bool(false),
405                 cbor::value::Value::Array(
406                     vec_try![
407                         cbor::value::Value::Integer((curve as i32).into()),
408                         cbor::value::Value::Integer((curve_type as i32).into()),
409                         cbor::value::Value::Bytes(k.private_key_bytes().to_vec()),
410                     ]
411                     .map_err(cbor_alloc_err)?,
412                 ),
413             ]
414             .map_err(cbor_alloc_err)?,
415         }))
416     }
417 
cddl_typename() -> Option<String>418     fn cddl_typename() -> Option<String> {
419         Some("KeyMaterial".to_string())
420     }
421 
cddl_schema() -> Option<String>422     fn cddl_schema() -> Option<String> {
423         Some(format!(
424             "&(
425   ; For each variant the `bool` second entry indicates whether the bstr for the key material
426   ; is opaque (true), or explicit (false).
427   [{}, bool, bstr], ; {}
428   [{}, bool, bstr], ; {}
429   [{}, bool, bstr], ; {}
430   ; An explicit RSA key is in the form of an ASN.1 DER encoding of a PKCS#1 `RSAPrivateKey`
431   ; structure, as specified by RFC 3447 sections A.1.2 and 3.2.
432   [{}, bool, bstr], ; {}
433   ; An explicit EC key for a NIST curve is in the form of an ASN.1 DER encoding of a
434   ; `ECPrivateKey` structure, as specified by RFC 5915 section 3.
435   ; An explicit EC key for curve 25519 is the raw key bytes.
436   [{}, bool, [EcCurve, CurveType, bstr]], ; {}
437 )",
438             Algorithm::Aes as i32,
439             "Algorithm_Aes",
440             Algorithm::TripleDes as i32,
441             "Algorithm_TripleDes",
442             Algorithm::Hmac as i32,
443             "Algorithm_Hmac",
444             Algorithm::Rsa as i32,
445             "Algorithm_Rsa",
446             Algorithm::Ec as i32,
447             "Algorithm_Ec",
448         ))
449     }
450 }
451 
452 /// Direction of cipher operation.
453 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
454 pub enum SymmetricOperation {
455     /// Perform encryption.
456     Encrypt,
457     /// Perform decryption.
458     Decrypt,
459 }
460 
461 /// Extract or generate a nonce of the given size.
nonce( size: usize, caller_nonce: Option<&Vec<u8>>, rng: &mut dyn Rng, ) -> Result<Vec<u8>, Error>462 pub fn nonce(
463     size: usize,
464     caller_nonce: Option<&Vec<u8>>,
465     rng: &mut dyn Rng,
466 ) -> Result<Vec<u8>, Error> {
467     match caller_nonce {
468         Some(n) => match n.len() {
469             l if l == size => Ok(n.clone()),
470             _ => Err(km_err!(InvalidNonce, "want {} byte nonce", size)),
471         },
472         None => {
473             let mut n = vec_try![0; size]?;
474             rng.fill_bytes(&mut n);
475             Ok(n)
476         }
477     }
478 }
479 
480 /// Salt value used in HKDF if none provided.
481 const HKDF_EMPTY_SALT: [u8; SHA256_DIGEST_LEN] = [0; SHA256_DIGEST_LEN];
482 
483 /// Convenience wrapper to perform one-shot HMAC-SHA256.
hmac_sha256(hmac: &dyn Hmac, key: &[u8], data: &[u8]) -> Result<Vec<u8>, Error>484 pub fn hmac_sha256(hmac: &dyn Hmac, key: &[u8], data: &[u8]) -> Result<Vec<u8>, Error> {
485     let mut op = hmac.begin(hmac::Key(crate::try_to_vec(key)?).into(), Digest::Sha256)?;
486     op.update(data)?;
487     op.finish()
488 }
489 
490 /// Default implementation of [`Hkdf`] for any type implementing [`Hmac`].
491 impl<T: Hmac> Hkdf for T {
extract(&self, mut salt: &[u8], ikm: &[u8]) -> Result<OpaqueOr<hmac::Key>, Error>492     fn extract(&self, mut salt: &[u8], ikm: &[u8]) -> Result<OpaqueOr<hmac::Key>, Error> {
493         if salt.is_empty() {
494             salt = &HKDF_EMPTY_SALT[..];
495         }
496         let prk = hmac_sha256(self, salt, ikm)?;
497         Ok(OpaqueOr::Explicit(hmac::Key::new(prk)))
498     }
499 
expand( &self, prk: &OpaqueOr<hmac::Key>, info: &[u8], out_len: usize, ) -> Result<Vec<u8>, Error>500     fn expand(
501         &self,
502         prk: &OpaqueOr<hmac::Key>,
503         info: &[u8],
504         out_len: usize,
505     ) -> Result<Vec<u8>, Error> {
506         let prk = &explicit!(prk)?.0;
507         let n = (out_len + SHA256_DIGEST_LEN - 1) / SHA256_DIGEST_LEN;
508         if n > 256 {
509             return Err(km_err!(InvalidArgument, "overflow in hkdf"));
510         }
511         let mut t = vec_try_with_capacity!(SHA256_DIGEST_LEN)?;
512         let mut okm = vec_try_with_capacity!(n * SHA256_DIGEST_LEN)?;
513         let n = n as u8;
514         for idx in 0..n {
515             let mut input = vec_try_with_capacity!(t.len() + info.len() + 1)?;
516             input.extend_from_slice(&t);
517             input.extend_from_slice(info);
518             input.push(idx + 1);
519 
520             t = hmac_sha256(self, prk, &input)?;
521             okm.try_extend_from_slice(&t)?;
522         }
523         okm.truncate(out_len);
524         Ok(okm)
525     }
526 }
527 
528 /// Default implementation of [`Ckdf`] for any type implementing [`AesCmac`].
529 impl<T: AesCmac> Ckdf for T {
ckdf( &self, key: &OpaqueOr<aes::Key>, label: &[u8], chunks: &[&[u8]], out_len: usize, ) -> Result<Vec<u8>, Error>530     fn ckdf(
531         &self,
532         key: &OpaqueOr<aes::Key>,
533         label: &[u8],
534         chunks: &[&[u8]],
535         out_len: usize,
536     ) -> Result<Vec<u8>, Error> {
537         let key = explicit!(key)?;
538         // Note: the variables i and l correspond to i and L in the standard.  See page 12 of
539         // http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-108.pdf.
540 
541         let blocks: u32 = ((out_len + aes::BLOCK_SIZE - 1) / aes::BLOCK_SIZE) as u32;
542         let l = (out_len * 8) as u32; // in bits
543         let net_order_l = l.to_be_bytes();
544         let zero_byte: [u8; 1] = [0];
545         let mut output = vec_try![0; out_len]?;
546         let mut output_pos = 0;
547 
548         for i in 1u32..=blocks {
549             // Data to mac is (i:u32 || label || 0x00:u8 || context || L:u32), with integers in
550             // network order.
551             let mut op = self.begin(key.clone().into())?;
552             let net_order_i = i.to_be_bytes();
553             op.update(&net_order_i[..])?;
554             op.update(label)?;
555             op.update(&zero_byte[..])?;
556             for chunk in chunks {
557                 op.update(chunk)?;
558             }
559             op.update(&net_order_l[..])?;
560 
561             let data = op.finish()?;
562             let copy_len = core::cmp::min(data.len(), output.len() - output_pos);
563             output[output_pos..output_pos + copy_len].clone_from_slice(&data[..copy_len]);
564             output_pos += copy_len;
565         }
566         if output_pos != output.len() {
567             return Err(km_err!(
568                 InvalidArgument,
569                 "finished at {} before end of output at {}",
570                 output_pos,
571                 output.len()
572             ));
573         }
574         Ok(output)
575     }
576 }
577