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