1 /*
2 * Copyright 2021, 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 #include <keymaster/pure_soft_secure_key_storage.h>
18
19 #include <vector>
20
21 #include <keymaster/logger.h>
22
23 namespace keymaster {
24
25 class PureSoftSecureStorageMap {
26 public:
PureSoftSecureStorageMap(uint32_t max_size)27 explicit PureSoftSecureStorageMap(uint32_t max_size) : max_size_(max_size) {}
28
29 /* Writes key id into pure software secure storage. Returns false if the list has
30 * already reached maximum size. */
31 bool WriteKey(km_id_t keyid);
32
33 /* Checks if the key id exists in the list. */
34 bool KeyExists(km_id_t keyid) const;
35
36 /* Deletes the key id from the list, if it is not existed then do nothing. */
37 void DeleteKey(km_id_t keyid);
38
39 /* Deletes all key ids from the list. */
40 void DeleteAllKeys();
41
42 /* Checks if there is still available slot to write key. */
43 bool HasSlot() const;
44
45 private:
46 std::vector<km_id_t> keyid_list_;
47 const uint32_t max_size_;
48 };
49
WriteKey(km_id_t keyid)50 bool PureSoftSecureStorageMap::WriteKey(km_id_t keyid) {
51 if (keyid_list_.size() >= max_size_) return false;
52 keyid_list_.push_back(keyid);
53 return true;
54 }
55
KeyExists(km_id_t keyid) const56 bool PureSoftSecureStorageMap::KeyExists(km_id_t keyid) const {
57 for (km_id_t key_id : keyid_list_)
58 if (key_id == keyid) return true;
59 return false;
60 }
61
DeleteKey(km_id_t keyid)62 void PureSoftSecureStorageMap::DeleteKey(km_id_t keyid) {
63 std::vector<km_id_t>::iterator iter;
64 for (iter = keyid_list_.begin(); iter != keyid_list_.end();) {
65 if (*iter == keyid)
66 iter = keyid_list_.erase(iter);
67 else
68 ++iter;
69 }
70 }
71
DeleteAllKeys()72 void PureSoftSecureStorageMap::DeleteAllKeys() {
73 keyid_list_.clear();
74 }
75
HasSlot() const76 bool PureSoftSecureStorageMap::HasSlot() const {
77 return keyid_list_.size() < max_size_;
78 }
79
PureSoftSecureKeyStorage(uint32_t max_slot)80 PureSoftSecureKeyStorage::PureSoftSecureKeyStorage(uint32_t max_slot)
81 : pure_soft_secure_storage_map_(new (std::nothrow) PureSoftSecureStorageMap(max_slot)) {}
82
~PureSoftSecureKeyStorage()83 PureSoftSecureKeyStorage::~PureSoftSecureKeyStorage() {
84 delete pure_soft_secure_storage_map_;
85 }
86
WriteKey(const km_id_t keyid,const KeymasterKeyBlob &)87 keymaster_error_t PureSoftSecureKeyStorage::WriteKey(const km_id_t keyid,
88 const KeymasterKeyBlob& /* blob */) {
89 if (!pure_soft_secure_storage_map_) {
90 LOG_S("Pure software secure key storage table not allocated.", 0);
91 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
92 }
93
94 if (!pure_soft_secure_storage_map_->WriteKey(keyid)) {
95 LOG_E("Pure software secure key storage slot full.", 0);
96 return KM_ERROR_UNKNOWN_ERROR;
97 }
98
99 return KM_ERROR_OK;
100 }
101
KeyExists(const km_id_t keyid,bool * exists)102 keymaster_error_t PureSoftSecureKeyStorage::KeyExists(const km_id_t keyid, bool* exists) {
103 if (!pure_soft_secure_storage_map_) {
104 LOG_S("Pure software secure key storage table not allocated.", 0);
105 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
106 }
107
108 *exists = pure_soft_secure_storage_map_->KeyExists(keyid);
109 return KM_ERROR_OK;
110 }
111
DeleteKey(const km_id_t keyid)112 keymaster_error_t PureSoftSecureKeyStorage::DeleteKey(const km_id_t keyid) {
113 if (!pure_soft_secure_storage_map_) {
114 LOG_S("Pure software secure key storage table not allocated.", 0);
115 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
116 }
117
118 pure_soft_secure_storage_map_->DeleteKey(keyid);
119 return KM_ERROR_OK;
120 }
121
DeleteAllKeys()122 keymaster_error_t PureSoftSecureKeyStorage::DeleteAllKeys() {
123 if (!pure_soft_secure_storage_map_) {
124 LOG_S("Pure software secure key storage table not allocated.", 0);
125 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
126 }
127
128 pure_soft_secure_storage_map_->DeleteAllKeys();
129 return KM_ERROR_OK;
130 }
131
HasSlot(bool * has_slot)132 keymaster_error_t PureSoftSecureKeyStorage::HasSlot(bool* has_slot) {
133 if (!pure_soft_secure_storage_map_) {
134 LOG_S("Pure software secure key storage table not allocated.", 0);
135 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
136 }
137
138 *has_slot = pure_soft_secure_storage_map_->HasSlot();
139 return KM_ERROR_OK;
140 }
141
142 } // namespace keymaster
143