• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
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 #ifndef STORAGE_DAEMON_CRYPTO_KEY_UTILS_H
16 #define STORAGE_DAEMON_CRYPTO_KEY_UTILS_H
17 
18 #include <string>
19 #include <linux/version.h>
20 
21 #include "hks_type.h"
22 #include "securec.h"
23 
24 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
25 #include <linux/fscrypt.h>
26 #define SUPPORT_FSCRYPT_V2
27 #else
28 #include "libfscrypt/fscrypt_uapi.h"
29 #endif
30 
31 namespace OHOS {
32 namespace StorageDaemon {
33 constexpr uint32_t CRYPTO_KEY_SECDISC_SIZE = 16384;
34 constexpr uint32_t CRYPTO_AES_256_XTS_KEY_SIZE = 64;
35 
36 using key_serial_t = int;
37 constexpr uint32_t CRYPTO_KEY_DESC_SIZE = FSCRYPT_KEY_DESCRIPTOR_SIZE;
38 constexpr const char *MNT_DATA = "/data";
39 constexpr const char *PATH_LATEST = "/latest";
40 constexpr const char *PATH_SHIELD = "/shield";
41 constexpr const char *PATH_SECDISC = "/sec_discard";
42 constexpr const char *PATH_ENCRYPTED = "/encrypted";
43 constexpr const char *PATH_KEYID = "/key_id";
44 constexpr const char *PATH_KEYDESC = "/key_desc";
45 
46 constexpr const char *DATA_EL0_DIR = "/data/service/el0";
47 constexpr const char *STORAGE_DAEMON_DIR = "/data/service/el0/storage_daemon";
48 constexpr const char *DEVICE_EL1_DIR = "/data/service/el0/storage_daemon/sd";
49 
50 class KeyBlob {
51 public:
52     KeyBlob() = default;
KeyBlob(KeyBlob const & blob)53     KeyBlob(KeyBlob const &blob)
54     {
55         Alloc(blob.size);
56         auto ret = memcpy_s(data.get(), size, blob.data.get(), blob.size);
57         if (ret != EOK) {
58             Clear();
59         }
60     }
~KeyBlob()61     ~KeyBlob()
62     {
63         Clear();
64     }
KeyBlob(uint32_t len)65     KeyBlob(uint32_t len)
66     {
67         Alloc(len);
68         // may fail, need check IsEmpty() if needed
69     }
KeyBlob(KeyBlob && right)70     KeyBlob(KeyBlob &&right)
71     {
72         data = std::move(right.data);
73         size = right.size;
74     }
KeyBlob(const std::vector<uint8_t> & vec)75     KeyBlob(const std::vector<uint8_t> &vec)
76     {
77         if (Alloc(vec.size())) {
78             auto ret = memcpy_s(data.get(), size, vec.data(), vec.size());
79             if (ret != EOK) {
80                 Clear();
81             }
82         }
83     }
84     KeyBlob& operator=(KeyBlob &&right)
85     {
86         data = std::move(right.data);
87         size = right.size;
88         return *this;
89     }
Alloc(uint32_t len)90     bool Alloc(uint32_t len)
91     {
92         if (len > CRYPTO_KEY_SECDISC_SIZE) {
93             return false;
94         }
95         if (!IsEmpty()) {
96             Clear();
97         }
98 
99         data = std::make_unique<uint8_t[]>(len);
100         size = len;
101         (void)memset_s(data.get(), size, 0, size);
102         return true;
103     }
Clear()104     void Clear()
105     {
106         if (data != nullptr && size != 0) {
107             (void)memset_s(data.get(), size, 0, size);
108         }
109         size = 0;
110         data.reset(nullptr);
111     }
IsEmpty()112     bool IsEmpty() const
113     {
114         return size == 0 || data.get() == nullptr;
115     }
ToString()116     std::string ToString() const
117     {
118         std::string hex;
119         if (IsEmpty()) {
120             return hex;
121         }
122         const char *hexMap = "0123456789abcdef";
123         static_assert(sizeof(data[0]) == sizeof(char));
124         for (size_t i = 0; i < size; i++) {
125             hex = hex + hexMap[(data[i] & 0xF0) >> 4] + hexMap[data[i] & 0x0F]; // higher 4 bits
126         }
127         return hex;
128     }
ToHksBlob()129     HksBlob ToHksBlob() const
130     {
131         return {size, data.get()};
132     }
133     uint32_t size { 0 };
134     std::unique_ptr<uint8_t[]> data { nullptr };
135 };
136 
137 struct KeyInfo {
138     uint8_t version { 0 };
139     KeyBlob key;
140     // the legacy interface use key_spec.u.descriptor
141     KeyBlob keyDesc;
142     // the v2 interface use the key_spec.u.identifier
143     KeyBlob keyId;
144 };
145 
146 struct KeyContext {
147     // secure discardable keyblob
148     KeyBlob secDiscard;
149     // encrypted huks key for encrypt/decrypt
150     KeyBlob shield;
151     // encrypted blob of rawkey
152     KeyBlob rndEnc;
153     // aes_gcm tags
154     KeyBlob nonce;
155     KeyBlob aad;
156 };
157 
158 struct UserAuth {
159     // when secure access enabled, token is needed to authenticate the user
160     KeyBlob token;
161     KeyBlob secret;
162     uint64_t secureUid { 0 };
163 };
164 } // namespace StorageDaemon
165 } // namespace OHOS
166 
167 #endif // STORAGE_DAEMON_CRYPTO_KEY_UTILS_H
168