summaryrefslogtreecommitdiff
path: root/keystore/KeyStore.h
blob: 7841a80027f2e4e22d8b3321bfc377ffd7887014 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef KEYSTORE_KEYSTORE_H_
#define KEYSTORE_KEYSTORE_H_

#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
#include <keymasterV4_1/Keymaster.h>
#include <utils/Vector.h>

#include <keystore/keymaster_types.h>

#include "auth_token_table.h"
#include "blob.h"
#include "confirmation_manager.h"
#include "grant_store.h"
#include "keymaster_worker.h"
#include "keystore_keymaster_enforcement.h"
#include "operation.h"
#include "user_state.h"

#include <array>
#include <optional>
#include <tuple>

namespace keystore {

using ::android::sp;
using keymaster::support::Keymaster;

template <typename T, size_t count> class Devices : public std::array<T, count> {
  public:
    T& operator[](SecurityLevel secLevel) {
        static_assert(uint32_t(SecurityLevel::SOFTWARE) == 0 &&
                          uint32_t(SecurityLevel::TRUSTED_ENVIRONMENT) == 1 &&
                          uint32_t(SecurityLevel::STRONGBOX) == 2,
                      "Numeric values of security levels have changed");
        return std::array<T, count>::at(static_cast<uint32_t>(secLevel));
    }
    T operator[](SecurityLevel secLevel) const {
        if (static_cast<uint32_t>(secLevel) > static_cast<uint32_t>(SecurityLevel::STRONGBOX)) {
            LOG(ERROR) << "Invalid security level requested";
            return {};
        }
        return (*const_cast<Devices*>(this))[secLevel];
    }
};

}  // namespace keystore

namespace std {
template <typename T, size_t N> struct tuple_size<keystore::Devices<T, N>> {
  public:
    static constexpr size_t value = std::tuple_size<std::array<T, N>>::value;
};
}  // namespace std

namespace keystore {

using KeymasterWorkers = Devices<std::shared_ptr<KeymasterWorker>, 3>;
using KeymasterDevices = Devices<sp<Keymaster>, 3>;

class KeyStore : public ::android::IBinder::DeathRecipient {
  public:
    KeyStore(const KeymasterDevices& kmDevices,
             SecurityLevel minimalAllowedSecurityLevelForNewKeys);
    ~KeyStore();

    std::shared_ptr<KeymasterWorker> getDevice(SecurityLevel securityLevel) const {
        return mKmDevices[securityLevel];
    }

    std::shared_ptr<KeymasterWorker> getFallbackDevice() const {
        // we only return the fallback device if the creation of new fallback key blobs is
        // allowed. (also see getDevice below)
        if (mAllowNewFallback) {
            return mKmDevices[SecurityLevel::SOFTWARE];
        } else {
            return nullptr;
        }
    }

    std::shared_ptr<KeymasterWorker> getDevice(const Blob& blob) {
        return mKmDevices[blob.getSecurityLevel()];
    }

    ResponseCode initialize();

    State getState(uid_t userId) { return mUserStateDB.getUserState(userId)->getState(); }

    ResponseCode initializeUser(const android::String8& pw, uid_t userId);

    ResponseCode copyMasterKey(uid_t srcUser, uid_t dstUser);
    ResponseCode writeMasterKey(const android::String8& pw, uid_t userId);
    ResponseCode readMasterKey(const android::String8& pw, uid_t userId);

    LockedKeyBlobEntry getLockedBlobEntryIfNotExists(const std::string& alias, uid_t uid);
    std::optional<KeyBlobEntry> getBlobEntryIfExists(const std::string& alias, uid_t uid);
    LockedKeyBlobEntry getLockedBlobEntryIfExists(const std::string& alias, uid_t uid);
    /*
     * Delete entries owned by userId. If keepUnencryptedEntries is true
     * then only encrypted entries will be removed, otherwise all entries will
     * be removed.
     */
    void resetUser(uid_t userId, bool keepUnenryptedEntries);
    bool isEmpty(uid_t userId) const;

    void lock(uid_t userId);

    std::tuple<ResponseCode, Blob, Blob> get(const LockedKeyBlobEntry& blobfile);
    ResponseCode put(const LockedKeyBlobEntry& blobfile, Blob keyBlob, Blob characteristicsBlob);
    ResponseCode del(const LockedKeyBlobEntry& blobfile);

    std::string addGrant(const LockedKeyBlobEntry& blobfile, uid_t granteeUid);
    bool removeGrant(const LockedKeyBlobEntry& blobfile, const uid_t granteeUid);
    void removeAllGrantsToUid(const uid_t granteeUid);

    ResponseCode importKey(const uint8_t* key, size_t keyLen, const LockedKeyBlobEntry& blobfile,
                           uid_t userId, int32_t flags);

    bool isHardwareBacked(const android::String16& keyType) const;

    std::tuple<ResponseCode, Blob, Blob, LockedKeyBlobEntry>
    getKeyForName(const android::String8& keyName, const uid_t uid, const BlobType type);

    void binderDied(const ::android::wp<IBinder>& who) override;

    UserStateDB& getUserStateDB() { return mUserStateDB; }
    AuthTokenTable& getAuthTokenTable() { return mAuthTokenTable; }
    KeystoreKeymasterEnforcement& getEnforcementPolicy() { return mEnforcementPolicy; }
    ConfirmationManager& getConfirmationManager() { return *mConfirmationManager; }

    void addOperationDevice(sp<IBinder> token, std::shared_ptr<KeymasterWorker> dev) {
        std::lock_guard<std::mutex> lock(operationDeviceMapMutex_);
        operationDeviceMap_.emplace(std::move(token), std::move(dev));
    }
    std::shared_ptr<KeymasterWorker> getOperationDevice(const sp<IBinder>& token) {
        std::lock_guard<std::mutex> lock(operationDeviceMapMutex_);
        auto it = operationDeviceMap_.find(token);
        if (it != operationDeviceMap_.end()) {
            return it->second;
        }
        return {};
    }
    void removeOperationDevice(const sp<IBinder>& token) {
        std::lock_guard<std::mutex> lock(operationDeviceMapMutex_);
        operationDeviceMap_.erase(token);
    }

  private:
    static const char* kOldMasterKey;
    static const char* kMetaDataFile;
    static const android::String16 kRsaKeyType;
    static const android::String16 kEcKeyType;

    KeymasterWorkers mKmDevices;

    bool mAllowNewFallback;

    UserStateDB mUserStateDB;
    AuthTokenTable mAuthTokenTable;
    KeystoreKeymasterEnforcement mEnforcementPolicy;
    sp<ConfirmationManager> mConfirmationManager;

    ::keystore::GrantStore mGrants;

    typedef struct { uint32_t version; } keystore_metadata_t;

    keystore_metadata_t mMetaData;

    /**
     * Upgrade the key from the current version to whatever is newest.
     */
    bool upgradeBlob(Blob* blob, const uint8_t oldVersion);

    void readMetaData();
    void writeMetaData();

    bool upgradeKeystore();

    std::mutex operationDeviceMapMutex_;
    std::map<sp<IBinder>, std::shared_ptr<KeymasterWorker>> operationDeviceMap_;
};

}  // namespace keystore

#endif  // KEYSTORE_KEYSTORE_H_