]>
Commit | Line | Data |
---|---|---|
d1ecb069 | 1 | /* |
fe8ab488 | 2 | * Copyright (c) 2009-2014 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 | |
fe8ab488 A |
43 | #include <sys/kdebug.h> |
44 | ||
45 | #define CP_CODE(code) FSDBG_CODE(DBG_CONTENT_PROT, code) | |
46 | /* | |
47 | * Class DBG_FSYSTEM == 0x03 | |
48 | * Subclass DBG_CONTENT_PROT == 0xCF | |
49 | * These debug codes are of the form 0x03CFzzzz | |
50 | */ | |
51 | ||
52 | enum { | |
53 | CPDBG_OFFSET_IO = CP_CODE(0), /* 0x03CF0000 */ | |
54 | }; | |
55 | ||
56 | /* normally the debug events are no-ops */ | |
57 | #define CP_DEBUG(x,a,b,c,d,e) do {} while (0); | |
58 | ||
59 | /* dev kernels only! */ | |
60 | #if !SECURE_KERNEL | |
61 | ||
62 | /* KDEBUG events used by content protection subsystem */ | |
63 | #if 0 | |
64 | #undef CP_DEBUG | |
65 | #define CP_DEBUG KERNEL_DEBUG_CONSTANT | |
66 | #endif | |
67 | ||
68 | #endif | |
69 | ||
70 | ||
71 | ||
39236c6e A |
72 | #define CP_IV_KEYSIZE 20 /* 16x8 = 128, but SHA1 pushes 20 bytes so keep space for that */ |
73 | #define CP_MAX_KEYSIZE 32 /* 8x4 = 32, 32x8 = 256 */ | |
fe8ab488 A |
74 | #define CP_MAX_CACHEBUFLEN 64 /* Maximum size of cp cache buffer/array */ |
75 | ||
39236c6e | 76 | #define CP_MAX_WRAPPEDKEYSIZE 128 /* The size of the largest allowed key */ |
316670eb | 77 | #define CP_INITIAL_WRAPPEDKEYSIZE 40 |
39236c6e A |
78 | #define CP_V2_WRAPPEDKEYSIZE 40 /* Size of the wrapped key in a v2 EA */ |
79 | #define CP_V4_RESERVEDBYTES 20 /* Number of reserved bytes in EA still present */ | |
d1ecb069 | 80 | |
6d2010ae | 81 | /* lock events from AppleKeyStore */ |
39236c6e A |
82 | #define CP_LOCKED_STATE 0 /* Device is locked */ |
83 | #define CP_UNLOCKED_STATE 1 /* Device is unlocked */ | |
d1ecb069 | 84 | |
39236c6e | 85 | #define CP_MAX_STATE 1 /* uint8_t ; maximum # of states is 255 */ |
d1ecb069 | 86 | |
39236c6e A |
87 | #define CP_LOCKED_KEYCHAIN 0 |
88 | #define CP_UNLOCKED_KEYCHAIN 1 | |
316670eb | 89 | |
39236c6e A |
90 | /* For struct cprotect: cp_flags */ |
91 | #define CP_NEEDS_KEYS 0x01 /* File needs persistent keys */ | |
92 | #define CP_KEY_FLUSHED 0x02 /* File's unwrapped key has been purged from memory */ | |
93 | #define CP_NO_XATTR 0x04 /* Key info has not been saved as EA to the FS */ | |
94 | #define CP_OFF_IV_ENABLED 0x08 /* Only go down relative IV route if this flag is set */ | |
95 | #define CP_RELOCATION_INFLIGHT 0x10 /* File with offset IVs is in the process of being relocated. */ | |
96 | #define CP_SEP_WRAPPEDKEY 0x20 /* Wrapped key delivered from keybag */ | |
d1ecb069 | 97 | |
fe8ab488 A |
98 | |
99 | ||
6d2010ae | 100 | /* Content Protection VNOP Operation flags */ |
39236c6e A |
101 | #define CP_READ_ACCESS 0x1 |
102 | #define CP_WRITE_ACCESS 0x2 | |
d1ecb069 | 103 | |
39236c6e | 104 | /* |
bd504ef0 | 105 | * Check for this version when deciding to enable features |
39236c6e A |
106 | * For iOS 4, CP_CURRENT_MAJOR_VERS = 2.0 |
107 | * For iOS 5, CP_CURRENT_MAJOR_VERS = 4.0 | |
bd504ef0 | 108 | */ |
6d2010ae | 109 | #define CONTENT_PROTECTION_XATTR_NAME "com.apple.system.cprotect" |
39236c6e A |
110 | #define CP_NEW_MAJOR_VERS 4 |
111 | #define CP_PREV_MAJOR_VERS 2 | |
112 | #define CP_MINOR_VERS 0 | |
d1ecb069 | 113 | |
fe8ab488 A |
114 | /* the class occupies the lowest 5 bits, so there are 32 values (0-31) */ |
115 | #define CP_EFFECTIVE_CLASSMASK 0x0000001f | |
116 | ||
117 | /* macros for quick access/typing to mask out the classmask */ | |
118 | #define CP_CLASS(x) ((uint32_t)(CP_EFFECTIVE_CLASSMASK & (x))) | |
119 | ||
120 | #define CP_CRYPTO_G1 0x00000020 | |
121 | ||
d1ecb069 A |
122 | typedef struct cprotect *cprotect_t; |
123 | typedef struct cp_wrap_func *cp_wrap_func_t; | |
d1ecb069 A |
124 | typedef struct cp_xattr *cp_xattr_t; |
125 | ||
6d2010ae A |
126 | typedef struct cnode * cnode_ptr_t; |
127 | //forward declare the struct. | |
128 | struct hfsmount; | |
d1ecb069 | 129 | |
39236c6e A |
130 | /* Structures passed between HFS and AKS kext */ |
131 | typedef struct { | |
132 | void *key; | |
133 | unsigned key_len; | |
134 | void *iv_key; | |
135 | unsigned iv_key_len; | |
136 | uint32_t flags; | |
fe8ab488 A |
137 | } cp_raw_key_s; |
138 | ||
139 | typedef cp_raw_key_s* cp_raw_key_t; | |
39236c6e A |
140 | |
141 | typedef struct { | |
142 | void *key; | |
143 | unsigned key_len; | |
144 | uint32_t dp_class; | |
fe8ab488 A |
145 | } cp_wrapped_key_s; |
146 | ||
147 | typedef cp_wrapped_key_s* cp_wrapped_key_t; | |
39236c6e A |
148 | |
149 | typedef struct { | |
150 | ino64_t inode; | |
151 | uint32_t volume; | |
152 | pid_t pid; | |
153 | uid_t uid; | |
fe8ab488 A |
154 | } cp_cred_s; |
155 | ||
156 | typedef cp_cred_s* cp_cred_t; | |
d1ecb069 | 157 | |
39236c6e A |
158 | /* The wrappers are invoked on the AKS kext */ |
159 | typedef int unwrapper_t(cp_cred_t access, const cp_wrapped_key_t wrapped_key_in, cp_raw_key_t key_out); | |
160 | 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); | |
161 | 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); | |
162 | typedef int invalidater_t(cp_cred_t access); /* invalidates keys */ | |
fe8ab488 | 163 | typedef int backup_key_t(cp_cred_t access, const cp_wrapped_key_t wrapped_key_in, cp_wrapped_key_t wrapped_key_out); |
39236c6e A |
164 | |
165 | ||
fe8ab488 A |
166 | /* |
167 | * Flags for Interaction between AKS / Kernel | |
168 | * These are twiddled via the input/output structs in the above | |
169 | * wrapper/unwrapper functions. | |
170 | */ | |
171 | #define CP_RAW_KEY_WRAPPEDKEY 0x00000001 | |
172 | ||
173 | ||
174 | /* | |
175 | * Flags for Key Generation Behavior | |
176 | * | |
177 | * These are passed to cp_generate_keys() and cp_new() in the | |
178 | * flags arguments | |
179 | */ | |
180 | #define CP_KEYWRAP_DIFFCLASS 0x00000001 /* wrapping with a different class bag is OK */ | |
39236c6e A |
181 | |
182 | ||
183 | /* | |
184 | * Runtime-only structure containing the content protection status | |
185 | * for the given file. This is contained within the cnode | |
316670eb A |
186 | * This is passed down to IOStorageFamily via the bufattr struct |
187 | * | |
188 | ****************************************************** | |
189 | * Some Key calculation information for offset based IV | |
190 | ****************************************************** | |
191 | * Kf = original 256 bit per file key | |
192 | * Kiv = SHA1(Kf), use full Kf, but truncate Kiv to 128 bits | |
193 | * Kiv can be cached in the cprotect, so it only has to be calculated once for the file init | |
194 | * | |
195 | * IVb = Encrypt(Kiv, offset) | |
196 | * | |
6d2010ae | 197 | */ |
d1ecb069 | 198 | struct cprotect { |
6d2010ae | 199 | uint32_t cp_flags; |
fe8ab488 | 200 | uint32_t cp_pclass; /* persistent class stored on-disk */ |
316670eb A |
201 | aes_encrypt_ctx cp_cache_iv_ctx; |
202 | uint32_t cp_cache_key_len; | |
fe8ab488 | 203 | uint8_t cp_cache_key[CP_MAX_CACHEBUFLEN]; |
316670eb | 204 | uint32_t cp_persistent_key_len; |
39236c6e | 205 | void* cp_backing_cnode; |
316670eb | 206 | uint8_t cp_persistent_key[]; |
d1ecb069 A |
207 | }; |
208 | ||
fe8ab488 | 209 | /* Structure to store pointers for AKS functions */ |
d1ecb069 | 210 | struct cp_wrap_func { |
39236c6e A |
211 | new_key_t *new_key; |
212 | unwrapper_t *unwrapper; | |
213 | rewrapper_t *rewrapper; | |
214 | invalidater_t *invalidater; | |
fe8ab488 | 215 | backup_key_t *backup_key; |
d1ecb069 A |
216 | }; |
217 | ||
6d2010ae | 218 | /* |
39236c6e | 219 | * On-disk structure written as the per-file EA payload |
6d2010ae A |
220 | * All on-disk multi-byte fields for the CP XATTR must be stored |
221 | * little-endian on-disk. This means they must be endian swapped to | |
39236c6e A |
222 | * L.E on getxattr() and converted to LE on setxattr(). |
223 | * | |
224 | * This structure is a fixed length and is tightly packed. | |
225 | * 56 bytes total. | |
6d2010ae | 226 | */ |
316670eb A |
227 | struct cp_xattr_v2 { |
228 | u_int16_t xattr_major_version; | |
229 | u_int16_t xattr_minor_version; | |
230 | u_int32_t flags; | |
231 | u_int32_t persistent_class; | |
232 | u_int32_t key_size; | |
233 | uint8_t persistent_key[CP_V2_WRAPPEDKEYSIZE]; | |
39236c6e A |
234 | } __attribute__((aligned(2), packed)); |
235 | ||
236 | ||
237 | /* | |
238 | * V4 Content Protection EA On-Disk Layout. | |
239 | * | |
240 | * This structure must be tightly packed, but the *size can vary* | |
241 | * depending on the length of the key. At MOST, the key length will be | |
242 | * CP_MAX_WRAPPEDKEYSIZE, but the length is defined by the key_size field. | |
243 | * | |
244 | * Either way, the packing must be applied to ensure that the key data is | |
245 | * retrievable in the right location relative to the start of the struct. | |
246 | * | |
247 | * Fully packed, this structure can range from : | |
248 | * MIN: 36 bytes (no key -- used with directories) | |
249 | * MAX: 164 bytes (with 128 byte key) | |
250 | * | |
251 | * During runtime we always allocate with the full 128 byte key, but only | |
252 | * use as much of the key buffer as needed. It must be tightly packed, though. | |
253 | */ | |
316670eb A |
254 | |
255 | struct cp_xattr_v4 { | |
256 | u_int16_t xattr_major_version; | |
257 | u_int16_t xattr_minor_version; | |
258 | u_int32_t flags; | |
259 | u_int32_t persistent_class; | |
260 | u_int32_t key_size; | |
39236c6e A |
261 | /* CP V4 Reserved Bytes == 20 */ |
262 | u_int8_t reserved[CP_V4_RESERVEDBYTES]; | |
263 | /* All above fields are fixed regardless of key length (36 bytes) */ | |
264 | /* Max Wrapped Size == 128 */ | |
316670eb | 265 | uint8_t persistent_key[CP_MAX_WRAPPEDKEYSIZE]; |
39236c6e | 266 | } __attribute__((aligned(2), packed)); |
d1ecb069 | 267 | |
39236c6e A |
268 | |
269 | /* | |
270 | * The Root Directory's EA (fileid 1) is special; it defines information about | |
271 | * what capabilities the filesystem is using. | |
272 | * | |
273 | * The data is still stored little endian. | |
274 | * | |
275 | * Note that this structure is tightly packed: 28 bytes total. | |
276 | */ | |
277 | struct cp_root_xattr { | |
278 | u_int16_t major_version; | |
279 | u_int16_t minor_version; | |
280 | u_int64_t flags; | |
281 | u_int8_t reserved[16]; | |
282 | } __attribute__((aligned(2), packed)); | |
6d2010ae A |
283 | |
284 | ||
39236c6e A |
285 | /* |
286 | * Functions to check the status of a CP and to query | |
6d2010ae A |
287 | * the containing filesystem to see if it is supported. |
288 | */ | |
289 | int cp_vnode_getclass(vnode_t, int *); | |
290 | int cp_vnode_setclass(vnode_t, uint32_t); | |
fe8ab488 | 291 | int cp_vnode_transcode(vnode_t vp, void *key, unsigned *len); |
6d2010ae | 292 | |
d1ecb069 A |
293 | int cp_key_store_action(int); |
294 | int cp_register_wraps(cp_wrap_func_t); | |
6d2010ae A |
295 | |
296 | int cp_entry_init(cnode_ptr_t, struct mount *); | |
316670eb | 297 | int cp_entry_gentempkeys(struct cprotect **entry_ptr, struct hfsmount *hfsmp); |
39236c6e A |
298 | int cp_needs_tempkeys (struct hfsmount *hfsmp, int* needs); |
299 | void cp_entry_destroy(struct cprotect *entry_ptr); | |
300 | void cp_replace_entry (struct cnode *cp, struct cprotect *newentry); | |
6d2010ae | 301 | cnode_ptr_t cp_get_protected_cnode(vnode_t); |
316670eb | 302 | int cp_handle_vnop(vnode_t, int, int); |
6d2010ae A |
303 | int cp_fs_protected (mount_t); |
304 | int cp_getrootxattr (struct hfsmount *hfsmp, struct cp_root_xattr *outxattr); | |
305 | int cp_setrootxattr (struct hfsmount *hfsmp, struct cp_root_xattr *newxattr); | |
316670eb | 306 | int cp_setxattr(struct cnode *cp, struct cprotect *entry, struct hfsmount *hfsmp, uint32_t fileid, int options); |
fe8ab488 A |
307 | int cp_generate_keys (struct hfsmount *hfsmp, struct cnode *cp, int targetclass, |
308 | uint32_t flags, struct cprotect **newentry); | |
39236c6e A |
309 | int cp_setup_newentry (struct hfsmount *hfsmp, struct cnode *dcp, int32_t suppliedclass, |
310 | mode_t cmode, struct cprotect **tmpentry); | |
316670eb A |
311 | int cp_handle_relocate (cnode_ptr_t cp, struct hfsmount *hfsmp); |
312 | int cp_handle_open(struct vnode *vp, int mode); | |
313 | int cp_get_root_major_vers (struct vnode *vp, uint32_t *level); | |
39236c6e A |
314 | int cp_get_default_level (struct vnode *vp, uint32_t *level); |
315 | int cp_is_valid_class (int isdir, int32_t protectionclass); | |
fe8ab488 A |
316 | int cp_set_trimmed(struct hfsmount *hfsmp); |
317 | int cp_set_rewrapped(struct hfsmount *hfsmp); | |
318 | int cp_flop_generation (struct hfsmount *hfsmp); | |
319 | ||
d1ecb069 A |
320 | |
321 | #endif /* KERNEL_PRIVATE */ | |
322 | ||
323 | #ifdef __cplusplus | |
324 | }; | |
325 | #endif | |
326 | ||
327 | #endif /* !_SYS_CPROTECT_H_ */ |