2 * Copyright (c) 2009-2015 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #ifndef HFS_CPROTECT_H_
30 #define HFS_CPROTECT_H_
34 #include <sys/cprotect.h>
36 #include <sys/cdefs.h>
37 #include <sys/content_protection.h>
38 #include <sys/kernel_types.h>
39 #include <crypto/aes.h>
40 #include <sys/kdebug.h>
43 #include "hfs_fsctl.h"
47 #define CP_IV_KEYSIZE 16 /* 16x8 = 128 */
48 #define CP_MAX_KEYSIZE 32 /* 8x4 = 32, 32x8 = 256 */
49 #define CP_MAX_CACHEBUFLEN 64 /* Maximum size of cp cache buffer/array */
51 #define CP_INITIAL_WRAPPEDKEYSIZE 40
52 #define CP_V2_WRAPPEDKEYSIZE 40 /* Size of the wrapped key in a v2 EA */
53 #define CP_V4_RESERVEDBYTES 16 /* Number of reserved bytes in EA still present */
55 #define CP_LOCKED_KEYCHAIN 0
56 #define CP_UNLOCKED_KEYCHAIN 1
58 #define CONTENT_PROTECTION_XATTR_NAME "com.apple.system.cprotect"
59 #define CONTENT_PROTECTION_XATTR_NAME_CHARS \
60 { 'c', 'o', 'm', '.', 'a', 'p', 'p', 'l', 'e', \
61 '.', 's', 'y', 's', 't', 'e', 'm', \
62 '.', 'c', 'p', 'r', 'o', 't', 'e', 'c', 't' }
63 #define CP_CURRENT_VERS CP_VERS_5
64 #define CP_VERS_5 5 // iOS 8.1
65 #define CP_VERS_4 4 // iOS 5
66 #define CP_VERS_2 2 // iOS 4
67 #define CP_MINOR_VERS 0
69 /* the class occupies the lowest 5 bits, so there are 32 values (0-31) */
70 #define CP_EFFECTIVE_CLASSMASK 0x0000001f
72 typedef uint32_t cp_key_class_t
;
73 typedef uint32_t cp_key_os_version_t
;
75 /* macros for quick access/typing to mask out the classmask */
76 #define CP_CLASS(x) ((cp_key_class_t)(CP_EFFECTIVE_CLASSMASK & (x)))
78 #define CP_CRYPTO_G1 0x00000020
80 typedef struct cp_xattr
*cp_xattr_t
;
81 typedef struct cnode
* cnode_ptr_t
;
82 //forward declare the struct.
86 * Flags for Key Generation Behavior
88 * These are passed to cp_generate_keys() and cp_new() in the
91 #define CP_KEYWRAP_DIFFCLASS 0x00000001 /* wrapping with a different class bag is OK */
94 * off_rsrc_t: this structure represents an offset and whether or not it's
95 * the resource fork. It's done this way so that we can easily do comparisons
98 * { 0, data-fork } < { 100, rsrc-fork }
102 OFF_RSRC_BIT
= 0x4000000000000000,
105 typedef int64_t off_rsrc_t
;
107 static inline bool off_rsrc_is_rsrc(off_rsrc_t off_rsrc
)
109 return off_rsrc
& OFF_RSRC_BIT
;
112 static inline off_t
off_rsrc_get_off(off_rsrc_t off_rsrc
)
114 return off_rsrc
& (OFF_RSRC_BIT
- 1);
117 static inline off_rsrc_t
off_rsrc_make(off_t offset
, bool is_rsrc
)
119 return offset
| (is_rsrc
? OFF_RSRC_BIT
: 0);
125 * This structure contains the unwrapped key and is passed to the lower layers.
126 * It is private so users must use the accessors declared in sys/cprotect.h
131 typedef uint32_t cpx_flags_t
;
133 CPX_SEP_WRAPPEDKEY
= 0x01,
134 CPX_IV_AES_CTX_INITIALIZED
= 0x02,
135 CPX_USE_OFFSET_FOR_IV
= 0x04,
137 // Using AES IV context generated from key
138 CPX_IV_AES_CTX_HFS
= 0x08,
145 cpx_flags_t cpx_flags
;
146 uint16_t cpx_max_key_len
;
147 uint16_t cpx_key_len
;
148 aes_encrypt_ctx cpx_iv_aes_ctx
; // Context used for generating the IV
149 uint8_t cpx_cached_key
[];
150 } __attribute__((packed
));
152 // -- struct cp_key_pair --
155 * This structure maintains the pair of keys; the persistent, wrapped key that
156 * is written to disk, and the unwrapped key (cpx_t) that we pass to lower
160 typedef struct cp_key_pair
{
161 uint16_t cpkp_max_pers_key_len
;
162 uint16_t cpkp_pers_key_len
;
165 // cpkp_cpx is variable length so the location of the persistent key varies
166 // uint8_t cpkp_persistent_key[];
169 // -- struct cprotect --
172 * Runtime-only structure containing the content protection status for
173 * the given file. This is referenced by the cnode. It has the
174 * variable length key pair at the end.
177 typedef uint32_t cp_flags_t
;
179 CP_NO_XATTR
= 0x01, /* Key info has not been saved as EA to the FS */
180 CP_RELOCATION_INFLIGHT
= 0x02, /* File with offset IVs is in the process of being relocated. */
182 CP_HAS_A_KEY
= 0x08, /* File has a non-zero length key */
190 cp_key_class_t cp_pclass
; /* persistent class stored on-disk */
191 void* cp_backing_cnode
;
192 cp_key_os_version_t cp_key_os_version
;
193 cp_key_revision_t cp_key_revision
;
194 uint16_t cp_raw_open_count
;
195 cp_key_pair_t cp_keys
; // Variable length
198 // -- On-Disk Structures --
200 typedef uint32_t cp_xattr_flags_t
;
203 * Be careful about using flags 0x02 to 0x20. Older code used to write
204 * flags that were used for in-memory purposes to disk and therefore
205 * they might be used in V4 structures. Here's what they were:
207 * CP_KEY_FLUSHED 0x02 Should never have made it to disk
208 * CP_NO_XATTR 0x04 Should never have made it to disk
209 * CP_OFF_IV_ENABLED 0x08 Probably made it to disk
210 * CP_RELOCATION_INFLIGHT 0x10 Should never have made it to disk
211 * CP_SEP_WRAPPEDKEY 0x20 Probably made it to disk
215 CP_XAF_NEEDS_KEYS
= 0x0001, /* V4 only: file needs persistent keys */
220 * V2 structure written as the per-file EA payload
221 * All on-disk multi-byte fields for the CP XATTR must be stored
222 * little-endian on-disk. This means they must be endian swapped to
223 * L.E on getxattr() and converted to LE on setxattr().
225 * This structure is a fixed length and is tightly packed.
229 u_int16_t xattr_major_version
;
230 u_int16_t xattr_minor_version
;
231 cp_xattr_flags_t flags
;
232 u_int32_t persistent_class
;
234 uint8_t persistent_key
[CP_V2_WRAPPEDKEYSIZE
];
235 } __attribute__((aligned(2), packed
));
239 * V4 Content Protection EA On-Disk Layout.
241 * This structure must be tightly packed, but the *size can vary*
242 * depending on the length of the key. At MOST, the key length will be
243 * CP_MAX_WRAPPEDKEYSIZE, but the length is defined by the key_size field.
245 * Either way, the packing must be applied to ensure that the key data is
246 * retrievable in the right location relative to the start of the struct.
248 * Fully packed, this structure can range from :
249 * MIN: 36 bytes (no key -- used with directories)
250 * MAX: 164 bytes (with 128 byte key)
252 * During runtime we always allocate with the full 128 byte key, but only
253 * use as much of the key buffer as needed. It must be tightly packed, though.
257 u_int16_t xattr_major_version
;
258 u_int16_t xattr_minor_version
;
259 cp_xattr_flags_t flags
;
260 cp_key_class_t persistent_class
;
262 // This field will be zero on older systems
263 cp_key_os_version_t key_os_version
;
264 /* CP V4 Reserved Bytes == 16 */
265 u_int8_t reserved
[CP_V4_RESERVEDBYTES
];
266 /* All above fields are fixed regardless of key length (36 bytes) */
267 /* Max Wrapped Size == 128 */
268 uint8_t persistent_key
[CP_MAX_WRAPPEDKEYSIZE
];
269 } __attribute__((aligned(2), packed
));
275 uint16_t xattr_major_version
;
276 uint16_t xattr_minor_version
;
277 cp_xattr_flags_t flags
;
278 cp_key_class_t persistent_class
;
279 cp_key_os_version_t key_os_version
;
280 cp_key_revision_t key_revision
;
285 // Variable length from here
286 uint8_t persistent_key
[CP_MAX_WRAPPEDKEYSIZE
];
289 // Wouldn't be necessary if xattr routines returned just what we ask for
291 } __attribute__((aligned(2), packed
));
294 CP_XATTR_MIN_LEN
= 20, // Minimum length for all versions
298 * The Root Directory's EA (fileid 1) is special; it defines information about
299 * what capabilities the filesystem is using.
301 * The data is still stored little endian.
303 struct cp_root_xattr
{
304 u_int16_t major_version
;
305 u_int16_t minor_version
;
307 } __attribute__((aligned(2), packed
));
310 CP_ROOT_XATTR_MIN_LEN
= 12,
314 // -- Function Prototypes --
316 int cp_entry_init(cnode_ptr_t
, struct mount
*);
317 int cpx_gentempkeys(cpx_t
*pcpx
, struct hfsmount
*hfsmp
);
318 void cp_entry_destroy(struct hfsmount
*hfsmp
, struct cprotect
*entry_ptr
);
319 void cp_replace_entry (struct hfsmount
*hfsmp
, struct cnode
*cp
, struct cprotect
*newentry
);
320 cnode_ptr_t
cp_get_protected_cnode(vnode_t
);
321 int cp_fs_protected (mount_t
);
322 int cp_getrootxattr (struct hfsmount
*hfsmp
, struct cp_root_xattr
*outxattr
);
323 int cp_setrootxattr (struct hfsmount
*hfsmp
, struct cp_root_xattr
*newxattr
);
324 int cp_generate_keys (struct hfsmount
*hfsmp
, struct cnode
*cp
,
325 cp_key_class_t targetclass
, uint32_t flags
,
326 struct cprotect
**newentry
);
327 int cp_setup_newentry (struct hfsmount
*hfsmp
, struct cnode
*dcp
,
328 cp_key_class_t suppliedclass
, mode_t cmode
,
329 struct cprotect
**tmpentry
);
330 int cp_is_valid_class (int isdir
, int32_t protectionclass
);
331 int cp_set_trimmed(struct hfsmount
*);
332 int cp_set_rewrapped(struct hfsmount
*);
333 int cp_flop_generation (struct hfsmount
*);
334 bool cp_is_supported_version(uint16_t version
);
337 typedef struct cp_io_params
{
342 * The physical offset for this I/O or -1 if unknown (i.e. caller must
343 * do a regular look up).
347 // The maximum length allowed for this I/O
351 // Return the I/O parameters for this I/O
352 void cp_io_params(struct hfsmount
*hfsmp
, cprotect_t cpr
, off_rsrc_t off_rsrc
,
353 int direction
, cp_io_params_t
*io_params
);
355 int cp_setxattr(struct cnode
*cp
, struct cprotect
*entry
, struct hfsmount
*hfsmp
,
356 uint32_t fileid
, int xattr_opts
);
358 typedef void * (* cp_new_alloc_fn
)(const void *old
, uint16_t pers_key_len
,
359 uint16_t cached_key_len
,
360 cp_key_pair_t
**pcpkp
);
362 int cp_new(cp_key_class_t
*newclass_eff
, struct hfsmount
*hfsmp
,
363 struct cnode
*cp
, mode_t cmode
, int32_t keyflags
,
364 cp_key_revision_t key_revision
,
365 cp_new_alloc_fn alloc_fn
, void **pholder
);
367 int cp_rewrap(struct cnode
*cp
, __unused
struct hfsmount
*hfsmp
,
368 cp_key_class_t
*newclass
, cp_key_pair_t
*cpkp
, const void *old_holder
,
369 cp_new_alloc_fn alloc_fn
, void **pholder
);
371 cprotect_t
cp_entry_alloc(cprotect_t old
, uint16_t pers_keylen
,
372 uint16_t cached_key_len
, cp_key_pair_t
**pcpkp
);
374 cp_key_os_version_t
cp_os_version(void);
376 cp_key_revision_t
cp_next_key_revision(cp_key_revision_t rev
);
378 typedef uint32_t cp_getxattr_options_t
;
380 // Return just basic information (not the key)
381 CP_GET_XATTR_BASIC_INFO
= 1,
384 int cp_read_xattr_v5(struct hfsmount
*hfsmp
, struct cp_xattr_v5
*xattr
,
385 size_t xattr_len
, cprotect_t
*pcpr
, cp_getxattr_options_t options
);
388 errno_t
cp_handle_strategy(buf_t bp
);
390 // -- cp_key_pair_t functions --
392 size_t cpkp_size(uint16_t pers_key_len
, uint16_t cached_key_len
);
393 size_t cpkp_sizex(const cp_key_pair_t
*cpkp
);
394 void cpkp_init(cp_key_pair_t
*cpkp
, uint16_t max_pers_key_len
,
395 uint16_t max_cached_key_len
);
396 void cpkp_flush(cp_key_pair_t
*cpkp
);
397 void cpkp_copy(const cp_key_pair_t
*src
, cp_key_pair_t
*dst
);
398 uint16_t cpkp_max_pers_key_len(const cp_key_pair_t
*cpkp
);
399 uint16_t cpkp_pers_key_len(const cp_key_pair_t
*cpkp
);
400 bool cpkp_can_copy(const cp_key_pair_t
*src
, const cp_key_pair_t
*dst
);
402 // -- Private cpx functions --
404 void cpx_init(cpx_t
, size_t key_len
);
405 bool cpx_has_key(const struct cpx
*cpx
);
406 uint16_t cpx_max_key_len(const struct cpx
*cpx
);
407 cpx_t
cpkp_cpx(const cp_key_pair_t
*cpkp
);
408 void cpx_copy(const struct cpx
*src
, cpx_t dst
);
410 // -- Helper Functions --
412 static inline int cp_get_crypto_generation (cp_key_class_t protclass
) {
413 if (protclass
& CP_CRYPTO_G1
) {
421 #endif /* KERNEL_PRIVATE */
423 #endif /* !HFS_CPROTECT_H_ */