]> git.saurik.com Git - apple/xnu.git/blame - bsd/hfs/hfs_cprotect.h
xnu-3248.60.10.tar.gz
[apple/xnu.git] / bsd / hfs / hfs_cprotect.h
CommitLineData
3e170ce0
A
1/*
2 * Copyright (c) 2009-2015 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#ifndef HFS_CPROTECT_H_
30#define HFS_CPROTECT_H_
31
32#if KERNEL_PRIVATE
33
34#include <sys/cprotect.h>
35
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>
41
42#include "hfs.h"
43#include "hfs_fsctl.h"
44
45__BEGIN_DECLS
46
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 */
50
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 */
54
55#define CP_LOCKED_KEYCHAIN 0
56#define CP_UNLOCKED_KEYCHAIN 1
57
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
68
69/* the class occupies the lowest 5 bits, so there are 32 values (0-31) */
70#define CP_EFFECTIVE_CLASSMASK 0x0000001f
71
72typedef uint32_t cp_key_class_t;
73typedef uint32_t cp_key_os_version_t;
74
75/* macros for quick access/typing to mask out the classmask */
76#define CP_CLASS(x) ((cp_key_class_t)(CP_EFFECTIVE_CLASSMASK & (x)))
77
78#define CP_CRYPTO_G1 0x00000020
79
80typedef struct cp_xattr *cp_xattr_t;
81typedef struct cnode * cnode_ptr_t;
82//forward declare the struct.
83struct hfsmount;
84
85/*
86 * Flags for Key Generation Behavior
87 *
88 * These are passed to cp_generate_keys() and cp_new() in the
89 * flags arguments
90 */
91#define CP_KEYWRAP_DIFFCLASS 0x00000001 /* wrapping with a different class bag is OK */
92
93/*
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
96 * i.e.
97 *
98 * { 0, data-fork } < { 100, rsrc-fork }
99 */
100
101enum {
102 OFF_RSRC_BIT = 0x4000000000000000,
103};
104
105typedef int64_t off_rsrc_t;
106
107static inline bool off_rsrc_is_rsrc(off_rsrc_t off_rsrc)
108{
109 return off_rsrc & OFF_RSRC_BIT;
110}
111
112static inline off_t off_rsrc_get_off(off_rsrc_t off_rsrc)
113{
114 return off_rsrc & (OFF_RSRC_BIT - 1);
115}
116
117static inline off_rsrc_t off_rsrc_make(off_t offset, bool is_rsrc)
118{
119 return offset | (is_rsrc ? OFF_RSRC_BIT : 0);
120}
121
122// -- struct cpx --
123
124/*
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
127 * to read/write it.
128 */
129
130// cpx_flags
131typedef uint32_t cpx_flags_t;
132enum {
133 CPX_SEP_WRAPPEDKEY = 0x01,
134 CPX_IV_AES_CTX_INITIALIZED = 0x02,
135 CPX_USE_OFFSET_FOR_IV = 0x04,
136
137 // Using AES IV context generated from key
138 CPX_IV_AES_CTX_HFS = 0x08,
139};
140
141struct cpx {
142#if DEBUG
143 uint32_t cpx_magic1;
144#endif
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));
151
152// -- struct cp_key_pair --
153
154/*
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
157 * layers.
158 */
159
160typedef struct cp_key_pair {
161 uint16_t cpkp_max_pers_key_len;
162 uint16_t cpkp_pers_key_len;
163 struct cpx cpkp_cpx;
164
165 // cpkp_cpx is variable length so the location of the persistent key varies
166 // uint8_t cpkp_persistent_key[];
167} cp_key_pair_t;
168
169// -- struct cprotect --
170
171/*
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.
175 */
176
177typedef uint32_t cp_flags_t;
178enum {
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. */
181
182 CP_HAS_A_KEY = 0x08, /* File has a non-zero length key */
183};
184
185struct cprotect {
186#if DEBUG
187 uint32_t cp_magic1;
188#endif
189 cp_flags_t cp_flags;
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
196};
197
198// -- On-Disk Structures --
199
200typedef uint32_t cp_xattr_flags_t;
201enum {
202 /*
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:
206 *
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
212 *
213 */
214
215 CP_XAF_NEEDS_KEYS = 0x0001, /* V4 only: file needs persistent keys */
216
217};
218
219/*
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().
224 *
225 * This structure is a fixed length and is tightly packed.
226 * 56 bytes total.
227 */
228struct cp_xattr_v2 {
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;
233 u_int32_t key_size;
234 uint8_t persistent_key[CP_V2_WRAPPEDKEYSIZE];
235} __attribute__((aligned(2), packed));
236
237
238/*
239 * V4 Content Protection EA On-Disk Layout.
240 *
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.
244 *
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.
247 *
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)
251 *
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.
254 */
255
256struct cp_xattr_v4 {
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;
261 u_int32_t key_size;
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));
270
271// -- Version 5 --
272
273
274struct cp_xattr_v5 {
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;
281 uint16_t key_len;
282
283 // 20 bytes to here
284
285 // Variable length from here
286 uint8_t persistent_key[CP_MAX_WRAPPEDKEYSIZE];
287
288
289 // Wouldn't be necessary if xattr routines returned just what we ask for
290 uint8_t spare[512];
291} __attribute__((aligned(2), packed));
292
293enum {
294 CP_XATTR_MIN_LEN = 20, // Minimum length for all versions
295};
296
297/*
298 * The Root Directory's EA (fileid 1) is special; it defines information about
299 * what capabilities the filesystem is using.
300 *
301 * The data is still stored little endian.
302 */
303struct cp_root_xattr {
304 u_int16_t major_version;
305 u_int16_t minor_version;
306 u_int64_t flags;
307} __attribute__((aligned(2), packed));
308
309enum {
310 CP_ROOT_XATTR_MIN_LEN = 12,
311};
312
313
314// -- Function Prototypes --
315
316int cp_entry_init(cnode_ptr_t, struct mount *);
317int cpx_gentempkeys(cpx_t *pcpx, struct hfsmount *hfsmp);
318void cp_entry_destroy(struct hfsmount *hfsmp, struct cprotect *entry_ptr);
319void cp_replace_entry (struct hfsmount *hfsmp, struct cnode *cp, struct cprotect *newentry);
320cnode_ptr_t cp_get_protected_cnode(vnode_t);
321int cp_fs_protected (mount_t);
322int cp_getrootxattr (struct hfsmount *hfsmp, struct cp_root_xattr *outxattr);
323int cp_setrootxattr (struct hfsmount *hfsmp, struct cp_root_xattr *newxattr);
324int cp_generate_keys (struct hfsmount *hfsmp, struct cnode *cp,
325 cp_key_class_t targetclass, uint32_t flags,
326 struct cprotect **newentry);
327int cp_setup_newentry (struct hfsmount *hfsmp, struct cnode *dcp,
328 cp_key_class_t suppliedclass, mode_t cmode,
329 struct cprotect **tmpentry);
330int cp_is_valid_class (int isdir, int32_t protectionclass);
331int cp_set_trimmed(struct hfsmount*);
332int cp_set_rewrapped(struct hfsmount *);
333int cp_flop_generation (struct hfsmount*);
334bool cp_is_supported_version(uint16_t version);
335
336
337typedef struct cp_io_params {
338 // The key to use
339 cpx_t cpx;
340
341 /*
342 * The physical offset for this I/O or -1 if unknown (i.e. caller must
343 * do a regular look up).
344 */
345 off_t phys_offset;
346
347 // The maximum length allowed for this I/O
348 off_t max_len;
349} cp_io_params_t;
350
351// Return the I/O parameters for this I/O
352void cp_io_params(struct hfsmount *hfsmp, cprotect_t cpr, off_rsrc_t off_rsrc,
353 int direction, cp_io_params_t *io_params);
354
355int cp_setxattr(struct cnode *cp, struct cprotect *entry, struct hfsmount *hfsmp,
356 uint32_t fileid, int xattr_opts);
357
358typedef 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);
361
362int 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);
366
367int 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);
370
371cprotect_t cp_entry_alloc(cprotect_t old, uint16_t pers_keylen,
372 uint16_t cached_key_len, cp_key_pair_t **pcpkp);
373
374cp_key_os_version_t cp_os_version(void);
375
376cp_key_revision_t cp_next_key_revision(cp_key_revision_t rev);
377
378typedef uint32_t cp_getxattr_options_t;
379enum {
380 // Return just basic information (not the key)
381 CP_GET_XATTR_BASIC_INFO = 1,
382};
383
384int 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);
386
387
388errno_t cp_handle_strategy(buf_t bp);
389
390// -- cp_key_pair_t functions --
391
392size_t cpkp_size(uint16_t pers_key_len, uint16_t cached_key_len);
393size_t cpkp_sizex(const cp_key_pair_t *cpkp);
394void cpkp_init(cp_key_pair_t *cpkp, uint16_t max_pers_key_len,
395 uint16_t max_cached_key_len);
396void cpkp_flush(cp_key_pair_t *cpkp);
397void cpkp_copy(const cp_key_pair_t *src, cp_key_pair_t *dst);
398uint16_t cpkp_max_pers_key_len(const cp_key_pair_t *cpkp);
399uint16_t cpkp_pers_key_len(const cp_key_pair_t *cpkp);
400bool cpkp_can_copy(const cp_key_pair_t *src, const cp_key_pair_t *dst);
401
402// -- Private cpx functions --
403
404void cpx_init(cpx_t, size_t key_len);
405bool cpx_has_key(const struct cpx *cpx);
406uint16_t cpx_max_key_len(const struct cpx *cpx);
407cpx_t cpkp_cpx(const cp_key_pair_t *cpkp);
408void cpx_copy(const struct cpx *src, cpx_t dst);
409
410// -- Helper Functions --
411
412static inline int cp_get_crypto_generation (cp_key_class_t protclass) {
413 if (protclass & CP_CRYPTO_G1) {
414 return 1;
415 }
416 else return 0;
417}
418
419__END_DECLS
420
421#endif /* KERNEL_PRIVATE */
422
423#endif /* !HFS_CPROTECT_H_ */