• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 //! This is the Keystore 2.0 Enforcements module.
16 // TODO: more description to follow.
17 use crate::error::{map_binder_status, Error, ErrorCode};
18 use crate::globals::{get_timestamp_service, ASYNC_TASK, DB, ENFORCEMENTS};
19 use crate::key_parameter::{KeyParameter, KeyParameterValue};
20 use crate::{authorization::Error as AuthzError, super_key::SuperEncryptionType};
21 use crate::{
22     database::{AuthTokenEntry, MonotonicRawTime},
23     globals::SUPER_KEY,
24 };
25 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
26     Algorithm::Algorithm, ErrorCode::ErrorCode as Ec, HardwareAuthToken::HardwareAuthToken,
27     HardwareAuthenticatorType::HardwareAuthenticatorType,
28     KeyParameter::KeyParameter as KmKeyParameter, KeyPurpose::KeyPurpose, Tag::Tag,
29 };
30 use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
31     TimeStampToken::TimeStampToken,
32 };
33 use android_security_authorization::aidl::android::security::authorization::ResponseCode::ResponseCode as AuthzResponseCode;
34 use android_system_keystore2::aidl::android::system::keystore2::{
35     Domain::Domain, IKeystoreSecurityLevel::KEY_FLAG_AUTH_BOUND_WITHOUT_CRYPTOGRAPHIC_LSKF_BINDING,
36     OperationChallenge::OperationChallenge,
37 };
38 use anyhow::{Context, Result};
39 use std::{
40     collections::{HashMap, HashSet},
41     sync::{
42         mpsc::{channel, Receiver, Sender, TryRecvError},
43         Arc, Mutex, Weak,
44     },
45     time::SystemTime,
46 };
47 
48 #[derive(Debug)]
49 enum AuthRequestState {
50     /// An outstanding per operation authorization request.
51     OpAuth,
52     /// An outstanding request for per operation authorization and secure timestamp.
53     TimeStampedOpAuth(Receiver<Result<TimeStampToken, Error>>),
54     /// An outstanding request for a timestamp token.
55     TimeStamp(Receiver<Result<TimeStampToken, Error>>),
56 }
57 
58 #[derive(Debug)]
59 struct AuthRequest {
60     state: AuthRequestState,
61     /// This need to be set to Some to fulfill a AuthRequestState::OpAuth or
62     /// AuthRequestState::TimeStampedOpAuth.
63     hat: Mutex<Option<HardwareAuthToken>>,
64 }
65 
66 unsafe impl Sync for AuthRequest {}
67 
68 impl AuthRequest {
op_auth() -> Arc<Self>69     fn op_auth() -> Arc<Self> {
70         Arc::new(Self { state: AuthRequestState::OpAuth, hat: Mutex::new(None) })
71     }
72 
timestamped_op_auth(receiver: Receiver<Result<TimeStampToken, Error>>) -> Arc<Self>73     fn timestamped_op_auth(receiver: Receiver<Result<TimeStampToken, Error>>) -> Arc<Self> {
74         Arc::new(Self {
75             state: AuthRequestState::TimeStampedOpAuth(receiver),
76             hat: Mutex::new(None),
77         })
78     }
79 
timestamp( hat: HardwareAuthToken, receiver: Receiver<Result<TimeStampToken, Error>>, ) -> Arc<Self>80     fn timestamp(
81         hat: HardwareAuthToken,
82         receiver: Receiver<Result<TimeStampToken, Error>>,
83     ) -> Arc<Self> {
84         Arc::new(Self { state: AuthRequestState::TimeStamp(receiver), hat: Mutex::new(Some(hat)) })
85     }
86 
add_auth_token(&self, hat: HardwareAuthToken)87     fn add_auth_token(&self, hat: HardwareAuthToken) {
88         *self.hat.lock().unwrap() = Some(hat)
89     }
90 
get_auth_tokens(&self) -> Result<(HardwareAuthToken, Option<TimeStampToken>)>91     fn get_auth_tokens(&self) -> Result<(HardwareAuthToken, Option<TimeStampToken>)> {
92         let hat = self
93             .hat
94             .lock()
95             .unwrap()
96             .take()
97             .ok_or(Error::Km(ErrorCode::KEY_USER_NOT_AUTHENTICATED))
98             .context("In get_auth_tokens: No operation auth token received.")?;
99 
100         let tst = match &self.state {
101             AuthRequestState::TimeStampedOpAuth(recv) | AuthRequestState::TimeStamp(recv) => {
102                 let result = recv.recv().context("In get_auth_tokens: Sender disconnected.")?;
103                 Some(result.context(concat!(
104                     "In get_auth_tokens: Worker responded with error ",
105                     "from generating timestamp token."
106                 ))?)
107             }
108             AuthRequestState::OpAuth => None,
109         };
110         Ok((hat, tst))
111     }
112 }
113 
114 /// DeferredAuthState describes how auth tokens and timestamp tokens need to be provided when
115 /// updating and finishing an operation.
116 #[derive(Debug)]
117 enum DeferredAuthState {
118     /// Used when an operation does not require further authorization.
119     NoAuthRequired,
120     /// Indicates that the operation requires an operation specific token. This means we have
121     /// to return an operation challenge to the client which should reward us with an
122     /// operation specific auth token. If it is not provided before the client calls update
123     /// or finish, the operation fails as not authorized.
124     OpAuthRequired,
125     /// Indicates that the operation requires a time stamp token. The auth token was already
126     /// loaded from the database, but it has to be accompanied by a time stamp token to inform
127     /// the target KM with a different clock about the time on the authenticators.
128     TimeStampRequired(HardwareAuthToken),
129     /// Indicates that both an operation bound auth token and a verification token are
130     /// before the operation can commence.
131     TimeStampedOpAuthRequired,
132     /// In this state the auth info is waiting for the deferred authorizations to come in.
133     /// We block on timestamp tokens, because we can always make progress on these requests.
134     /// The per-op auth tokens might never come, which means we fail if the client calls
135     /// update or finish before we got a per-op auth token.
136     Waiting(Arc<AuthRequest>),
137     /// In this state we have gotten all of the required tokens, we just cache them to
138     /// be used when the operation progresses.
139     Token(HardwareAuthToken, Option<TimeStampToken>),
140 }
141 
142 /// Auth info hold all of the authorization related information of an operation. It is stored
143 /// in and owned by the operation. It is constructed by authorize_create and stays with the
144 /// operation until it completes.
145 #[derive(Debug)]
146 pub struct AuthInfo {
147     state: DeferredAuthState,
148     /// An optional key id required to update the usage count if the key usage is limited.
149     key_usage_limited: Option<i64>,
150     confirmation_token_receiver: Option<Arc<Mutex<Option<Receiver<Vec<u8>>>>>>,
151 }
152 
153 struct TokenReceiverMap {
154     /// The map maps an outstanding challenge to a TokenReceiver. If an incoming Hardware Auth
155     /// Token (HAT) has the map key in its challenge field, it gets passed to the TokenReceiver
156     /// and the entry is removed from the map. In the case where no HAT is received before the
157     /// corresponding operation gets dropped, the entry goes stale. So every time the cleanup
158     /// counter (second field in the tuple) turns 0, the map is cleaned from stale entries.
159     /// The cleanup counter is decremented every time a new receiver is added.
160     /// and reset to TokenReceiverMap::CLEANUP_PERIOD + 1 after each cleanup.
161     map_and_cleanup_counter: Mutex<(HashMap<i64, TokenReceiver>, u8)>,
162 }
163 
164 impl Default for TokenReceiverMap {
default() -> Self165     fn default() -> Self {
166         Self { map_and_cleanup_counter: Mutex::new((HashMap::new(), Self::CLEANUP_PERIOD + 1)) }
167     }
168 }
169 
170 impl TokenReceiverMap {
171     /// There is a chance that receivers may become stale because their operation is dropped
172     /// without ever being authorized. So occasionally we iterate through the map and throw
173     /// out obsolete entries.
174     /// This is the number of calls to add_receiver between cleanups.
175     const CLEANUP_PERIOD: u8 = 25;
176 
add_auth_token(&self, hat: HardwareAuthToken)177     pub fn add_auth_token(&self, hat: HardwareAuthToken) {
178         let recv = {
179             // Limit the scope of the mutex guard, so that it is not held while the auth token is
180             // added.
181             let mut map = self.map_and_cleanup_counter.lock().unwrap();
182             let (ref mut map, _) = *map;
183             map.remove_entry(&hat.challenge)
184         };
185 
186         if let Some((_, recv)) = recv {
187             recv.add_auth_token(hat);
188         }
189     }
190 
add_receiver(&self, challenge: i64, recv: TokenReceiver)191     pub fn add_receiver(&self, challenge: i64, recv: TokenReceiver) {
192         let mut map = self.map_and_cleanup_counter.lock().unwrap();
193         let (ref mut map, ref mut cleanup_counter) = *map;
194         map.insert(challenge, recv);
195 
196         *cleanup_counter -= 1;
197         if *cleanup_counter == 0 {
198             map.retain(|_, v| !v.is_obsolete());
199             map.shrink_to_fit();
200             *cleanup_counter = Self::CLEANUP_PERIOD + 1;
201         }
202     }
203 }
204 
205 #[derive(Debug)]
206 struct TokenReceiver(Weak<AuthRequest>);
207 
208 impl TokenReceiver {
is_obsolete(&self) -> bool209     fn is_obsolete(&self) -> bool {
210         self.0.upgrade().is_none()
211     }
212 
add_auth_token(&self, hat: HardwareAuthToken)213     fn add_auth_token(&self, hat: HardwareAuthToken) {
214         if let Some(state_arc) = self.0.upgrade() {
215             state_arc.add_auth_token(hat);
216         }
217     }
218 }
219 
get_timestamp_token(challenge: i64) -> Result<TimeStampToken, Error>220 fn get_timestamp_token(challenge: i64) -> Result<TimeStampToken, Error> {
221     let dev = get_timestamp_service().expect(concat!(
222         "Secure Clock service must be present ",
223         "if TimeStampTokens are required."
224     ));
225     map_binder_status(dev.generateTimeStamp(challenge))
226 }
227 
timestamp_token_request(challenge: i64, sender: Sender<Result<TimeStampToken, Error>>)228 fn timestamp_token_request(challenge: i64, sender: Sender<Result<TimeStampToken, Error>>) {
229     if let Err(e) = sender.send(get_timestamp_token(challenge)) {
230         log::info!(
231             concat!(
232                 "In timestamp_token_request: Receiver hung up ",
233                 "before timestamp token could be delivered. {:?}"
234             ),
235             e
236         );
237     }
238 }
239 
240 impl AuthInfo {
241     /// This function gets called after an operation was successfully created.
242     /// It makes all the preparations required, so that the operation has all the authentication
243     /// related artifacts to advance on update and finish.
finalize_create_authorization(&mut self, challenge: i64) -> Option<OperationChallenge>244     pub fn finalize_create_authorization(&mut self, challenge: i64) -> Option<OperationChallenge> {
245         match &self.state {
246             DeferredAuthState::OpAuthRequired => {
247                 let auth_request = AuthRequest::op_auth();
248                 let token_receiver = TokenReceiver(Arc::downgrade(&auth_request));
249                 ENFORCEMENTS.register_op_auth_receiver(challenge, token_receiver);
250 
251                 self.state = DeferredAuthState::Waiting(auth_request);
252                 Some(OperationChallenge { challenge })
253             }
254             DeferredAuthState::TimeStampedOpAuthRequired => {
255                 let (sender, receiver) = channel::<Result<TimeStampToken, Error>>();
256                 let auth_request = AuthRequest::timestamped_op_auth(receiver);
257                 let token_receiver = TokenReceiver(Arc::downgrade(&auth_request));
258                 ENFORCEMENTS.register_op_auth_receiver(challenge, token_receiver);
259 
260                 ASYNC_TASK.queue_hi(move |_| timestamp_token_request(challenge, sender));
261                 self.state = DeferredAuthState::Waiting(auth_request);
262                 Some(OperationChallenge { challenge })
263             }
264             DeferredAuthState::TimeStampRequired(hat) => {
265                 let hat = (*hat).clone();
266                 let (sender, receiver) = channel::<Result<TimeStampToken, Error>>();
267                 let auth_request = AuthRequest::timestamp(hat, receiver);
268                 ASYNC_TASK.queue_hi(move |_| timestamp_token_request(challenge, sender));
269                 self.state = DeferredAuthState::Waiting(auth_request);
270                 None
271             }
272             _ => None,
273         }
274     }
275 
276     /// This function is the authorization hook called before operation update.
277     /// It returns the auth tokens required by the operation to commence update.
before_update(&mut self) -> Result<(Option<HardwareAuthToken>, Option<TimeStampToken>)>278     pub fn before_update(&mut self) -> Result<(Option<HardwareAuthToken>, Option<TimeStampToken>)> {
279         self.get_auth_tokens()
280     }
281 
282     /// This function is the authorization hook called before operation finish.
283     /// It returns the auth tokens required by the operation to commence finish.
284     /// The third token is a confirmation token.
before_finish( &mut self, ) -> Result<(Option<HardwareAuthToken>, Option<TimeStampToken>, Option<Vec<u8>>)>285     pub fn before_finish(
286         &mut self,
287     ) -> Result<(Option<HardwareAuthToken>, Option<TimeStampToken>, Option<Vec<u8>>)> {
288         let mut confirmation_token: Option<Vec<u8>> = None;
289         if let Some(ref confirmation_token_receiver) = self.confirmation_token_receiver {
290             let locked_receiver = confirmation_token_receiver.lock().unwrap();
291             if let Some(ref receiver) = *locked_receiver {
292                 loop {
293                     match receiver.try_recv() {
294                         // As long as we get tokens we loop and discard all but the most
295                         // recent one.
296                         Ok(t) => confirmation_token = Some(t),
297                         Err(TryRecvError::Empty) => break,
298                         Err(TryRecvError::Disconnected) => {
299                             log::error!(concat!(
300                                 "We got disconnected from the APC service, ",
301                                 "this should never happen."
302                             ));
303                             break;
304                         }
305                     }
306                 }
307             }
308         }
309         self.get_auth_tokens().map(|(hat, tst)| (hat, tst, confirmation_token))
310     }
311 
312     /// This function is the authorization hook called after finish succeeded.
313     /// As of this writing it checks if the key was a limited use key. If so it updates the
314     /// use counter of the key in the database. When the use counter is depleted, the key gets
315     /// marked for deletion and the garbage collector is notified.
after_finish(&self) -> Result<()>316     pub fn after_finish(&self) -> Result<()> {
317         if let Some(key_id) = self.key_usage_limited {
318             // On the last successful use, the key gets deleted. In this case we
319             // have to notify the garbage collector.
320             DB.with(|db| {
321                 db.borrow_mut()
322                     .check_and_update_key_usage_count(key_id)
323                     .context("Trying to update key usage count.")
324             })
325             .context("In after_finish.")?;
326         }
327         Ok(())
328     }
329 
330     /// This function returns the auth tokens as needed by the ongoing operation or fails
331     /// with ErrorCode::KEY_USER_NOT_AUTHENTICATED. If this was called for the first time
332     /// after a deferred authorization was requested by finalize_create_authorization, this
333     /// function may block on the generation of a time stamp token. It then moves the
334     /// tokens into the DeferredAuthState::Token state for future use.
get_auth_tokens(&mut self) -> Result<(Option<HardwareAuthToken>, Option<TimeStampToken>)>335     fn get_auth_tokens(&mut self) -> Result<(Option<HardwareAuthToken>, Option<TimeStampToken>)> {
336         let deferred_tokens = if let DeferredAuthState::Waiting(ref auth_request) = self.state {
337             Some(auth_request.get_auth_tokens().context("In AuthInfo::get_auth_tokens.")?)
338         } else {
339             None
340         };
341 
342         if let Some((hat, tst)) = deferred_tokens {
343             self.state = DeferredAuthState::Token(hat, tst);
344         }
345 
346         match &self.state {
347             DeferredAuthState::NoAuthRequired => Ok((None, None)),
348             DeferredAuthState::Token(hat, tst) => Ok((Some((*hat).clone()), (*tst).clone())),
349             DeferredAuthState::OpAuthRequired
350             | DeferredAuthState::TimeStampedOpAuthRequired
351             | DeferredAuthState::TimeStampRequired(_) => {
352                 Err(Error::Km(ErrorCode::KEY_USER_NOT_AUTHENTICATED)).context(concat!(
353                     "In AuthInfo::get_auth_tokens: No operation auth token requested??? ",
354                     "This should not happen."
355                 ))
356             }
357             // This should not be reachable, because it should have been handled above.
358             DeferredAuthState::Waiting(_) => {
359                 Err(Error::sys()).context("In AuthInfo::get_auth_tokens: Cannot be reached.")
360             }
361         }
362     }
363 }
364 
365 /// Enforcements data structure
366 #[derive(Default)]
367 pub struct Enforcements {
368     /// This hash set contains the user ids for whom the device is currently unlocked. If a user id
369     /// is not in the set, it implies that the device is locked for the user.
370     device_unlocked_set: Mutex<HashSet<i32>>,
371     /// This field maps outstanding auth challenges to their operations. When an auth token
372     /// with the right challenge is received it is passed to the map using
373     /// TokenReceiverMap::add_auth_token() which removes the entry from the map. If an entry goes
374     /// stale, because the operation gets dropped before an auth token is received, the map
375     /// is cleaned up in regular intervals.
376     op_auth_map: TokenReceiverMap,
377     /// The enforcement module will try to get a confirmation token from this channel whenever
378     /// an operation that requires confirmation finishes.
379     confirmation_token_receiver: Arc<Mutex<Option<Receiver<Vec<u8>>>>>,
380 }
381 
382 impl Enforcements {
383     /// Install the confirmation token receiver. The enforcement module will try to get a
384     /// confirmation token from this channel whenever an operation that requires confirmation
385     /// finishes.
install_confirmation_token_receiver( &self, confirmation_token_receiver: Receiver<Vec<u8>>, )386     pub fn install_confirmation_token_receiver(
387         &self,
388         confirmation_token_receiver: Receiver<Vec<u8>>,
389     ) {
390         *self.confirmation_token_receiver.lock().unwrap() = Some(confirmation_token_receiver);
391     }
392 
393     /// Checks if a create call is authorized, given key parameters and operation parameters.
394     /// It returns an optional immediate auth token which can be presented to begin, and an
395     /// AuthInfo object which stays with the authorized operation and is used to obtain
396     /// auth tokens and timestamp tokens as required by the operation.
397     /// With regard to auth tokens, the following steps are taken:
398     ///
399     /// If no key parameters are given (typically when the client is self managed
400     /// (see Domain.Blob)) nothing is enforced.
401     /// If the key is time-bound, find a matching auth token from the database.
402     /// If the above step is successful, and if requires_timestamp is given, the returned
403     /// AuthInfo will provide a Timestamp token as appropriate.
authorize_create( &self, purpose: KeyPurpose, key_properties: Option<&(i64, Vec<KeyParameter>)>, op_params: &[KmKeyParameter], requires_timestamp: bool, ) -> Result<(Option<HardwareAuthToken>, AuthInfo)>404     pub fn authorize_create(
405         &self,
406         purpose: KeyPurpose,
407         key_properties: Option<&(i64, Vec<KeyParameter>)>,
408         op_params: &[KmKeyParameter],
409         requires_timestamp: bool,
410     ) -> Result<(Option<HardwareAuthToken>, AuthInfo)> {
411         let (key_id, key_params) = match key_properties {
412             Some((key_id, key_params)) => (*key_id, key_params),
413             None => {
414                 return Ok((
415                     None,
416                     AuthInfo {
417                         state: DeferredAuthState::NoAuthRequired,
418                         key_usage_limited: None,
419                         confirmation_token_receiver: None,
420                     },
421                 ))
422             }
423         };
424 
425         match purpose {
426             // Allow SIGN, DECRYPT for both symmetric and asymmetric keys.
427             KeyPurpose::SIGN | KeyPurpose::DECRYPT => {}
428             // Rule out WRAP_KEY purpose
429             KeyPurpose::WRAP_KEY => {
430                 return Err(Error::Km(Ec::INCOMPATIBLE_PURPOSE))
431                     .context("In authorize_create: WRAP_KEY purpose is not allowed here.");
432             }
433             // Allow AGREE_KEY for EC keys only.
434             KeyPurpose::AGREE_KEY => {
435                 for kp in key_params.iter() {
436                     if kp.get_tag() == Tag::ALGORITHM
437                         && *kp.key_parameter_value() != KeyParameterValue::Algorithm(Algorithm::EC)
438                     {
439                         return Err(Error::Km(Ec::UNSUPPORTED_PURPOSE)).context(
440                             "In authorize_create: key agreement is only supported for EC keys.",
441                         );
442                     }
443                 }
444             }
445             KeyPurpose::VERIFY | KeyPurpose::ENCRYPT => {
446                 // We do not support ENCRYPT and VERIFY (the remaining two options of purpose) for
447                 // asymmetric keys.
448                 for kp in key_params.iter() {
449                     match *kp.key_parameter_value() {
450                         KeyParameterValue::Algorithm(Algorithm::RSA)
451                         | KeyParameterValue::Algorithm(Algorithm::EC) => {
452                             return Err(Error::Km(Ec::UNSUPPORTED_PURPOSE)).context(
453                                 "In authorize_create: public operations on asymmetric keys are not \
454                                  supported.",
455                             );
456                         }
457                         _ => {}
458                     }
459                 }
460             }
461             _ => {
462                 return Err(Error::Km(Ec::UNSUPPORTED_PURPOSE))
463                     .context("In authorize_create: specified purpose is not supported.");
464             }
465         }
466         // The following variables are to record information from key parameters to be used in
467         // enforcements, when two or more such pieces of information are required for enforcements.
468         // There is only one additional variable than what legacy keystore has, but this helps
469         // reduce the number of for loops on key parameters from 3 to 1, compared to legacy keystore
470         let mut key_purpose_authorized: bool = false;
471         let mut user_auth_type: Option<HardwareAuthenticatorType> = None;
472         let mut no_auth_required: bool = false;
473         let mut caller_nonce_allowed = false;
474         let mut user_id: i32 = -1;
475         let mut user_secure_ids = Vec::<i64>::new();
476         let mut key_time_out: Option<i64> = None;
477         let mut allow_while_on_body = false;
478         let mut unlocked_device_required = false;
479         let mut key_usage_limited: Option<i64> = None;
480         let mut confirmation_token_receiver: Option<Arc<Mutex<Option<Receiver<Vec<u8>>>>>> = None;
481         let mut max_boot_level: Option<i32> = None;
482 
483         // iterate through key parameters, recording information we need for authorization
484         // enforcements later, or enforcing authorizations in place, where applicable
485         for key_param in key_params.iter() {
486             match key_param.key_parameter_value() {
487                 KeyParameterValue::NoAuthRequired => {
488                     no_auth_required = true;
489                 }
490                 KeyParameterValue::AuthTimeout(t) => {
491                     key_time_out = Some(*t as i64);
492                 }
493                 KeyParameterValue::HardwareAuthenticatorType(a) => {
494                     user_auth_type = Some(*a);
495                 }
496                 KeyParameterValue::KeyPurpose(p) => {
497                     // The following check has the effect of key_params.contains(purpose)
498                     // Also, authorizing purpose can not be completed here, if there can be multiple
499                     // key parameters for KeyPurpose.
500                     key_purpose_authorized = key_purpose_authorized || *p == purpose;
501                 }
502                 KeyParameterValue::CallerNonce => {
503                     caller_nonce_allowed = true;
504                 }
505                 KeyParameterValue::ActiveDateTime(a) => {
506                     if !Enforcements::is_given_time_passed(*a, true) {
507                         return Err(Error::Km(Ec::KEY_NOT_YET_VALID))
508                             .context("In authorize_create: key is not yet active.");
509                     }
510                 }
511                 KeyParameterValue::OriginationExpireDateTime(o) => {
512                     if (purpose == KeyPurpose::ENCRYPT || purpose == KeyPurpose::SIGN)
513                         && Enforcements::is_given_time_passed(*o, false)
514                     {
515                         return Err(Error::Km(Ec::KEY_EXPIRED))
516                             .context("In authorize_create: key is expired.");
517                     }
518                 }
519                 KeyParameterValue::UsageExpireDateTime(u) => {
520                     if (purpose == KeyPurpose::DECRYPT || purpose == KeyPurpose::VERIFY)
521                         && Enforcements::is_given_time_passed(*u, false)
522                     {
523                         return Err(Error::Km(Ec::KEY_EXPIRED))
524                             .context("In authorize_create: key is expired.");
525                     }
526                 }
527                 KeyParameterValue::UserSecureID(s) => {
528                     user_secure_ids.push(*s);
529                 }
530                 KeyParameterValue::UserID(u) => {
531                     user_id = *u;
532                 }
533                 KeyParameterValue::UnlockedDeviceRequired => {
534                     unlocked_device_required = true;
535                 }
536                 KeyParameterValue::AllowWhileOnBody => {
537                     allow_while_on_body = true;
538                 }
539                 KeyParameterValue::UsageCountLimit(_) => {
540                     // We don't examine the limit here because this is enforced on finish.
541                     // Instead, we store the key_id so that finish can look up the key
542                     // in the database again and check and update the counter.
543                     key_usage_limited = Some(key_id);
544                 }
545                 KeyParameterValue::TrustedConfirmationRequired => {
546                     confirmation_token_receiver = Some(self.confirmation_token_receiver.clone());
547                 }
548                 KeyParameterValue::MaxBootLevel(level) => {
549                     max_boot_level = Some(*level);
550                 }
551                 // NOTE: as per offline discussion, sanitizing key parameters and rejecting
552                 // create operation if any non-allowed tags are present, is not done in
553                 // authorize_create (unlike in legacy keystore where AuthorizeBegin is rejected if
554                 // a subset of non-allowed tags are present). Because sanitizing key parameters
555                 // should have been done during generate/import key, by KeyMint.
556                 _ => { /*Do nothing on all the other key parameters, as in legacy keystore*/ }
557             }
558         }
559 
560         // authorize the purpose
561         if !key_purpose_authorized {
562             return Err(Error::Km(Ec::INCOMPATIBLE_PURPOSE))
563                 .context("In authorize_create: the purpose is not authorized.");
564         }
565 
566         // if both NO_AUTH_REQUIRED and USER_SECURE_ID tags are present, return error
567         if !user_secure_ids.is_empty() && no_auth_required {
568             return Err(Error::Km(Ec::INVALID_KEY_BLOB)).context(
569                 "In authorize_create: key has both NO_AUTH_REQUIRED and USER_SECURE_ID tags.",
570             );
571         }
572 
573         // if either of auth_type or secure_id is present and the other is not present, return error
574         if (user_auth_type.is_some() && user_secure_ids.is_empty())
575             || (user_auth_type.is_none() && !user_secure_ids.is_empty())
576         {
577             return Err(Error::Km(Ec::KEY_USER_NOT_AUTHENTICATED)).context(
578                 "In authorize_create: Auth required, but either auth type or secure ids \
579                  are not present.",
580             );
581         }
582 
583         // validate caller nonce for origination purposes
584         if (purpose == KeyPurpose::ENCRYPT || purpose == KeyPurpose::SIGN)
585             && !caller_nonce_allowed
586             && op_params.iter().any(|kp| kp.tag == Tag::NONCE)
587         {
588             return Err(Error::Km(Ec::CALLER_NONCE_PROHIBITED)).context(
589                 "In authorize_create, NONCE is present, although CALLER_NONCE is not present",
590             );
591         }
592 
593         if unlocked_device_required {
594             // check the device locked status. If locked, operations on the key are not
595             // allowed.
596             if self.is_device_locked(user_id) {
597                 return Err(Error::Km(Ec::DEVICE_LOCKED))
598                     .context("In authorize_create: device is locked.");
599             }
600         }
601 
602         if let Some(level) = max_boot_level {
603             if !SUPER_KEY.read().unwrap().level_accessible(level) {
604                 return Err(Error::Km(Ec::BOOT_LEVEL_EXCEEDED))
605                     .context("In authorize_create: boot level is too late.");
606             }
607         }
608 
609         if !unlocked_device_required && no_auth_required {
610             return Ok((
611                 None,
612                 AuthInfo {
613                     state: DeferredAuthState::NoAuthRequired,
614                     key_usage_limited,
615                     confirmation_token_receiver,
616                 },
617             ));
618         }
619 
620         let has_sids = !user_secure_ids.is_empty();
621 
622         let timeout_bound = key_time_out.is_some() && has_sids;
623 
624         let per_op_bound = key_time_out.is_none() && has_sids;
625 
626         let need_auth_token = timeout_bound || unlocked_device_required;
627 
628         let hat_and_last_off_body = if need_auth_token {
629             let hat_and_last_off_body = Self::find_auth_token(|hat: &AuthTokenEntry| {
630                 if let (Some(auth_type), true) = (user_auth_type, timeout_bound) {
631                     hat.satisfies(&user_secure_ids, auth_type)
632                 } else {
633                     unlocked_device_required
634                 }
635             });
636             Some(
637                 hat_and_last_off_body
638                     .ok_or(Error::Km(Ec::KEY_USER_NOT_AUTHENTICATED))
639                     .context("In authorize_create: No suitable auth token found.")?,
640             )
641         } else {
642             None
643         };
644 
645         // Now check the validity of the auth token if the key is timeout bound.
646         let hat = match (hat_and_last_off_body, key_time_out) {
647             (Some((hat, last_off_body)), Some(key_time_out)) => {
648                 let now = MonotonicRawTime::now();
649                 let token_age = now
650                     .checked_sub(&hat.time_received())
651                     .ok_or_else(Error::sys)
652                     .context(concat!(
653                         "In authorize_create: Overflow while computing Auth token validity. ",
654                         "Validity cannot be established."
655                     ))?;
656 
657                 let on_body_extended = allow_while_on_body && last_off_body < hat.time_received();
658 
659                 if token_age.seconds() > key_time_out && !on_body_extended {
660                     return Err(Error::Km(Ec::KEY_USER_NOT_AUTHENTICATED))
661                         .context("In authorize_create: matching auth token is expired.");
662                 }
663                 Some(hat)
664             }
665             (Some((hat, _)), None) => Some(hat),
666             // If timeout_bound is true, above code must have retrieved a HAT or returned with
667             // KEY_USER_NOT_AUTHENTICATED. This arm should not be reachable.
668             (None, Some(_)) => panic!("Logical error."),
669             _ => None,
670         };
671 
672         Ok(match (hat, requires_timestamp, per_op_bound) {
673             // Per-op-bound and Some(hat) can only happen if we are both per-op bound and unlocked
674             // device required. In addition, this KM instance needs a timestamp token.
675             // So the HAT cannot be presented on create. So on update/finish we present both
676             // an per-op-bound auth token and a timestamp token.
677             (Some(_), true, true) => (None, DeferredAuthState::TimeStampedOpAuthRequired),
678             (Some(hat), true, false) => (
679                 Some(hat.auth_token().clone()),
680                 DeferredAuthState::TimeStampRequired(hat.take_auth_token()),
681             ),
682             (Some(hat), false, true) => {
683                 (Some(hat.take_auth_token()), DeferredAuthState::OpAuthRequired)
684             }
685             (Some(hat), false, false) => {
686                 (Some(hat.take_auth_token()), DeferredAuthState::NoAuthRequired)
687             }
688             (None, _, true) => (None, DeferredAuthState::OpAuthRequired),
689             (None, _, false) => (None, DeferredAuthState::NoAuthRequired),
690         })
691         .map(|(hat, state)| {
692             (hat, AuthInfo { state, key_usage_limited, confirmation_token_receiver })
693         })
694     }
695 
find_auth_token<F>(p: F) -> Option<(AuthTokenEntry, MonotonicRawTime)> where F: Fn(&AuthTokenEntry) -> bool,696     fn find_auth_token<F>(p: F) -> Option<(AuthTokenEntry, MonotonicRawTime)>
697     where
698         F: Fn(&AuthTokenEntry) -> bool,
699     {
700         DB.with(|db| db.borrow().find_auth_token_entry(p))
701     }
702 
703     /// Checks if the time now since epoch is greater than (or equal, if is_given_time_inclusive is
704     /// set) the given time (in milliseconds)
is_given_time_passed(given_time: i64, is_given_time_inclusive: bool) -> bool705     fn is_given_time_passed(given_time: i64, is_given_time_inclusive: bool) -> bool {
706         let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH);
707 
708         let time_since_epoch = match duration_since_epoch {
709             Ok(duration) => duration.as_millis(),
710             Err(_) => return false,
711         };
712 
713         if is_given_time_inclusive {
714             time_since_epoch >= (given_time as u128)
715         } else {
716             time_since_epoch > (given_time as u128)
717         }
718     }
719 
720     /// Check if the device is locked for the given user. If there's no entry yet for the user,
721     /// we assume that the device is locked
is_device_locked(&self, user_id: i32) -> bool722     fn is_device_locked(&self, user_id: i32) -> bool {
723         // unwrap here because there's no way this mutex guard can be poisoned and
724         // because there's no way to recover, even if it is poisoned.
725         let set = self.device_unlocked_set.lock().unwrap();
726         !set.contains(&user_id)
727     }
728 
729     /// Sets the device locked status for the user. This method is called externally.
set_device_locked(&self, user_id: i32, device_locked_status: bool)730     pub fn set_device_locked(&self, user_id: i32, device_locked_status: bool) {
731         // unwrap here because there's no way this mutex guard can be poisoned and
732         // because there's no way to recover, even if it is poisoned.
733         let mut set = self.device_unlocked_set.lock().unwrap();
734         if device_locked_status {
735             set.remove(&user_id);
736         } else {
737             set.insert(user_id);
738         }
739     }
740 
741     /// Add this auth token to the database.
742     /// Then present the auth token to the op auth map. If an operation is waiting for this
743     /// auth token this fulfills the request and removes the receiver from the map.
add_auth_token(&self, hat: HardwareAuthToken)744     pub fn add_auth_token(&self, hat: HardwareAuthToken) {
745         DB.with(|db| db.borrow_mut().insert_auth_token(&hat));
746         self.op_auth_map.add_auth_token(hat);
747     }
748 
749     /// This allows adding an entry to the op_auth_map, indexed by the operation challenge.
750     /// This is to be called by create_operation, once it has received the operation challenge
751     /// from keymint for an operation whose authorization decision is OpAuthRequired, as signalled
752     /// by the DeferredAuthState.
register_op_auth_receiver(&self, challenge: i64, recv: TokenReceiver)753     fn register_op_auth_receiver(&self, challenge: i64, recv: TokenReceiver) {
754         self.op_auth_map.add_receiver(challenge, recv);
755     }
756 
757     /// Given the set of key parameters and flags, check if super encryption is required.
super_encryption_required( domain: &Domain, key_parameters: &[KeyParameter], flags: Option<i32>, ) -> SuperEncryptionType758     pub fn super_encryption_required(
759         domain: &Domain,
760         key_parameters: &[KeyParameter],
761         flags: Option<i32>,
762     ) -> SuperEncryptionType {
763         if let Some(flags) = flags {
764             if (flags & KEY_FLAG_AUTH_BOUND_WITHOUT_CRYPTOGRAPHIC_LSKF_BINDING) != 0 {
765                 return SuperEncryptionType::None;
766             }
767         }
768         // Each answer has a priority, numerically largest priority wins.
769         struct Candidate {
770             priority: u32,
771             enc_type: SuperEncryptionType,
772         }
773         let mut result = Candidate { priority: 0, enc_type: SuperEncryptionType::None };
774         for kp in key_parameters {
775             let t = match kp.key_parameter_value() {
776                 KeyParameterValue::MaxBootLevel(level) => {
777                     Candidate { priority: 3, enc_type: SuperEncryptionType::BootLevel(*level) }
778                 }
779                 KeyParameterValue::UnlockedDeviceRequired if *domain == Domain::APP => {
780                     Candidate { priority: 2, enc_type: SuperEncryptionType::ScreenLockBound }
781                 }
782                 KeyParameterValue::UserSecureID(_) if *domain == Domain::APP => {
783                     Candidate { priority: 1, enc_type: SuperEncryptionType::LskfBound }
784                 }
785                 _ => Candidate { priority: 0, enc_type: SuperEncryptionType::None },
786             };
787             if t.priority > result.priority {
788                 result = t;
789             }
790         }
791         result.enc_type
792     }
793 
794     /// Finds a matching auth token along with a timestamp token.
795     /// This method looks through auth-tokens cached by keystore which satisfy the given
796     /// authentication information (i.e. |secureUserId|).
797     /// The most recent matching auth token which has a |challenge| field which matches
798     /// the passed-in |challenge| parameter is returned.
799     /// In this case the |authTokenMaxAgeMillis| parameter is not used.
800     ///
801     /// Otherwise, the most recent matching auth token which is younger than |authTokenMaxAgeMillis|
802     /// is returned.
get_auth_tokens( &self, challenge: i64, secure_user_id: i64, auth_token_max_age_millis: i64, ) -> Result<(HardwareAuthToken, TimeStampToken)>803     pub fn get_auth_tokens(
804         &self,
805         challenge: i64,
806         secure_user_id: i64,
807         auth_token_max_age_millis: i64,
808     ) -> Result<(HardwareAuthToken, TimeStampToken)> {
809         let auth_type = HardwareAuthenticatorType::ANY;
810         let sids: Vec<i64> = vec![secure_user_id];
811         // Filter the matching auth tokens by challenge
812         let result = Self::find_auth_token(|hat: &AuthTokenEntry| {
813             (challenge == hat.challenge()) && hat.satisfies(&sids, auth_type)
814         });
815 
816         let auth_token = if let Some((auth_token_entry, _)) = result {
817             auth_token_entry.take_auth_token()
818         } else {
819             // Filter the matching auth tokens by age.
820             if auth_token_max_age_millis != 0 {
821                 let now_in_millis = MonotonicRawTime::now();
822                 let result = Self::find_auth_token(|auth_token_entry: &AuthTokenEntry| {
823                     let token_valid = now_in_millis
824                         .checked_sub(&auth_token_entry.time_received())
825                         .map_or(false, |token_age_in_millis| {
826                             auth_token_max_age_millis > token_age_in_millis.milliseconds()
827                         });
828                     token_valid && auth_token_entry.satisfies(&sids, auth_type)
829                 });
830 
831                 if let Some((auth_token_entry, _)) = result {
832                     auth_token_entry.take_auth_token()
833                 } else {
834                     return Err(AuthzError::Rc(AuthzResponseCode::NO_AUTH_TOKEN_FOUND))
835                         .context("In get_auth_tokens: No auth token found.");
836                 }
837             } else {
838                 return Err(AuthzError::Rc(AuthzResponseCode::NO_AUTH_TOKEN_FOUND)).context(
839                     concat!(
840                         "In get_auth_tokens: No auth token found for ",
841                         "the given challenge and passed-in auth token max age is zero."
842                     ),
843                 );
844             }
845         };
846         // Wait and obtain the timestamp token from secure clock service.
847         let tst = get_timestamp_token(challenge)
848             .context("In get_auth_tokens. Error in getting timestamp token.")?;
849         Ok((auth_token, tst))
850     }
851 }
852 
853 // TODO: Add tests to enforcement module (b/175578618).
854