1 /*
2  * Copyright (C) 2022 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 KEY_CONTROL_H
16 #define KEY_CONTROL_H
17 
18 #include <linux/keyctl.h>
19 #include <linux/version.h>
20 #if ((defined LINUX_VERSION_CODE ) && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
21 #include <linux/fscrypt.h>
22 #define SUPPORT_FSCRYPT_V2
23 #else
24 #include "fscrypt_uapi.h"
25 #endif
26 
27 #include <stdbool.h>
28 #include <stdint.h>
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 #define POLICY_BUF_SIZE (100)
35 
36 static const uint32_t FSCRYPT_CE_CLASS = 1;
37 static const uint32_t FSCRYPT_SDP_ECE_CLASS = 2;
38 static const uint32_t FSCRYPT_SDP_SECE_CLASS = 3;
39 static const uint32_t FSCRYPT_DPS_CLASS = 4;
40 
41 #define EXT4_AES_256_XTS_KEY_SIZE 64
42 #define EXT4_ENCRYPTION_MODE_ECDH 3
43 #define EXT4_ENCRYPTION_MODE_AES_256_XTS 1
44 #define SECE_PUB_KEY_LEN 64
45 #define SECE_PRI_KEY_LEN 32
46 #define EXT4_AES_256_XTS_KEY_SIZE_TO_KEYRING 32
47 #define EXT4_AES_256_XTS_APP_KEY_SIZE_TO_KEYRING 8
48 
49 enum {
50     FSCRYPT_INVALID = 0,
51     FSCRYPT_V1 = 1,
52     FSCRYPT_V2 = 2,
53 };
54 
55 #define EXT4_MAX_KEY_SIZE 64
56 #pragma pack(push, 1)
57 struct EncryptionKeySdp {
58     uint32_t version;
59     uint32_t sdpClass; //ECE || SECE
60     uint32_t mode; //xts or ecdh
61     char raw[EXT4_MAX_KEY_SIZE];
62     uint32_t size;
63     char pubkey[EXT4_MAX_KEY_SIZE];
64     uint32_t pubkeySize;
65 };
66 #pragma pack(pop)
67 
68 #define FSCRYPT_MAX_KEY_SIZE 64
69 #pragma pack(push, 1)
70 struct EncryptAsdpKey {
71     uint32_t version;
72     uint8_t raw[FSCRYPT_MAX_KEY_SIZE];
73     uint32_t size;
74 };
75 #pragma pack(pop)
76 
77 union FscryptPolicy {
78     struct fscrypt_policy_v1 v1;
79 #ifdef SUPPORT_FSCRYPT_V2
80     struct fscrypt_policy_v2 v2;
81 #endif
82 };
83 
84 typedef unsigned char uint8_t;
85 typedef int key_serial_t;
86 
87 static const char *FSCRYPT_POLICY_KEY = "fscrypt.policy.config";
88 static const char *PATH_FSCRYPT_VER = "/fscrypt_version";
89 
90 key_serial_t KeyCtrlGetKeyringId(key_serial_t id, int create);
91 key_serial_t KeyCtrlAddKey(const char *type, const char *description,
92     const key_serial_t ringId);
93 key_serial_t KeyCtrlAddKeyEx(const char *type, const char *description,
94     struct fscrypt_key *fsKey, const key_serial_t ringId);
95 key_serial_t KeyCtrlAddKeySdp(const char *type, const char *description,
96                               struct EncryptionKeySdp *fsKey, const key_serial_t ringId);
97 key_serial_t KeyCtrlAddAppAsdpKey(const char *type,
98                                   const char *description,
99                                   struct EncryptAsdpKey *fsKey,
100                                   const key_serial_t ringId);
101 long KeyCtrlSearch(key_serial_t ringId, const char *type, const char *description,
102     key_serial_t destRingId);
103 long KeyCtrlUnlink(key_serial_t key, key_serial_t keyring);
104 
105 #ifdef SUPPORT_FSCRYPT_V2
106 bool KeyCtrlInstallKey(const char *mnt, struct fscrypt_add_key_arg *arg);
107 bool KeyCtrlRemoveKey(const char *mnt, struct fscrypt_remove_key_arg *arg);
108 bool KeyCtrlGetKeyStatus(const char *mnt, struct fscrypt_get_key_status_arg *arg);
109 bool KeyCtrlGetPolicyEx(const char *path, struct fscrypt_get_policy_ex_arg *policy);
110 #endif
111 
112 bool KeyCtrlSetPolicy(const char *path, union FscryptPolicy *policy);
113 bool KeyCtrlGetPolicy(const char *path, struct fscrypt_policy *policy);
114 
115 uint8_t KeyCtrlGetFscryptVersion(const char *mnt);
116 uint8_t KeyCtrlLoadVersion(const char *keyPath);
117 
118 bool KeyCtrlHasFscryptSyspara(void);
119 
120 #ifdef __cplusplus
121 }
122 #endif
123 
124 #endif