1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define LOG_TAG "keystore" 18 19 #include "keymaster_enforcement.h" 20 21 #include <assert.h> 22 #include <inttypes.h> 23 #include <limits.h> 24 #include <string.h> 25 26 #include <openssl/evp.h> 27 28 #include <cutils/log.h> 29 #include <hardware/hw_auth_token.h> 30 #include <list> 31 32 #include <keystore/keystore_hidl_support.h> 33 34 namespace keystore { 35 36 class AccessTimeMap { 37 public: 38 explicit AccessTimeMap(uint32_t max_size) : max_size_(max_size) {} 39 40 /* If the key is found, returns true and fills \p last_access_time. If not found returns 41 * false. */ 42 bool LastKeyAccessTime(km_id_t keyid, uint32_t* last_access_time) const; 43 44 /* Updates the last key access time with the currentTime parameter. Adds the key if 45 * needed, returning false if key cannot be added because list is full. */ 46 bool UpdateKeyAccessTime(km_id_t keyid, uint32_t current_time, uint32_t timeout); 47 48 private: 49 struct AccessTime { 50 km_id_t keyid; 51 uint32_t access_time; 52 uint32_t timeout; 53 }; 54 std::list<AccessTime> last_access_list_; 55 const uint32_t max_size_; 56 }; 57 58 class AccessCountMap { 59 public: 60 explicit AccessCountMap(uint32_t max_size) : max_size_(max_size) {} 61 62 /* If the key is found, returns true and fills \p count. If not found returns 63 * false. */ 64 bool KeyAccessCount(km_id_t keyid, uint32_t* count) const; 65 66 /* Increments key access count, adding an entry if the key has never been used. Returns 67 * false if the list has reached maximum size. */ 68 bool IncrementKeyAccessCount(km_id_t keyid); 69 70 private: 71 struct AccessCount { 72 km_id_t keyid; 73 uint64_t access_count; 74 }; 75 std::list<AccessCount> access_count_list_; 76 const uint32_t max_size_; 77 }; 78 79 bool is_public_key_algorithm(const AuthorizationSet& auth_set) { 80 auto algorithm = auth_set.GetTagValue(TAG_ALGORITHM); 81 return algorithm.isOk() && 82 (algorithm.value() == Algorithm::RSA || algorithm.value() == Algorithm::EC); 83 } 84 85 static ErrorCode authorized_purpose(const KeyPurpose purpose, const AuthorizationSet& auth_set) { 86 switch (purpose) { 87 case KeyPurpose::VERIFY: 88 case KeyPurpose::ENCRYPT: 89 case KeyPurpose::SIGN: 90 case KeyPurpose::DECRYPT: 91 if (auth_set.Contains(TAG_PURPOSE, purpose)) return ErrorCode::OK; 92 return ErrorCode::INCOMPATIBLE_PURPOSE; 93 94 default: 95 return ErrorCode::UNSUPPORTED_PURPOSE; 96 } 97 } 98 99 inline bool is_origination_purpose(KeyPurpose purpose) { 100 return purpose == KeyPurpose::ENCRYPT || purpose == KeyPurpose::SIGN; 101 } 102 103 inline bool is_usage_purpose(KeyPurpose purpose) { 104 return purpose == KeyPurpose::DECRYPT || purpose == KeyPurpose::VERIFY; 105 } 106 107 KeymasterEnforcement::KeymasterEnforcement(uint32_t max_access_time_map_size, 108 uint32_t max_access_count_map_size) 109 : access_time_map_(new (std::nothrow) AccessTimeMap(max_access_time_map_size)), 110 access_count_map_(new (std::nothrow) AccessCountMap(max_access_count_map_size)) {} 111 112 KeymasterEnforcement::~KeymasterEnforcement() { 113 delete access_time_map_; 114 delete access_count_map_; 115 } 116 117 ErrorCode KeymasterEnforcement::AuthorizeOperation(const KeyPurpose purpose, const km_id_t keyid, 118 const AuthorizationSet& auth_set, 119 const AuthorizationSet& operation_params, 120 const HardwareAuthToken& auth_token, 121 uint64_t op_handle, bool is_begin_operation) { 122 if (is_public_key_algorithm(auth_set)) { 123 switch (purpose) { 124 case KeyPurpose::ENCRYPT: 125 case KeyPurpose::VERIFY: 126 /* Public key operations are always authorized. */ 127 return ErrorCode::OK; 128 129 case KeyPurpose::DECRYPT: 130 case KeyPurpose::SIGN: 131 break; 132 133 case KeyPurpose::WRAP_KEY: 134 return ErrorCode::INCOMPATIBLE_PURPOSE; 135 }; 136 }; 137 138 if (is_begin_operation) 139 return AuthorizeBegin(purpose, keyid, auth_set, operation_params, auth_token); 140 else 141 return AuthorizeUpdateOrFinish(auth_set, auth_token, op_handle); 142 } 143 144 // For update and finish the only thing to check is user authentication, and then only if it's not 145 // timeout-based. 146 ErrorCode KeymasterEnforcement::AuthorizeUpdateOrFinish(const AuthorizationSet& auth_set, 147 const HardwareAuthToken& auth_token, 148 uint64_t op_handle) { 149 int auth_type_index = -1; 150 for (size_t pos = 0; pos < auth_set.size(); ++pos) { 151 switch (auth_set[pos].tag) { 152 case Tag::NO_AUTH_REQUIRED: 153 case Tag::AUTH_TIMEOUT: 154 // If no auth is required or if auth is timeout-based, we have nothing to check. 155 return ErrorCode::OK; 156 157 case Tag::USER_AUTH_TYPE: 158 auth_type_index = pos; 159 break; 160 161 default: 162 break; 163 } 164 } 165 166 // Note that at this point we should be able to assume that authentication is required, because 167 // authentication is required if KM_TAG_NO_AUTH_REQUIRED is absent. However, there are legacy 168 // keys which have no authentication-related tags, so we assume that absence is equivalent to 169 // presence of KM_TAG_NO_AUTH_REQUIRED. 170 // 171 // So, if we found KM_TAG_USER_AUTH_TYPE or if we find KM_TAG_USER_SECURE_ID then authentication 172 // is required. If we find neither, then we assume authentication is not required and return 173 // success. 174 bool authentication_required = (auth_type_index != -1); 175 for (auto& param : auth_set) { 176 auto user_secure_id = authorizationValue(TAG_USER_SECURE_ID, param); 177 if (user_secure_id.isOk()) { 178 authentication_required = true; 179 int auth_timeout_index = -1; 180 if (auth_token.mac.size() && 181 AuthTokenMatches(auth_set, auth_token, user_secure_id.value(), auth_type_index, 182 auth_timeout_index, op_handle, false /* is_begin_operation */)) 183 return ErrorCode::OK; 184 } 185 } 186 187 if (authentication_required) return ErrorCode::KEY_USER_NOT_AUTHENTICATED; 188 189 return ErrorCode::OK; 190 } 191 192 ErrorCode KeymasterEnforcement::AuthorizeBegin(const KeyPurpose purpose, const km_id_t keyid, 193 const AuthorizationSet& auth_set, 194 const AuthorizationSet& operation_params, 195 NullOr<const HardwareAuthToken&> auth_token) { 196 // Find some entries that may be needed to handle KM_TAG_USER_SECURE_ID 197 int auth_timeout_index = -1; 198 int auth_type_index = -1; 199 int no_auth_required_index = -1; 200 for (size_t pos = 0; pos < auth_set.size(); ++pos) { 201 switch (auth_set[pos].tag) { 202 case Tag::AUTH_TIMEOUT: 203 auth_timeout_index = pos; 204 break; 205 case Tag::USER_AUTH_TYPE: 206 auth_type_index = pos; 207 break; 208 case Tag::NO_AUTH_REQUIRED: 209 no_auth_required_index = pos; 210 break; 211 default: 212 break; 213 } 214 } 215 216 ErrorCode error = authorized_purpose(purpose, auth_set); 217 if (error != ErrorCode::OK) return error; 218 219 // If successful, and if key has a min time between ops, this will be set to the time limit 220 uint32_t min_ops_timeout = UINT32_MAX; 221 222 bool update_access_count = false; 223 bool caller_nonce_authorized_by_key = false; 224 bool authentication_required = false; 225 bool auth_token_matched = false; 226 bool unlocked_device_required = false; 227 int32_t user_id = -1; 228 229 for (auto& param : auth_set) { 230 231 // KM_TAG_PADDING_OLD and KM_TAG_DIGEST_OLD aren't actually members of the enum, so we can't 232 // switch on them. There's nothing to validate for them, though, so just ignore them. 233 if (int32_t(param.tag) == KM_TAG_PADDING_OLD || int32_t(param.tag) == KM_TAG_DIGEST_OLD) 234 continue; 235 236 switch (param.tag) { 237 238 case Tag::ACTIVE_DATETIME: { 239 auto date = authorizationValue(TAG_ACTIVE_DATETIME, param); 240 if (date.isOk() && !activation_date_valid(date.value())) 241 return ErrorCode::KEY_NOT_YET_VALID; 242 break; 243 } 244 case Tag::ORIGINATION_EXPIRE_DATETIME: { 245 auto date = authorizationValue(TAG_ORIGINATION_EXPIRE_DATETIME, param); 246 if (is_origination_purpose(purpose) && date.isOk() && 247 expiration_date_passed(date.value())) 248 return ErrorCode::KEY_EXPIRED; 249 break; 250 } 251 case Tag::USAGE_EXPIRE_DATETIME: { 252 auto date = authorizationValue(TAG_USAGE_EXPIRE_DATETIME, param); 253 if (is_usage_purpose(purpose) && date.isOk() && expiration_date_passed(date.value())) 254 return ErrorCode::KEY_EXPIRED; 255 break; 256 } 257 case Tag::MIN_SECONDS_BETWEEN_OPS: { 258 auto min_ops_timeout = authorizationValue(TAG_MIN_SECONDS_BETWEEN_OPS, param); 259 if (min_ops_timeout.isOk() && !MinTimeBetweenOpsPassed(min_ops_timeout.value(), keyid)) 260 return ErrorCode::KEY_RATE_LIMIT_EXCEEDED; 261 break; 262 } 263 case Tag::MAX_USES_PER_BOOT: { 264 auto max_users = authorizationValue(TAG_MAX_USES_PER_BOOT, param); 265 update_access_count = true; 266 if (max_users.isOk() && !MaxUsesPerBootNotExceeded(keyid, max_users.value())) 267 return ErrorCode::KEY_MAX_OPS_EXCEEDED; 268 break; 269 } 270 case Tag::USER_SECURE_ID: 271 if (no_auth_required_index != -1) { 272 // Key has both KM_TAG_USER_SECURE_ID and KM_TAG_NO_AUTH_REQUIRED 273 return ErrorCode::INVALID_KEY_BLOB; 274 } 275 276 if (auth_timeout_index != -1) { 277 auto secure_id = authorizationValue(TAG_USER_SECURE_ID, param); 278 authentication_required = true; 279 if (secure_id.isOk() && auth_token.isOk() && 280 AuthTokenMatches(auth_set, auth_token.value(), secure_id.value(), 281 auth_type_index, auth_timeout_index, 0 /* op_handle */, 282 true /* is_begin_operation */)) 283 auth_token_matched = true; 284 } 285 break; 286 287 case Tag::USER_ID: 288 user_id = authorizationValue(TAG_USER_ID, param).value(); 289 break; 290 291 case Tag::CALLER_NONCE: 292 caller_nonce_authorized_by_key = true; 293 break; 294 295 case Tag::UNLOCKED_DEVICE_REQUIRED: 296 unlocked_device_required = true; 297 break; 298 299 /* Tags should never be in key auths. */ 300 case Tag::INVALID: 301 case Tag::ROOT_OF_TRUST: 302 case Tag::APPLICATION_DATA: 303 case Tag::ATTESTATION_CHALLENGE: 304 case Tag::ATTESTATION_APPLICATION_ID: 305 case Tag::ATTESTATION_ID_BRAND: 306 case Tag::ATTESTATION_ID_DEVICE: 307 case Tag::ATTESTATION_ID_PRODUCT: 308 case Tag::ATTESTATION_ID_SERIAL: 309 case Tag::ATTESTATION_ID_IMEI: 310 case Tag::ATTESTATION_ID_MEID: 311 case Tag::ATTESTATION_ID_MANUFACTURER: 312 case Tag::ATTESTATION_ID_MODEL: 313 return ErrorCode::INVALID_KEY_BLOB; 314 315 /* Tags used for cryptographic parameters in keygen. Nothing to enforce. */ 316 case Tag::PURPOSE: 317 case Tag::ALGORITHM: 318 case Tag::KEY_SIZE: 319 case Tag::BLOCK_MODE: 320 case Tag::DIGEST: 321 case Tag::MAC_LENGTH: 322 case Tag::PADDING: 323 case Tag::NONCE: 324 case Tag::MIN_MAC_LENGTH: 325 case Tag::EC_CURVE: 326 327 /* Tags not used for operations. */ 328 case Tag::BLOB_USAGE_REQUIREMENTS: 329 330 /* Algorithm specific parameters not used for access control. */ 331 case Tag::RSA_PUBLIC_EXPONENT: 332 333 /* Informational tags. */ 334 case Tag::CREATION_DATETIME: 335 case Tag::ORIGIN: 336 case Tag::ROLLBACK_RESISTANCE: 337 338 /* Tags handled when KM_TAG_USER_SECURE_ID is handled */ 339 case Tag::NO_AUTH_REQUIRED: 340 case Tag::USER_AUTH_TYPE: 341 case Tag::AUTH_TIMEOUT: 342 343 /* Tag to provide data to operations. */ 344 case Tag::ASSOCIATED_DATA: 345 346 /* Tags that are implicitly verified by secure side */ 347 case Tag::APPLICATION_ID: 348 case Tag::BOOT_PATCHLEVEL: 349 case Tag::OS_PATCHLEVEL: 350 case Tag::OS_VERSION: 351 case Tag::TRUSTED_USER_PRESENCE_REQUIRED: 352 case Tag::VENDOR_PATCHLEVEL: 353 354 /* TODO(swillden): Handle these */ 355 case Tag::INCLUDE_UNIQUE_ID: 356 case Tag::UNIQUE_ID: 357 case Tag::RESET_SINCE_ID_ROTATION: 358 case Tag::ALLOW_WHILE_ON_BODY: 359 case Tag::HARDWARE_TYPE: 360 case Tag::TRUSTED_CONFIRMATION_REQUIRED: 361 case Tag::CONFIRMATION_TOKEN: 362 break; 363 364 case Tag::BOOTLOADER_ONLY: 365 return ErrorCode::INVALID_KEY_BLOB; 366 } 367 } 368 369 if (unlocked_device_required && is_device_locked(user_id)) { 370 switch (purpose) { 371 case KeyPurpose::ENCRYPT: 372 case KeyPurpose::VERIFY: 373 /* These are okay */ 374 break; 375 case KeyPurpose::DECRYPT: 376 case KeyPurpose::SIGN: 377 case KeyPurpose::WRAP_KEY: 378 return ErrorCode::DEVICE_LOCKED; 379 }; 380 } 381 382 if (authentication_required && !auth_token_matched) { 383 ALOGE("Auth required but no matching auth token found"); 384 return ErrorCode::KEY_USER_NOT_AUTHENTICATED; 385 } 386 387 if (!caller_nonce_authorized_by_key && is_origination_purpose(purpose) && 388 operation_params.Contains(Tag::NONCE)) 389 return ErrorCode::CALLER_NONCE_PROHIBITED; 390 391 if (min_ops_timeout != UINT32_MAX) { 392 if (!access_time_map_) { 393 ALOGE("Rate-limited keys table not allocated. Rate-limited keys disabled"); 394 return ErrorCode::MEMORY_ALLOCATION_FAILED; 395 } 396 397 if (!access_time_map_->UpdateKeyAccessTime(keyid, get_current_time(), min_ops_timeout)) { 398 ALOGE("Rate-limited keys table full. Entries will time out."); 399 return ErrorCode::TOO_MANY_OPERATIONS; 400 } 401 } 402 403 if (update_access_count) { 404 if (!access_count_map_) { 405 ALOGE("Usage-count limited keys tabel not allocated. Count-limited keys disabled"); 406 return ErrorCode::MEMORY_ALLOCATION_FAILED; 407 } 408 409 if (!access_count_map_->IncrementKeyAccessCount(keyid)) { 410 ALOGE("Usage count-limited keys table full, until reboot."); 411 return ErrorCode::TOO_MANY_OPERATIONS; 412 } 413 } 414 415 return ErrorCode::OK; 416 } 417 418 class EvpMdCtx { 419 public: 420 EvpMdCtx() { EVP_MD_CTX_init(&ctx_); } 421 ~EvpMdCtx() { EVP_MD_CTX_cleanup(&ctx_); } 422 423 EVP_MD_CTX* get() { return &ctx_; } 424 425 private: 426 EVP_MD_CTX ctx_; 427 }; 428 429 /* static */ 430 bool KeymasterEnforcement::CreateKeyId(const hidl_vec<uint8_t>& key_blob, km_id_t* keyid) { 431 EvpMdCtx ctx; 432 433 uint8_t hash[EVP_MAX_MD_SIZE]; 434 unsigned int hash_len; 435 if (EVP_DigestInit_ex(ctx.get(), EVP_sha256(), nullptr /* ENGINE */) && 436 EVP_DigestUpdate(ctx.get(), &key_blob[0], key_blob.size()) && 437 EVP_DigestFinal_ex(ctx.get(), hash, &hash_len)) { 438 assert(hash_len >= sizeof(*keyid)); 439 memcpy(keyid, hash, sizeof(*keyid)); 440 return true; 441 } 442 443 return false; 444 } 445 446 bool KeymasterEnforcement::MinTimeBetweenOpsPassed(uint32_t min_time_between, const km_id_t keyid) { 447 if (!access_time_map_) return false; 448 449 uint32_t last_access_time; 450 if (!access_time_map_->LastKeyAccessTime(keyid, &last_access_time)) return true; 451 return min_time_between <= static_cast<int64_t>(get_current_time()) - last_access_time; 452 } 453 454 bool KeymasterEnforcement::MaxUsesPerBootNotExceeded(const km_id_t keyid, uint32_t max_uses) { 455 if (!access_count_map_) return false; 456 457 uint32_t key_access_count; 458 if (!access_count_map_->KeyAccessCount(keyid, &key_access_count)) return true; 459 return key_access_count < max_uses; 460 } 461 462 template <typename IntType, uint32_t byteOrder> struct choose_hton; 463 464 template <typename IntType> struct choose_hton<IntType, __ORDER_LITTLE_ENDIAN__> { 465 inline static IntType hton(const IntType& value) { 466 IntType result = 0; 467 const unsigned char* inbytes = reinterpret_cast<const unsigned char*>(&value); 468 unsigned char* outbytes = reinterpret_cast<unsigned char*>(&result); 469 for (int i = sizeof(IntType) - 1; i >= 0; --i) { 470 *(outbytes++) = inbytes[i]; 471 } 472 return result; 473 } 474 }; 475 476 template <typename IntType> struct choose_hton<IntType, __ORDER_BIG_ENDIAN__> { 477 inline static IntType hton(const IntType& value) { return value; } 478 }; 479 480 template <typename IntType> inline IntType hton(const IntType& value) { 481 return choose_hton<IntType, __BYTE_ORDER__>::hton(value); 482 } 483 484 template <typename IntType> inline IntType ntoh(const IntType& value) { 485 // same operation and hton 486 return choose_hton<IntType, __BYTE_ORDER__>::hton(value); 487 } 488 489 bool KeymasterEnforcement::AuthTokenMatches(const AuthorizationSet& auth_set, 490 const HardwareAuthToken& auth_token, 491 const uint64_t user_secure_id, 492 const int auth_type_index, const int auth_timeout_index, 493 const uint64_t op_handle, 494 bool is_begin_operation) const { 495 assert(auth_type_index < static_cast<int>(auth_set.size())); 496 assert(auth_timeout_index < static_cast<int>(auth_set.size())); 497 498 if (!ValidateTokenSignature(auth_token)) { 499 ALOGE("Auth token signature invalid"); 500 return false; 501 } 502 503 if (auth_timeout_index == -1 && op_handle && op_handle != auth_token.challenge) { 504 ALOGE("Auth token has the challenge %" PRIu64 ", need %" PRIu64, auth_token.challenge, 505 op_handle); 506 return false; 507 } 508 509 if (user_secure_id != auth_token.userId && user_secure_id != auth_token.authenticatorId) { 510 ALOGI("Auth token SIDs %" PRIu64 " and %" PRIu64 " do not match key SID %" PRIu64, 511 auth_token.userId, auth_token.authenticatorId, user_secure_id); 512 return false; 513 } 514 515 if (auth_type_index < 0 || auth_type_index > static_cast<int>(auth_set.size())) { 516 ALOGE("Auth required but no auth type found"); 517 return false; 518 } 519 520 assert(auth_set[auth_type_index].tag == TAG_USER_AUTH_TYPE); 521 auto key_auth_type_mask = authorizationValue(TAG_USER_AUTH_TYPE, auth_set[auth_type_index]); 522 if (!key_auth_type_mask.isOk()) return false; 523 524 if ((uint32_t(key_auth_type_mask.value()) & auth_token.authenticatorType) == 0) { 525 ALOGE("Key requires match of auth type mask 0%uo, but token contained 0%uo", 526 key_auth_type_mask.value(), auth_token.authenticatorType); 527 return false; 528 } 529 530 if (auth_timeout_index != -1 && is_begin_operation) { 531 assert(auth_set[auth_timeout_index].tag == TAG_AUTH_TIMEOUT); 532 auto auth_token_timeout = 533 authorizationValue(TAG_AUTH_TIMEOUT, auth_set[auth_timeout_index]); 534 if (!auth_token_timeout.isOk()) return false; 535 536 if (auth_token_timed_out(auth_token, auth_token_timeout.value())) { 537 ALOGE("Auth token has timed out"); 538 return false; 539 } 540 } 541 542 // Survived the whole gauntlet. We have authentage! 543 return true; 544 } 545 546 bool AccessTimeMap::LastKeyAccessTime(km_id_t keyid, uint32_t* last_access_time) const { 547 for (auto& entry : last_access_list_) 548 if (entry.keyid == keyid) { 549 *last_access_time = entry.access_time; 550 return true; 551 } 552 return false; 553 } 554 555 bool AccessTimeMap::UpdateKeyAccessTime(km_id_t keyid, uint32_t current_time, uint32_t timeout) { 556 for (auto iter = last_access_list_.begin(); iter != last_access_list_.end();) { 557 if (iter->keyid == keyid) { 558 iter->access_time = current_time; 559 return true; 560 } 561 562 // Expire entry if possible. 563 assert(current_time >= iter->access_time); 564 if (current_time - iter->access_time >= iter->timeout) 565 iter = last_access_list_.erase(iter); 566 else 567 ++iter; 568 } 569 570 if (last_access_list_.size() >= max_size_) return false; 571 572 AccessTime new_entry; 573 new_entry.keyid = keyid; 574 new_entry.access_time = current_time; 575 new_entry.timeout = timeout; 576 last_access_list_.push_front(new_entry); 577 return true; 578 } 579 580 bool AccessCountMap::KeyAccessCount(km_id_t keyid, uint32_t* count) const { 581 for (auto& entry : access_count_list_) 582 if (entry.keyid == keyid) { 583 *count = entry.access_count; 584 return true; 585 } 586 return false; 587 } 588 589 bool AccessCountMap::IncrementKeyAccessCount(km_id_t keyid) { 590 for (auto& entry : access_count_list_) 591 if (entry.keyid == keyid) { 592 // Note that the 'if' below will always be true because KM_TAG_MAX_USES_PER_BOOT is a 593 // uint32_t, and as soon as entry.access_count reaches the specified maximum value 594 // operation requests will be rejected and access_count won't be incremented any more. 595 // And, besides, UINT64_MAX is huge. But we ensure that it doesn't wrap anyway, out of 596 // an abundance of caution. 597 if (entry.access_count < UINT64_MAX) ++entry.access_count; 598 return true; 599 } 600 601 if (access_count_list_.size() >= max_size_) return false; 602 603 AccessCount new_entry; 604 new_entry.keyid = keyid; 605 new_entry.access_count = 1; 606 access_count_list_.push_front(new_entry); 607 return true; 608 } 609 }; /* namespace keystore */ 610