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