]>
Commit | Line | Data |
---|---|---|
d1ecb069 | 1 | /* |
39236c6e | 2 | * Copyright (c) 2009-2012 Apple Inc. All rights reserved. |
d1ecb069 A |
3 | * |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ | |
39236c6e | 5 | * |
d1ecb069 A |
6 | * This file contains Original Code and/or Modifications of Original Code |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. The rights granted to you under the License | |
10 | * may not be used to create, or enable the creation or redistribution of, | |
11 | * unlawful or unlicensed copies of an Apple operating system, or to | |
12 | * circumvent, violate, or enable the circumvention or violation of, any | |
13 | * terms of an Apple operating system software license agreement. | |
39236c6e | 14 | * |
d1ecb069 A |
15 | * Please obtain a copy of the License at |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
39236c6e | 17 | * |
d1ecb069 A |
18 | * The Original Code and all software distributed under the License are |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
23 | * Please see the License for the specific language governing rights and | |
24 | * limitations under the License. | |
39236c6e | 25 | * |
d1ecb069 A |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
27 | */ | |
28 | ||
29 | #ifndef _SYS_CPROTECT_H_ | |
30 | #define _SYS_CPROTECT_H_ | |
31 | ||
32 | #ifdef __cplusplus | |
33 | extern "C" { | |
34 | #endif | |
35 | ||
36 | #if KERNEL_PRIVATE | |
37 | ||
38 | #include <sys/cdefs.h> | |
6d2010ae | 39 | #include <sys/content_protection.h> |
d1ecb069 | 40 | #include <sys/kernel_types.h> |
316670eb | 41 | #include <crypto/aes.h> |
d1ecb069 | 42 | |
39236c6e A |
43 | #define CP_IV_KEYSIZE 20 /* 16x8 = 128, but SHA1 pushes 20 bytes so keep space for that */ |
44 | #define CP_MAX_KEYSIZE 32 /* 8x4 = 32, 32x8 = 256 */ | |
45 | #define CP_MAX_WRAPPEDKEYSIZE 128 /* The size of the largest allowed key */ | |
316670eb | 46 | #define CP_INITIAL_WRAPPEDKEYSIZE 40 |
39236c6e A |
47 | #define CP_V2_WRAPPEDKEYSIZE 40 /* Size of the wrapped key in a v2 EA */ |
48 | #define CP_V4_RESERVEDBYTES 20 /* Number of reserved bytes in EA still present */ | |
d1ecb069 | 49 | |
6d2010ae | 50 | /* lock events from AppleKeyStore */ |
39236c6e A |
51 | #define CP_LOCKED_STATE 0 /* Device is locked */ |
52 | #define CP_UNLOCKED_STATE 1 /* Device is unlocked */ | |
d1ecb069 | 53 | |
39236c6e | 54 | #define CP_MAX_STATE 1 /* uint8_t ; maximum # of states is 255 */ |
d1ecb069 | 55 | |
39236c6e A |
56 | #define CP_LOCKED_KEYCHAIN 0 |
57 | #define CP_UNLOCKED_KEYCHAIN 1 | |
316670eb | 58 | |
39236c6e A |
59 | /* For struct cprotect: cp_flags */ |
60 | #define CP_NEEDS_KEYS 0x01 /* File needs persistent keys */ | |
61 | #define CP_KEY_FLUSHED 0x02 /* File's unwrapped key has been purged from memory */ | |
62 | #define CP_NO_XATTR 0x04 /* Key info has not been saved as EA to the FS */ | |
63 | #define CP_OFF_IV_ENABLED 0x08 /* Only go down relative IV route if this flag is set */ | |
64 | #define CP_RELOCATION_INFLIGHT 0x10 /* File with offset IVs is in the process of being relocated. */ | |
65 | #define CP_SEP_WRAPPEDKEY 0x20 /* Wrapped key delivered from keybag */ | |
d1ecb069 | 66 | |
6d2010ae | 67 | /* Content Protection VNOP Operation flags */ |
39236c6e A |
68 | #define CP_READ_ACCESS 0x1 |
69 | #define CP_WRITE_ACCESS 0x2 | |
d1ecb069 | 70 | |
39236c6e | 71 | /* |
bd504ef0 | 72 | * Check for this version when deciding to enable features |
39236c6e A |
73 | * For iOS 4, CP_CURRENT_MAJOR_VERS = 2.0 |
74 | * For iOS 5, CP_CURRENT_MAJOR_VERS = 4.0 | |
bd504ef0 | 75 | */ |
6d2010ae | 76 | #define CONTENT_PROTECTION_XATTR_NAME "com.apple.system.cprotect" |
39236c6e A |
77 | #define CP_NEW_MAJOR_VERS 4 |
78 | #define CP_PREV_MAJOR_VERS 2 | |
79 | #define CP_MINOR_VERS 0 | |
d1ecb069 A |
80 | |
81 | typedef struct cprotect *cprotect_t; | |
82 | typedef struct cp_wrap_func *cp_wrap_func_t; | |
83 | typedef struct cp_global_state *cp_global_state_t; | |
84 | typedef struct cp_xattr *cp_xattr_t; | |
85 | ||
6d2010ae A |
86 | typedef struct cnode * cnode_ptr_t; |
87 | //forward declare the struct. | |
88 | struct hfsmount; | |
d1ecb069 | 89 | |
39236c6e A |
90 | /* Structures passed between HFS and AKS kext */ |
91 | typedef struct { | |
92 | void *key; | |
93 | unsigned key_len; | |
94 | void *iv_key; | |
95 | unsigned iv_key_len; | |
96 | uint32_t flags; | |
97 | } cp_raw_key_s, *cp_raw_key_t; | |
98 | ||
99 | typedef struct { | |
100 | void *key; | |
101 | unsigned key_len; | |
102 | uint32_t dp_class; | |
103 | } cp_wrapped_key_s, *cp_wrapped_key_t; | |
104 | ||
105 | typedef struct { | |
106 | ino64_t inode; | |
107 | uint32_t volume; | |
108 | pid_t pid; | |
109 | uid_t uid; | |
110 | } cp_cred_s, *cp_cred_t; | |
d1ecb069 | 111 | |
39236c6e A |
112 | /* The wrappers are invoked on the AKS kext */ |
113 | typedef int unwrapper_t(cp_cred_t access, const cp_wrapped_key_t wrapped_key_in, cp_raw_key_t key_out); | |
114 | typedef int rewrapper_t(cp_cred_t access, uint32_t dp_class, const cp_wrapped_key_t wrapped_key_in, cp_wrapped_key_t wrapped_key_out); | |
115 | typedef int new_key_t(cp_cred_t access, uint32_t dp_class, cp_raw_key_t key_out, cp_wrapped_key_t wrapped_key_out); | |
116 | typedef int invalidater_t(cp_cred_t access); /* invalidates keys */ | |
117 | ||
118 | ||
119 | /* Flags for Interaction between AKS / Kernel */ | |
120 | #define CP_RAW_KEY_WRAPPEDKEY 0x00000001 | |
121 | ||
122 | ||
123 | /* | |
124 | * Runtime-only structure containing the content protection status | |
125 | * for the given file. This is contained within the cnode | |
316670eb A |
126 | * This is passed down to IOStorageFamily via the bufattr struct |
127 | * | |
128 | ****************************************************** | |
129 | * Some Key calculation information for offset based IV | |
130 | ****************************************************** | |
131 | * Kf = original 256 bit per file key | |
132 | * Kiv = SHA1(Kf), use full Kf, but truncate Kiv to 128 bits | |
133 | * Kiv can be cached in the cprotect, so it only has to be calculated once for the file init | |
134 | * | |
135 | * IVb = Encrypt(Kiv, offset) | |
136 | * | |
6d2010ae | 137 | */ |
d1ecb069 | 138 | struct cprotect { |
6d2010ae A |
139 | uint32_t cp_flags; |
140 | uint32_t cp_pclass; | |
316670eb A |
141 | aes_encrypt_ctx cp_cache_iv_ctx; |
142 | uint32_t cp_cache_key_len; | |
143 | uint8_t cp_cache_key[CP_MAX_KEYSIZE]; | |
144 | uint32_t cp_persistent_key_len; | |
39236c6e | 145 | void* cp_backing_cnode; |
316670eb | 146 | uint8_t cp_persistent_key[]; |
d1ecb069 A |
147 | }; |
148 | ||
149 | struct cp_wrap_func { | |
39236c6e A |
150 | new_key_t *new_key; |
151 | unwrapper_t *unwrapper; | |
152 | rewrapper_t *rewrapper; | |
153 | invalidater_t *invalidater; | |
d1ecb069 A |
154 | }; |
155 | ||
156 | struct cp_global_state { | |
6d2010ae | 157 | uint8_t wrap_functions_set; |
316670eb A |
158 | uint8_t lock_state; |
159 | u_int16_t reserved; | |
d1ecb069 A |
160 | }; |
161 | ||
6d2010ae | 162 | /* |
39236c6e | 163 | * On-disk structure written as the per-file EA payload |
6d2010ae A |
164 | * All on-disk multi-byte fields for the CP XATTR must be stored |
165 | * little-endian on-disk. This means they must be endian swapped to | |
39236c6e A |
166 | * L.E on getxattr() and converted to LE on setxattr(). |
167 | * | |
168 | * This structure is a fixed length and is tightly packed. | |
169 | * 56 bytes total. | |
6d2010ae | 170 | */ |
316670eb A |
171 | struct cp_xattr_v2 { |
172 | u_int16_t xattr_major_version; | |
173 | u_int16_t xattr_minor_version; | |
174 | u_int32_t flags; | |
175 | u_int32_t persistent_class; | |
176 | u_int32_t key_size; | |
177 | uint8_t persistent_key[CP_V2_WRAPPEDKEYSIZE]; | |
39236c6e A |
178 | } __attribute__((aligned(2), packed)); |
179 | ||
180 | ||
181 | /* | |
182 | * V4 Content Protection EA On-Disk Layout. | |
183 | * | |
184 | * This structure must be tightly packed, but the *size can vary* | |
185 | * depending on the length of the key. At MOST, the key length will be | |
186 | * CP_MAX_WRAPPEDKEYSIZE, but the length is defined by the key_size field. | |
187 | * | |
188 | * Either way, the packing must be applied to ensure that the key data is | |
189 | * retrievable in the right location relative to the start of the struct. | |
190 | * | |
191 | * Fully packed, this structure can range from : | |
192 | * MIN: 36 bytes (no key -- used with directories) | |
193 | * MAX: 164 bytes (with 128 byte key) | |
194 | * | |
195 | * During runtime we always allocate with the full 128 byte key, but only | |
196 | * use as much of the key buffer as needed. It must be tightly packed, though. | |
197 | */ | |
316670eb A |
198 | |
199 | struct cp_xattr_v4 { | |
200 | u_int16_t xattr_major_version; | |
201 | u_int16_t xattr_minor_version; | |
202 | u_int32_t flags; | |
203 | u_int32_t persistent_class; | |
204 | u_int32_t key_size; | |
39236c6e A |
205 | /* CP V4 Reserved Bytes == 20 */ |
206 | u_int8_t reserved[CP_V4_RESERVEDBYTES]; | |
207 | /* All above fields are fixed regardless of key length (36 bytes) */ | |
208 | /* Max Wrapped Size == 128 */ | |
316670eb | 209 | uint8_t persistent_key[CP_MAX_WRAPPEDKEYSIZE]; |
39236c6e | 210 | } __attribute__((aligned(2), packed)); |
d1ecb069 | 211 | |
39236c6e A |
212 | |
213 | /* | |
214 | * The Root Directory's EA (fileid 1) is special; it defines information about | |
215 | * what capabilities the filesystem is using. | |
216 | * | |
217 | * The data is still stored little endian. | |
218 | * | |
219 | * Note that this structure is tightly packed: 28 bytes total. | |
220 | */ | |
221 | struct cp_root_xattr { | |
222 | u_int16_t major_version; | |
223 | u_int16_t minor_version; | |
224 | u_int64_t flags; | |
225 | u_int8_t reserved[16]; | |
226 | } __attribute__((aligned(2), packed)); | |
6d2010ae A |
227 | |
228 | ||
39236c6e A |
229 | /* |
230 | * Functions to check the status of a CP and to query | |
6d2010ae A |
231 | * the containing filesystem to see if it is supported. |
232 | */ | |
233 | int cp_vnode_getclass(vnode_t, int *); | |
234 | int cp_vnode_setclass(vnode_t, uint32_t); | |
316670eb | 235 | int cp_vnode_transcode(vnode_t); |
6d2010ae | 236 | |
d1ecb069 A |
237 | int cp_key_store_action(int); |
238 | int cp_register_wraps(cp_wrap_func_t); | |
6d2010ae A |
239 | |
240 | int cp_entry_init(cnode_ptr_t, struct mount *); | |
316670eb | 241 | int cp_entry_gentempkeys(struct cprotect **entry_ptr, struct hfsmount *hfsmp); |
39236c6e A |
242 | int cp_needs_tempkeys (struct hfsmount *hfsmp, int* needs); |
243 | void cp_entry_destroy(struct cprotect *entry_ptr); | |
244 | void cp_replace_entry (struct cnode *cp, struct cprotect *newentry); | |
6d2010ae | 245 | cnode_ptr_t cp_get_protected_cnode(vnode_t); |
316670eb | 246 | int cp_handle_vnop(vnode_t, int, int); |
6d2010ae A |
247 | int cp_fs_protected (mount_t); |
248 | int cp_getrootxattr (struct hfsmount *hfsmp, struct cp_root_xattr *outxattr); | |
249 | int cp_setrootxattr (struct hfsmount *hfsmp, struct cp_root_xattr *newxattr); | |
316670eb | 250 | int cp_setxattr(struct cnode *cp, struct cprotect *entry, struct hfsmount *hfsmp, uint32_t fileid, int options); |
39236c6e A |
251 | int cp_generate_keys (struct hfsmount *hfsmp, struct cnode *cp, int targetclass, struct cprotect **newentry); |
252 | int cp_setup_newentry (struct hfsmount *hfsmp, struct cnode *dcp, int32_t suppliedclass, | |
253 | mode_t cmode, struct cprotect **tmpentry); | |
316670eb A |
254 | int cp_handle_relocate (cnode_ptr_t cp, struct hfsmount *hfsmp); |
255 | int cp_handle_open(struct vnode *vp, int mode); | |
256 | int cp_get_root_major_vers (struct vnode *vp, uint32_t *level); | |
39236c6e A |
257 | int cp_get_default_level (struct vnode *vp, uint32_t *level); |
258 | int cp_is_valid_class (int isdir, int32_t protectionclass); | |
d1ecb069 A |
259 | |
260 | #endif /* KERNEL_PRIVATE */ | |
261 | ||
262 | #ifdef __cplusplus | |
263 | }; | |
264 | #endif | |
265 | ||
266 | #endif /* !_SYS_CPROTECT_H_ */ |