• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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_KEYCTL_H
16 #define STORAGE_DAEMON_CRYPTO_KEYCTL_H
17 
18 #include <unistd.h>
19 #include <vector>
20 #include <map>
21 #include <string>
22 #include <linux/keyctl.h>
23 #include <linux/version.h>
24 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
25 #include <linux/fscrypt.h>
26 #else
27 #include "fscrypt_uapi.h"
28 #endif
29 
30 namespace OHOS {
31 namespace StorageDaemon {
32 using key_serial_t = int;
33 constexpr uint32_t CRYPTO_KEY_DESC_SIZE = FSCRYPT_KEY_DESCRIPTOR_SIZE;
34 static const std::string MNT_DATA = "/data";
35 static const std::string PATH_LATEST = "/latest";
36 static const std::string PATH_FSCRYPT_VER = "/fscrypt_version";
37 static const std::string PATH_ALIAS = "/alias";
38 static const std::string PATH_SECDISC = "/sec_discard";
39 static const std::string PATH_ENCRYPTED = "/encrypted";
40 static const std::string PATH_KEYID = "/key_id";
41 static const std::string PATH_KEYDESC = "/key_desc";
42 
43 enum {
44     FSCRYPT_INVALID = 0,
45     FSCRYPT_V1 = 1,
46     FSCRYPT_V2 = 2,
47 };
48 
49 union FscryptPolicy {
50     fscrypt_policy_v1 v1;
51     fscrypt_policy_v2 v2;
52 };
53 
54 class KeyCtrl {
55 public:
56     // ------ fscrypt legacy ------
57     static key_serial_t AddKey(const std::string &type, const std::string &description, const key_serial_t ringId);
58     static key_serial_t AddKey(const std::string &type, const std::string &description, fscrypt_key &fsKey,
59         const key_serial_t ringId);
60     static key_serial_t GetKeyring(key_serial_t id, int create);
61     static long Revoke(key_serial_t id);
62     static long Search(key_serial_t ringId, const std::string &type, const std::string &description,
63         key_serial_t destRingId);
64     static long SetPermission(key_serial_t id, int permissions);
65     static long Unlink(key_serial_t key, key_serial_t keyring);
66     static long RestrictKeyring(key_serial_t keyring, const std::string &type, const std::string &restriction);
67     static long GetSecurity(key_serial_t key, std::string &buffer);
68 
69     // ------ fscrypt v2 ------
70     static bool InstallKey(const std::string &mnt, fscrypt_add_key_arg &arg);
71     static bool RemoveKey(const std::string &mnt, fscrypt_remove_key_arg &arg);
72     static bool GetKeyStatus(const std::string &mnt, fscrypt_get_key_status_arg &arg);
73 
74     static bool SetPolicy(const std::string &path, FscryptPolicy &policy);
75     static bool GetPolicy(const std::string &path, fscrypt_policy &policy);
76     static bool GetPolicy(const std::string &path, fscrypt_get_policy_ex_arg &policy);
77     static bool LoadAndSetPolicy(const std::string &keyPath, const std::string &toEncrypt);
78     static uint8_t LoadVersion(const std::string &keyPath);
79 
80     static uint8_t GetFscryptVersion(const std::string &mnt);
81     static uint8_t GetEncryptedVersion(const std::string &dir);
82     static int32_t InitFscryptPolicy();
83     static int32_t SetFscryptSyspara(const std::string &config);
84     static bool HasFscryptSyspara();
85     static std::string CheckRealPath(const std::string &path);
86 };
87 
88 struct EncryptPolicy {
89     std::string version;
90     std::string fileName;
91     std::string content;
92     std::string flags;
93     bool hwWrappedKey { false };
94 };
95 
96 static const EncryptPolicy DEFAULT_POLICY = {
97     .version = "2",
98     .fileName = "aes-256-cts",
99     .content = "aes-256-xts",
100     .flags = "padding-32",
101     .hwWrappedKey = false,
102 };
103 
104 static const auto ALL_VERSION = std::map<std::string, uint8_t> {
105     {"1", FSCRYPT_V1},
106     {"2", FSCRYPT_V2},
107 };
108 
109 static const auto FILENAME_MODES = std::map<std::string, uint8_t> {
110     {"aes-256-cts", FSCRYPT_MODE_AES_256_CTS},
111 };
112 
113 static const auto CONTENTS_MODES = std::map<std::string, uint8_t> {
114     {"aes-256-xts", FSCRYPT_MODE_AES_256_XTS},
115 };
116 // To use Adiantum, CONFIG_CRYPTO_ADIANTUM must be enabled.
117 // Also, fast implementations of ChaCha and NHPoly1305 should be enabled,
118 // e.g. CONFIG_CRYPTO_CHACHA20_NEON and CONFIG_CRYPTO_NHPOLY1305_NEON for ARM.
119 
120 static const auto POLICY_FLAGS = std::map<std::string, uint8_t> {
121     {"padding-4", FSCRYPT_POLICY_FLAGS_PAD_4},
122     {"padding-8", FSCRYPT_POLICY_FLAGS_PAD_8},
123     {"padding-16", FSCRYPT_POLICY_FLAGS_PAD_16},
124     {"padding-32", FSCRYPT_POLICY_FLAGS_PAD_32},
125     // "direct-key" use with adiantum
126 };
127 
128 static const auto FSCRYPT_OPTIONS_TABLE = std::vector<std::map<std::string, uint8_t>> {
129     ALL_VERSION,
130     FILENAME_MODES,
131     CONTENTS_MODES,
132 };
133 } // namespace StorageDaemon
134 } // namespace OHOS
135 
136 #endif // STORAGE_DAEMON_CRYPTO_KEYCTL_H
137