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