2 * Copyright (c) 2000-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@
30 #include <sys/mount.h>
31 #include <sys/random.h>
32 #include <sys/xattr.h>
33 #include <sys/uio_internal.h>
34 #include <sys/ubc_internal.h>
35 #include <sys/vnode_if.h>
36 #include <sys/vnode_internal.h>
37 #include <sys/fcntl.h>
38 #include <libkern/OSByteOrder.h>
39 #include <libkern/crypto/sha1.h>
41 #include <sys/kauth.h>
44 #include "hfs_cnode.h"
45 #include "hfs_fsctl.h"
46 #include "hfs_cprotect.h"
49 #define PTR_ADD(type, base, offset) (type)((uintptr_t)(base) + (offset))
52 * The wrap function pointers and the variable to indicate if they
53 * are initialized are system-wide, and hence are defined globally.
55 static struct cp_wrap_func g_cp_wrap_func
= {};
56 static int are_wraps_initialized
= false;
58 extern int (**hfs_vnodeop_p
) (void *);
61 * CP private functions
63 static int cp_root_major_vers(mount_t mp
);
64 static int cp_getxattr(cnode_t
*, struct hfsmount
*hfsmp
, struct cprotect
**);
65 static void cp_entry_dealloc(hfsmount_t
*hfsmp
, struct cprotect
*entry
);
66 static int cp_restore_keys(struct cprotect
*, struct hfsmount
*hfsmp
, struct cnode
*);
67 static int cp_lock_vfs_callback(mount_t
, void *);
68 static int cp_lock_vnode_callback(vnode_t
, void *);
69 static int cp_vnode_is_eligible (vnode_t
);
70 static int cp_check_access (cnode_t
*cp
, struct hfsmount
*hfsmp
, int vnop
);
71 static int cp_unwrap(struct hfsmount
*, struct cprotect
*, struct cnode
*);
72 static void cp_init_access(cp_cred_t access
, struct cnode
*cp
);
75 #if DEVELOPMENT || DEBUG
76 #define CP_ASSERT(x) \
78 panic("Content Protection: failed assertion in %s", __FUNCTION__); \
84 // -- cpx_t accessors --
86 size_t cpx_size(size_t key_size
)
88 size_t size
= sizeof(struct cpx
) + key_size
;
91 size
+= 4; // Extra for magic
97 static size_t cpx_sizex(const struct cpx
*cpx
)
99 return cpx_size(cpx
->cpx_max_key_len
);
102 cpx_t
cpx_alloc(size_t key_len
)
106 MALLOC(cpx
, cpx_t
, cpx_size(key_len
), M_TEMP
, M_WAITOK
);
108 cpx_init(cpx
, key_len
);
114 static const uint32_t cpx_magic1
= 0x7b787063; // cpx{
115 static const uint32_t cpx_magic2
= 0x7870637d; // }cpx
118 void cpx_free(cpx_t cpx
)
121 assert(cpx
->cpx_magic1
== cpx_magic1
);
122 assert(*PTR_ADD(uint32_t *, cpx
, cpx_sizex(cpx
) - 4) == cpx_magic2
);
124 bzero(cpx
->cpx_cached_key
, cpx
->cpx_max_key_len
);
128 void cpx_init(cpx_t cpx
, size_t key_len
)
131 cpx
->cpx_magic1
= cpx_magic1
;
132 *PTR_ADD(uint32_t *, cpx
, cpx_size(key_len
) - 4) = cpx_magic2
;
135 cpx
->cpx_key_len
= 0;
136 cpx
->cpx_max_key_len
= key_len
;
139 bool cpx_is_sep_wrapped_key(const struct cpx
*cpx
)
141 return ISSET(cpx
->cpx_flags
, CPX_SEP_WRAPPEDKEY
);
144 void cpx_set_is_sep_wrapped_key(struct cpx
*cpx
, bool v
)
147 SET(cpx
->cpx_flags
, CPX_SEP_WRAPPEDKEY
);
149 CLR(cpx
->cpx_flags
, CPX_SEP_WRAPPEDKEY
);
152 bool cpx_use_offset_for_iv(const struct cpx
*cpx
)
154 return ISSET(cpx
->cpx_flags
, CPX_USE_OFFSET_FOR_IV
);
157 void cpx_set_use_offset_for_iv(struct cpx
*cpx
, bool v
)
160 SET(cpx
->cpx_flags
, CPX_USE_OFFSET_FOR_IV
);
162 CLR(cpx
->cpx_flags
, CPX_USE_OFFSET_FOR_IV
);
165 uint16_t cpx_max_key_len(const struct cpx
*cpx
)
167 return cpx
->cpx_max_key_len
;
170 uint16_t cpx_key_len(const struct cpx
*cpx
)
172 return cpx
->cpx_key_len
;
175 void cpx_set_key_len(struct cpx
*cpx
, uint16_t key_len
)
177 cpx
->cpx_key_len
= key_len
;
179 if (ISSET(cpx
->cpx_flags
, CPX_IV_AES_CTX_HFS
)) {
181 * We assume that if the key length is being modified, the key
182 * has changed. As a result, un-set any bits related to the
183 * AES context, if needed. They should be re-generated
186 CLR(cpx
->cpx_flags
, CPX_IV_AES_CTX_INITIALIZED
| CPX_IV_AES_CTX_HFS
);
190 bool cpx_has_key(const struct cpx
*cpx
)
192 return cpx
->cpx_key_len
> 0;
195 #pragma clang diagnostic push
196 #pragma clang diagnostic ignored "-Wcast-qual"
197 void *cpx_key(const struct cpx
*cpx
)
199 return (void *)cpx
->cpx_cached_key
;
201 #pragma clang diagnostic pop
203 static void cpx_set_aes_iv_key(struct cpx
*cpx
, void *iv_key
)
205 aes_encrypt_key128(iv_key
, &cpx
->cpx_iv_aes_ctx
);
206 SET(cpx
->cpx_flags
, CPX_IV_AES_CTX_INITIALIZED
| CPX_USE_OFFSET_FOR_IV
);
207 CLR(cpx
->cpx_flags
, CPX_IV_AES_CTX_HFS
);
210 aes_encrypt_ctx
*cpx_iv_aes_ctx(struct cpx
*cpx
)
212 if (ISSET(cpx
->cpx_flags
, CPX_IV_AES_CTX_INITIALIZED
))
213 return &cpx
->cpx_iv_aes_ctx
;
216 uint8_t digest
[SHA_DIGEST_LENGTH
]; /* Kiv */
218 /* First init the cp_cache_iv_key[] */
222 * We can only use this when the keys are generated in the AP; As a result
223 * we only use the first 32 bytes of key length in the cache key
225 SHA1Update(&sha1ctxt
, cpx
->cpx_cached_key
, cpx
->cpx_key_len
);
226 SHA1Final(digest
, &sha1ctxt
);
228 cpx_set_aes_iv_key(cpx
, digest
);
229 SET(cpx
->cpx_flags
, CPX_IV_AES_CTX_HFS
);
231 return &cpx
->cpx_iv_aes_ctx
;
234 static void cpx_flush(cpx_t cpx
)
236 bzero(cpx
->cpx_cached_key
, cpx
->cpx_max_key_len
);
237 bzero(&cpx
->cpx_iv_aes_ctx
, sizeof(cpx
->cpx_iv_aes_ctx
));
239 cpx
->cpx_key_len
= 0;
242 static bool cpx_can_copy(const struct cpx
*src
, const struct cpx
*dst
)
244 return src
->cpx_key_len
<= dst
->cpx_max_key_len
;
247 void cpx_copy(const struct cpx
*src
, cpx_t dst
)
249 uint16_t key_len
= cpx_key_len(src
);
250 cpx_set_key_len(dst
, key_len
);
251 memcpy(cpx_key(dst
), cpx_key(src
), key_len
);
252 dst
->cpx_flags
= src
->cpx_flags
;
253 if (ISSET(dst
->cpx_flags
, CPX_IV_AES_CTX_INITIALIZED
))
254 dst
->cpx_iv_aes_ctx
= src
->cpx_iv_aes_ctx
;
257 // -- cp_key_pair accessors --
259 void cpkp_init(cp_key_pair_t
*cpkp
, uint16_t max_pers_key_len
,
260 uint16_t max_cached_key_len
)
262 cpkp
->cpkp_max_pers_key_len
= max_pers_key_len
;
263 cpkp
->cpkp_pers_key_len
= 0;
264 cpx_init(&cpkp
->cpkp_cpx
, max_cached_key_len
);
266 // Default to using offsets
267 cpx_set_use_offset_for_iv(&cpkp
->cpkp_cpx
, true);
270 uint16_t cpkp_max_pers_key_len(const cp_key_pair_t
*cpkp
)
272 return cpkp
->cpkp_max_pers_key_len
;
275 uint16_t cpkp_pers_key_len(const cp_key_pair_t
*cpkp
)
277 return cpkp
->cpkp_pers_key_len
;
280 static bool cpkp_has_pers_key(const cp_key_pair_t
*cpkp
)
282 return cpkp
->cpkp_pers_key_len
> 0;
285 static void *cpkp_pers_key(const cp_key_pair_t
*cpkp
)
287 return PTR_ADD(void *, &cpkp
->cpkp_cpx
, cpx_sizex(&cpkp
->cpkp_cpx
));
290 static void cpkp_set_pers_key_len(cp_key_pair_t
*cpkp
, uint16_t key_len
)
292 if (key_len
> cpkp
->cpkp_max_pers_key_len
)
293 panic("hfs_cprotect: key too big!");
294 cpkp
->cpkp_pers_key_len
= key_len
;
297 #pragma clang diagnostic push
298 #pragma clang diagnostic ignored "-Wcast-qual"
299 cpx_t
cpkp_cpx(const cp_key_pair_t
*cpkp
)
301 // Cast to remove const qualifier
302 return (cpx_t
)&cpkp
->cpkp_cpx
;
304 #pragma clang diagnostic pop
306 size_t cpkp_size(uint16_t pers_key_len
, uint16_t cached_key_len
)
308 return (sizeof(cp_key_pair_t
) - sizeof(struct cpx
)
309 + pers_key_len
+ cpx_size(cached_key_len
));
312 size_t cpkp_sizex(const cp_key_pair_t
*cpkp
)
314 return cpkp_size(cpkp
->cpkp_max_pers_key_len
, cpkp
->cpkp_cpx
.cpx_max_key_len
);
317 void cpkp_flush(cp_key_pair_t
*cpkp
)
319 cpx_flush(&cpkp
->cpkp_cpx
);
320 cpkp
->cpkp_pers_key_len
= 0;
321 bzero(cpkp_pers_key(cpkp
), cpkp
->cpkp_max_pers_key_len
);
324 bool cpkp_can_copy(const cp_key_pair_t
*src
, const cp_key_pair_t
*dst
)
326 return (cpkp_pers_key_len(src
) <= dst
->cpkp_max_pers_key_len
327 && cpx_can_copy(&src
->cpkp_cpx
, &dst
->cpkp_cpx
));
330 void cpkp_copy(const cp_key_pair_t
*src
, cp_key_pair_t
*dst
)
332 const uint16_t key_len
= cpkp_pers_key_len(src
);
333 cpkp_set_pers_key_len(dst
, key_len
);
334 memcpy(cpkp_pers_key(dst
), cpkp_pers_key(src
), key_len
);
335 cpx_copy(&src
->cpkp_cpx
, &dst
->cpkp_cpx
);
340 bool cp_is_supported_version(uint16_t vers
)
342 return vers
== CP_VERS_4
|| vers
== CP_VERS_5
;
346 * Return the appropriate key and, if requested, the physical offset and
347 * maximum length for a particular I/O operation.
349 void cp_io_params(__unused hfsmount_t
*hfsmp
, cprotect_t cpr
,
350 __unused off_rsrc_t off_rsrc
,
351 __unused
int direction
, cp_io_params_t
*io_params
)
354 io_params
->max_len
= INT64_MAX
;
355 io_params
->phys_offset
= -1;
356 io_params
->cpx
= cpkp_cpx(&cpr
->cp_keys
);
359 static void cp_flush_cached_keys(cprotect_t cpr
)
361 cpx_flush(cpkp_cpx(&cpr
->cp_keys
));
364 static bool cp_needs_pers_key(cprotect_t cpr
)
366 if (CP_CLASS(cpr
->cp_pclass
) == PROTECTION_CLASS_F
)
367 return !cpx_has_key(cpkp_cpx(&cpr
->cp_keys
));
369 return !cpkp_has_pers_key(&cpr
->cp_keys
);
373 cp_key_store_action(int action
)
376 if (action
< 0 || action
> CP_MAX_STATE
) {
381 * The lock state is kept locally to each data protected filesystem to
382 * avoid using globals. Pass along the lock request to each filesystem
383 * we iterate through.
387 * Upcast the value in 'action' to be a pointer-width unsigned integer.
388 * This avoids issues relating to pointer-width.
390 return vfs_iterate(0, cp_lock_vfs_callback
, (void*)(uintptr_t)action
);
395 cp_register_wraps(cp_wrap_func_t key_store_func
)
397 g_cp_wrap_func
.new_key
= key_store_func
->new_key
;
398 g_cp_wrap_func
.unwrapper
= key_store_func
->unwrapper
;
399 g_cp_wrap_func
.rewrapper
= key_store_func
->rewrapper
;
400 /* do not use invalidater until rdar://12170050 goes in ! */
401 g_cp_wrap_func
.invalidater
= key_store_func
->invalidater
;
402 g_cp_wrap_func
.backup_key
= key_store_func
->backup_key
;
404 /* Mark the functions as initialized in the function pointer container */
405 are_wraps_initialized
= true;
410 static cp_key_revision_t
cp_initial_key_revision(__unused hfsmount_t
*hfsmp
)
415 cp_key_revision_t
cp_next_key_revision(cp_key_revision_t rev
)
417 rev
= (rev
+ 0x0100) ^ (mach_absolute_time() & 0xff);
424 * Allocate and initialize a cprotect blob for a new cnode.
425 * Called from hfs_getnewvnode: cnode is locked exclusive.
427 * Read xattr data off the cnode. Then, if conditions permit,
428 * unwrap the file key and cache it in the cprotect blob.
431 cp_entry_init(struct cnode
*cp
, struct mount
*mp
)
433 struct cprotect
*entry
= NULL
;
435 struct hfsmount
*hfsmp
= VFSTOHFS(mp
);
438 * The cnode should be locked at this point, regardless of whether or not
439 * we are creating a new item in the namespace or vending a vnode on behalf
440 * of lookup. The only time we tell getnewvnode to skip the lock is when
441 * constructing a resource fork vnode. But a resource fork vnode must come
442 * after the regular data fork cnode has already been constructed.
444 if (!cp_fs_protected (mp
)) {
445 cp
->c_cpentry
= NULL
;
449 if (!S_ISREG(cp
->c_mode
) && !S_ISDIR(cp
->c_mode
)) {
450 cp
->c_cpentry
= NULL
;
454 if (are_wraps_initialized
== false) {
455 printf("hfs: cp_update_entry: wrap functions not yet set\n");
459 if (hfsmp
->hfs_running_cp_major_vers
== 0) {
460 panic ("hfs cp: no running mount point version! ");
463 CP_ASSERT (cp
->c_cpentry
== NULL
);
465 error
= cp_getxattr(cp
, hfsmp
, &entry
);
466 if (error
== ENOATTR
) {
468 * Normally, we should always have a CP EA for a file or directory that
469 * we are initializing here. However, there are some extenuating circumstances,
470 * such as the root directory immediately following a newfs_hfs.
472 * As a result, we leave code here to deal with an ENOATTR which will always
473 * default to a 'D/NONE' key, though we don't expect to use it much.
475 cp_key_class_t target_class
= PROTECTION_CLASS_D
;
477 if (S_ISDIR(cp
->c_mode
)) {
478 target_class
= PROTECTION_CLASS_DIR_NONE
;
481 cp_key_revision_t key_revision
= cp_initial_key_revision(hfsmp
);
483 /* allow keybag to override our class preferences */
484 error
= cp_new (&target_class
, hfsmp
, cp
, cp
->c_mode
, CP_KEYWRAP_DIFFCLASS
,
485 key_revision
, (cp_new_alloc_fn
)cp_entry_alloc
, (void **)&entry
);
487 entry
->cp_pclass
= target_class
;
488 entry
->cp_key_os_version
= cp_os_version();
489 entry
->cp_key_revision
= key_revision
;
490 error
= cp_setxattr (cp
, entry
, hfsmp
, cp
->c_fileid
, XATTR_CREATE
);
496 * a) error was not ENOATTR (we got something bad from the getxattr call)
497 * b) we encountered an error setting the xattr above.
498 * c) we failed to generate a new cprotect data structure.
504 cp
->c_cpentry
= entry
;
508 entry
->cp_backing_cnode
= cp
;
512 cp_entry_destroy(hfsmp
, entry
);
514 cp
->c_cpentry
= NULL
;
523 * Generate a keyless cprotect structure for use with the new AppleKeyStore kext.
524 * Since the kext is now responsible for vending us both wrapped/unwrapped keys
525 * we need to create a keyless xattr upon file / directory creation. When we have the inode value
526 * and the file/directory is established, then we can ask it to generate keys. Note that
527 * this introduces a potential race; If the device is locked and the wrapping
528 * keys are purged between the time we call this function and the time we ask it to generate
529 * keys for us, we could have to fail the open(2) call and back out the entry.
532 int cp_setup_newentry (struct hfsmount
*hfsmp
, struct cnode
*dcp
,
533 cp_key_class_t suppliedclass
, mode_t cmode
,
534 struct cprotect
**tmpentry
)
537 struct cprotect
*entry
= NULL
;
538 uint32_t target_class
= hfsmp
->default_cp_class
;
539 suppliedclass
= CP_CLASS(suppliedclass
);
541 if (hfsmp
->hfs_running_cp_major_vers
== 0) {
542 panic ("CP: major vers not set in mount!");
545 if (S_ISDIR (cmode
)) {
549 /* Decide the target class. Input argument takes priority. */
550 if (cp_is_valid_class (isdir
, suppliedclass
)) {
551 /* caller supplies -1 if it was not specified so we will default to the mount point value */
552 target_class
= suppliedclass
;
554 * One exception, F is never valid for a directory
555 * because its children may inherit and userland will be
556 * unable to read/write to the files.
559 if (target_class
== PROTECTION_CLASS_F
) {
567 * If no valid class was supplied, behave differently depending on whether or not
568 * the item being created is a file or directory.
571 * If parent directory has a non-zero class, use that.
572 * If parent directory has a zero class (not set), then attempt to
573 * apply the mount point default.
576 * Directories always inherit from the parent; if the parent
577 * has a NONE class set, then we can continue to use that.
579 if ((dcp
) && (dcp
->c_cpentry
)) {
580 uint32_t parentclass
= CP_CLASS(dcp
->c_cpentry
->cp_pclass
);
581 /* If the parent class is not valid, default to the mount point value */
582 if (cp_is_valid_class(1, parentclass
)) {
584 target_class
= parentclass
;
586 else if (parentclass
!= PROTECTION_CLASS_DIR_NONE
) {
587 /* files can inherit so long as it's not NONE */
588 target_class
= parentclass
;
591 /* Otherwise, we already defaulted to the mount point's default */
595 /* Generate the cprotect to vend out */
596 entry
= cp_entry_alloc(NULL
, 0, 0, NULL
);
603 * We don't have keys yet, so fill in what we can. At this point
604 * this blob has no keys and it has no backing xattr. We just know the
607 entry
->cp_flags
= CP_NO_XATTR
;
608 /* Note this is only the effective class */
609 entry
->cp_pclass
= target_class
;
616 * Set up an initial key/class pair for a disassociated cprotect entry.
617 * This function is used to generate transient keys that will never be
618 * written to disk. We use class F for this since it provides the exact
619 * semantics that are needed here. Because we never attach this blob to
620 * a cnode directly, we take a pointer to the cprotect struct.
622 * This function is primarily used in the HFS FS truncation codepath
623 * where we may rely on AES symmetry to relocate encrypted data from
624 * one spot in the disk to another.
626 int cpx_gentempkeys(cpx_t
*pcpx
, __unused
struct hfsmount
*hfsmp
)
628 cpx_t cpx
= cpx_alloc(CP_MAX_KEYSIZE
);
630 cpx_set_key_len(cpx
, CP_MAX_KEYSIZE
);
631 read_random(cpx_key(cpx
), CP_MAX_KEYSIZE
);
632 cpx_set_use_offset_for_iv(cpx
, true);
640 * Tear down and clear a cprotect blob for a closing file.
641 * Called at hfs_reclaim_cnode: cnode is locked exclusive.
644 cp_entry_destroy(hfsmount_t
*hfsmp
, struct cprotect
*entry_ptr
)
646 if (entry_ptr
== NULL
) {
647 /* nothing to clean up */
650 cp_entry_dealloc(hfsmp
, entry_ptr
);
655 cp_fs_protected (mount_t mnt
)
657 return (vfs_flags(mnt
) & MNT_CPROTECT
);
662 * Return a pointer to underlying cnode if there is one for this vnode.
663 * Done without taking cnode lock, inspecting only vnode state.
666 cp_get_protected_cnode(struct vnode
*vp
)
668 if (!cp_vnode_is_eligible(vp
)) {
672 if (!cp_fs_protected(VTOVFS(vp
))) {
673 /* mount point doesn't support it */
677 return (struct cnode
*) vp
->v_data
;
682 * Sets *class to persistent class associated with vnode,
686 cp_vnode_getclass(struct vnode
*vp
, int *class)
688 struct cprotect
*entry
;
691 int took_truncate_lock
= 0;
692 struct hfsmount
*hfsmp
= NULL
;
694 /* Is this an interesting vp? */
695 if (!cp_vnode_is_eligible (vp
)) {
699 /* Is the mount point formatted for content protection? */
700 if (!cp_fs_protected(VTOVFS(vp
))) {
708 * Take the truncate lock up-front in shared mode because we may need
709 * to manipulate the CP blob. Pend lock events until we're done here.
711 hfs_lock_truncate (cp
, HFS_SHARED_LOCK
, HFS_LOCK_DEFAULT
);
712 took_truncate_lock
= 1;
715 * We take only the shared cnode lock up-front. If it turns out that
716 * we need to manipulate the CP blob to write a key out, drop the
717 * shared cnode lock and acquire an exclusive lock.
719 error
= hfs_lock(cp
, HFS_SHARED_LOCK
, HFS_LOCK_DEFAULT
);
721 hfs_unlock_truncate(cp
, HFS_LOCK_DEFAULT
);
725 /* pull the class from the live entry */
726 entry
= cp
->c_cpentry
;
729 panic("Content Protection: uninitialized cnode %p", cp
);
732 /* Note that we may not have keys yet, but we know the target class. */
735 *class = CP_CLASS(entry
->cp_pclass
);
738 if (took_truncate_lock
) {
739 hfs_unlock_truncate(cp
, HFS_LOCK_DEFAULT
);
747 * Sets persistent class for this file or directory.
748 * If vnode cannot be protected (system file, non-regular file, non-hfs), EBADF.
749 * If the new class can't be accessed now, EPERM.
750 * Otherwise, record class and re-wrap key if the mount point is content-protected.
753 cp_vnode_setclass(struct vnode
*vp
, uint32_t newclass
)
756 struct cprotect
*entry
= 0;
758 int took_truncate_lock
= 0;
759 struct hfsmount
*hfsmp
= NULL
;
762 if (vnode_isdir (vp
)) {
766 /* Ensure we only use the effective class here */
767 newclass
= CP_CLASS(newclass
);
769 if (!cp_is_valid_class(isdir
, newclass
)) {
770 printf("hfs: CP: cp_setclass called with invalid class %d\n", newclass
);
774 /* Is this an interesting vp? */
775 if (!cp_vnode_is_eligible(vp
)) {
779 /* Is the mount point formatted for content protection? */
780 if (!cp_fs_protected(VTOVFS(vp
))) {
785 if (hfsmp
->hfs_flags
& HFS_READ_ONLY
) {
790 * Take the cnode truncate lock exclusive because we want to manipulate the
791 * CP blob. The lock-event handling code is doing the same. This also forces
792 * all pending IOs to drain before we can re-write the persistent and cache keys.
795 hfs_lock_truncate (cp
, HFS_EXCLUSIVE_LOCK
, HFS_LOCK_DEFAULT
);
796 took_truncate_lock
= 1;
799 * The truncate lock is not sufficient to guarantee the CP blob
800 * isn't being used. We must wait for existing writes to finish.
802 vnode_waitforwrites(vp
, 0, 0, 0, "cp_vnode_setclass");
804 if (hfs_lock(cp
, HFS_EXCLUSIVE_LOCK
, HFS_LOCK_DEFAULT
)) {
808 entry
= cp
->c_cpentry
;
815 * re-wrap per-file key with new class.
816 * Generate an entirely new key if switching to F.
818 if (vnode_isreg(vp
)) {
820 * The vnode is a file. Before proceeding with the re-wrap, we need
821 * to unwrap the keys before proceeding. This is to ensure that
822 * the destination class's properties still work appropriately for the
823 * target class (since B allows I/O but an unwrap prior to the next unlock
824 * will not be allowed).
826 if (!cpx_has_key(&entry
->cp_keys
.cpkp_cpx
)) {
827 error
= cp_restore_keys (entry
, hfsmp
, cp
);
833 if (newclass
== PROTECTION_CLASS_F
) {
834 /* Verify that file is blockless if switching to class F */
835 if (cp
->c_datafork
->ff_size
> 0) {
841 cprotect_t new_entry
= cp_entry_alloc(NULL
, 0, CP_MAX_KEYSIZE
, &cpkp
);
848 /* newclass is only the effective class */
849 new_entry
->cp_pclass
= newclass
;
850 new_entry
->cp_key_os_version
= cp_os_version();
851 new_entry
->cp_key_revision
= cp_next_key_revision(entry
->cp_key_revision
);
853 cpx_t cpx
= cpkp_cpx(cpkp
);
855 /* Class F files are not wrapped, so they continue to use MAX_KEYSIZE */
856 cpx_set_key_len(cpx
, CP_MAX_KEYSIZE
);
857 read_random (cpx_key(cpx
), CP_MAX_KEYSIZE
);
859 cp_replace_entry(hfsmp
, cp
, new_entry
);
865 /* Deny the setclass if file is to be moved from F to something else */
866 if (entry
->cp_pclass
== PROTECTION_CLASS_F
) {
871 if (!cpkp_has_pers_key(&entry
->cp_keys
)) {
872 struct cprotect
*new_entry
= NULL
;
874 * We want to fail if we can't wrap to the target class. By not setting
875 * CP_KEYWRAP_DIFFCLASS, we tell keygeneration that if it can't wrap
876 * to 'newclass' then error out.
879 error
= cp_generate_keys (hfsmp
, cp
, newclass
, flags
, &new_entry
);
881 cp_replace_entry (hfsmp
, cp
, new_entry
);
883 /* Bypass the setxattr code below since generate_keys does it for us */
887 cprotect_t new_entry
;
888 error
= cp_rewrap(cp
, hfsmp
, &newclass
, &entry
->cp_keys
, entry
,
889 (cp_new_alloc_fn
)cp_entry_alloc
, (void **)&new_entry
);
891 /* we didn't have perms to set this class. leave file as-is and error out */
896 new_entry
->cp_pclass
= newclass
;
898 cp_replace_entry(hfsmp
, cp
, new_entry
);
901 else if (vnode_isdir(vp
)) {
902 /* For directories, just update the pclass. newclass is only effective class */
903 entry
->cp_pclass
= newclass
;
907 /* anything else, just error out */
913 * We get here if the new class was F, or if we were re-wrapping a cprotect that already
914 * existed. If the keys were never generated, then they'll skip the setxattr calls.
917 error
= cp_setxattr(cp
, cp
->c_cpentry
, VTOHFS(vp
), 0, XATTR_REPLACE
);
918 if (error
== ENOATTR
) {
919 error
= cp_setxattr(cp
, cp
->c_cpentry
, VTOHFS(vp
), 0, XATTR_CREATE
);
924 if (took_truncate_lock
) {
925 hfs_unlock_truncate (cp
, HFS_LOCK_DEFAULT
);
932 int cp_vnode_transcode(vnode_t vp
, void *key
, unsigned *len
)
935 struct cprotect
*entry
= 0;
937 int took_truncate_lock
= 0;
938 struct hfsmount
*hfsmp
= NULL
;
940 /* Structures passed between HFS and AKS */
942 cp_wrapped_key_s wrapped_key_in
, wrapped_key_out
;
944 /* Is this an interesting vp? */
945 if (!cp_vnode_is_eligible(vp
)) {
949 /* Is the mount point formatted for content protection? */
950 if (!cp_fs_protected(VTOVFS(vp
))) {
958 * Take the cnode truncate lock exclusive because we want to manipulate the
959 * CP blob. The lock-event handling code is doing the same. This also forces
960 * all pending IOs to drain before we can re-write the persistent and cache keys.
962 hfs_lock_truncate (cp
, HFS_EXCLUSIVE_LOCK
, HFS_LOCK_DEFAULT
);
963 took_truncate_lock
= 1;
965 if (hfs_lock(cp
, HFS_EXCLUSIVE_LOCK
, HFS_LOCK_DEFAULT
)) {
969 entry
= cp
->c_cpentry
;
975 /* Send the per-file key in wrapped form for re-wrap with the current class information
976 * Send NULLs in the output parameters of the wrapper() and AKS will do the rest.
977 * Don't need to process any outputs, so just clear the locks and pass along the error. */
978 if (vnode_isreg(vp
)) {
980 /* Picked up the following from cp_wrap().
981 * If needed, more comments available there. */
983 if (CP_CLASS(entry
->cp_pclass
) == PROTECTION_CLASS_F
) {
988 cp_init_access(&access_in
, cp
);
990 bzero(&wrapped_key_in
, sizeof(wrapped_key_in
));
991 bzero(&wrapped_key_out
, sizeof(wrapped_key_out
));
993 cp_key_pair_t
*cpkp
= &entry
->cp_keys
;
996 wrapped_key_in
.key
= cpkp_pers_key(cpkp
);
997 wrapped_key_in
.key_len
= cpkp_pers_key_len(cpkp
);
999 if (!wrapped_key_in
.key_len
) {
1004 /* Use the actual persistent class when talking to AKS */
1005 wrapped_key_in
.dp_class
= entry
->cp_pclass
;
1006 wrapped_key_out
.key
= key
;
1007 wrapped_key_out
.key_len
= *len
;
1009 error
= g_cp_wrap_func
.backup_key(&access_in
,
1016 *len
= wrapped_key_out
.key_len
;
1020 if (took_truncate_lock
) {
1021 hfs_unlock_truncate (cp
, HFS_LOCK_DEFAULT
);
1029 * Check permission for the given operation (read, write) on this node.
1030 * Additionally, if the node needs work, do it:
1031 * - create a new key for the file if one hasn't been set before
1032 * - write out the xattr if it hasn't already been saved
1033 * - unwrap the key if needed
1035 * Takes cnode lock, and upgrades to exclusive if modifying cprotect.
1037 * Note that this function does *NOT* take the cnode truncate lock. This is because
1038 * the thread calling us may already have the truncate lock. It is not necessary
1039 * because either we successfully finish this function before the keys are tossed
1040 * and the IO will fail, or the keys are tossed and then this function will fail.
1041 * Either way, the cnode lock still ultimately guards the keys. We only rely on the
1042 * truncate lock to protect us against tossing the keys as a cluster call is in-flight.
1045 cp_handle_vnop(struct vnode
*vp
, int vnop
, int ioflag
)
1047 struct cprotect
*entry
;
1049 struct hfsmount
*hfsmp
= NULL
;
1050 struct cnode
*cp
= NULL
;
1053 * First, do validation against the vnode before proceeding any further:
1054 * Is this vnode originating from a valid content-protected filesystem ?
1056 if (cp_vnode_is_eligible(vp
) == 0) {
1058 * It is either not HFS or not a file/dir. Just return success. This is a valid
1059 * case if servicing i/o against another filesystem type from VFS
1064 if (cp_fs_protected (VTOVFS(vp
)) == 0) {
1066 * The underlying filesystem does not support content protection. This is also
1067 * a valid case. Simply return success.
1073 * At this point, we know we have a HFS vnode that backs a file or directory on a
1074 * filesystem that supports content protection
1078 if ((error
= hfs_lock(cp
, HFS_SHARED_LOCK
, HFS_LOCK_DEFAULT
))) {
1082 entry
= cp
->c_cpentry
;
1084 if (entry
== NULL
) {
1086 * If this cnode is not content protected, simply return success.
1087 * Note that this function is called by all I/O-based call sites
1088 * when CONFIG_PROTECT is enabled during XNU building.
1092 * All files should have cprotect structs. It's possible to encounter
1093 * a directory from a V2.0 CP system but all files should have protection
1096 if (vnode_isreg(vp
)) {
1114 if ((error
= cp_check_access(cp
, hfsmp
, vnop
))) {
1115 /* check for raw encrypted access before bailing out */
1116 if ((ioflag
& IO_ENCRYPTED
)
1117 && (vnop
== CP_READ_ACCESS
)) {
1119 * read access only + asking for the raw encrypted bytes
1120 * is legitimate, so reset the error value to 0
1129 if (!ISSET(entry
->cp_flags
, CP_NO_XATTR
)) {
1130 if (!S_ISREG(cp
->c_mode
))
1133 // If we have a persistent key and the cached key, we're done
1134 if (!cp_needs_pers_key(entry
)
1135 && cpx_has_key(cpkp_cpx(&entry
->cp_keys
))) {
1140 /* upgrade to exclusive lock */
1141 if (lck_rw_lock_shared_to_exclusive(&cp
->c_rwlock
) == FALSE
) {
1142 if ((error
= hfs_lock(cp
, HFS_EXCLUSIVE_LOCK
, HFS_LOCK_DEFAULT
))) {
1146 cp
->c_lockowner
= current_thread();
1149 /* generate new keys if none have ever been saved */
1150 if (cp_needs_pers_key(entry
)) {
1151 struct cprotect
*newentry
= NULL
;
1153 * It's ok if this ends up being wrapped in a different class than 'pclass'.
1154 * class modification is OK here.
1156 uint32_t flags
= CP_KEYWRAP_DIFFCLASS
;
1158 error
= cp_generate_keys (hfsmp
, cp
, CP_CLASS(cp
->c_cpentry
->cp_pclass
), flags
, &newentry
);
1160 cp_replace_entry (hfsmp
, cp
, newentry
);
1168 /* unwrap keys if needed */
1169 if (!cpx_has_key(cpkp_cpx(&entry
->cp_keys
))) {
1170 if ((vnop
== CP_READ_ACCESS
) && (ioflag
& IO_ENCRYPTED
)) {
1171 /* no need to try to restore keys; they are not going to be used */
1175 error
= cp_restore_keys(entry
, hfsmp
, cp
);
1182 /* write out the xattr if it's new */
1183 if (entry
->cp_flags
& CP_NO_XATTR
)
1184 error
= cp_setxattr(cp
, entry
, VTOHFS(cp
->c_vp
), 0, XATTR_CREATE
);
1194 static void cp_log_eperm (struct vnode
* vp
, int pclass
, boolean_t create
) {
1195 char procname
[256] = {};
1196 const char *fname
= "unknown";
1197 const char *dbgop
= "open";
1199 int ppid
= proc_selfpid();
1200 /* selfname does a strlcpy so we're OK */
1201 proc_selfname(procname
, sizeof(procname
));
1202 if (vp
&& vp
->v_name
) {
1203 /* steal from the namecache */
1211 printf("proc %s (pid %d) class %d, op: %s failure @ file %s\n", procname
, ppid
, pclass
, dbgop
, fname
);
1218 cp_handle_open(struct vnode
*vp
, int mode
)
1220 struct cnode
*cp
= NULL
;
1221 struct cprotect
*entry
= NULL
;
1222 struct hfsmount
*hfsmp
;
1225 /* If vnode not eligible, just return success */
1226 if (!cp_vnode_is_eligible(vp
)) {
1230 /* If mount point not properly set up, then also return success */
1231 if (!cp_fs_protected(VTOVFS(vp
))) {
1237 // Allow if raw encrypted mode requested
1238 if (ISSET(mode
, FENCRYPTED
)) {
1241 if (ISSET(mode
, FUNENCRYPTED
)) {
1245 /* We know the vnode is in a valid state. Acquire cnode and validate */
1248 if ((error
= hfs_lock(cp
, HFS_EXCLUSIVE_LOCK
, HFS_LOCK_DEFAULT
))) {
1252 entry
= cp
->c_cpentry
;
1253 if (entry
== NULL
) {
1255 * If the mount is protected and we couldn't get a cprotect for this vnode,
1256 * then it's not valid for opening.
1258 if (vnode_isreg(vp
)) {
1264 if (!S_ISREG(cp
->c_mode
))
1268 * Does the cnode have keys yet? If not, then generate them.
1270 if (cp_needs_pers_key(entry
)) {
1271 struct cprotect
*newentry
= NULL
;
1272 /* Allow the keybag to override our class preferences */
1273 uint32_t flags
= CP_KEYWRAP_DIFFCLASS
;
1274 error
= cp_generate_keys (hfsmp
, cp
, CP_CLASS(cp
->c_cpentry
->cp_pclass
), flags
, &newentry
);
1276 cp_replace_entry (hfsmp
, cp
, newentry
);
1285 * We want to minimize the number of unwraps that we'll have to do since
1286 * the cost can vary, depending on the platform we're running.
1288 switch (CP_CLASS(entry
->cp_pclass
)) {
1289 case PROTECTION_CLASS_B
:
1290 if (mode
& O_CREAT
) {
1292 * Class B always allows creation. Since O_CREAT was passed through
1293 * we infer that this was a newly created vnode/cnode. Even though a potential
1294 * race exists when multiple threads attempt to create/open a particular
1295 * file, only one can "win" and actually create it. VFS will unset the
1296 * O_CREAT bit on the loser.
1298 * Note that skipping the unwrap check here is not a security issue --
1299 * we have to unwrap the key permanently upon the first I/O.
1304 if (cpx_has_key(cpkp_cpx(&entry
->cp_keys
)) && !ISSET(mode
, FENCRYPTED
)) {
1306 * For a class B file, attempt the unwrap if we have the key in
1308 * The device could have just transitioned into the lock state, and
1309 * this vnode may not yet have been purged from the vnode cache (which would
1312 cp_cred_s access_in
;
1313 cp_wrapped_key_s wrapped_key_in
;
1315 cp_init_access(&access_in
, cp
);
1316 bzero(&wrapped_key_in
, sizeof(wrapped_key_in
));
1317 wrapped_key_in
.key
= cpkp_pers_key(&entry
->cp_keys
);
1318 wrapped_key_in
.key_len
= cpkp_pers_key_len(&entry
->cp_keys
);
1319 /* Use the persistent class when talking to AKS */
1320 wrapped_key_in
.dp_class
= entry
->cp_pclass
;
1321 error
= g_cp_wrap_func
.unwrapper(&access_in
, &wrapped_key_in
, NULL
);
1327 /* otherwise, fall through to attempt the unwrap/restore */
1328 case PROTECTION_CLASS_A
:
1329 case PROTECTION_CLASS_C
:
1331 * At this point, we know that we need to attempt an unwrap if needed; we want
1332 * to makes sure that open(2) fails properly if the device is either just-locked
1333 * or never made it past first unlock. Since the keybag serializes access to the
1334 * unwrapping keys for us and only calls our VFS callback once they've been purged,
1335 * we will get here in two cases:
1337 * A) we're in a window before the wrapping keys are purged; this is OK since when they get
1338 * purged, the vnode will get flushed if needed.
1340 * B) The keys are already gone. In this case, the restore_keys call below will fail.
1342 * Since this function is bypassed entirely if we're opening a raw encrypted file,
1343 * we can always attempt the restore.
1345 if (!cpx_has_key(cpkp_cpx(&entry
->cp_keys
))) {
1346 error
= cp_restore_keys(entry
, hfsmp
, cp
);
1355 case PROTECTION_CLASS_D
:
1364 if ((hfsmp
->hfs_cp_verbose
) && (error
== EPERM
)) {
1365 cp_log_eperm (vp
, CP_CLASS(entry
->cp_pclass
), false);
1377 * Gets the EA we set on the root folder (fileid 1) to get information about the
1378 * version of Content Protection that was used to write to this filesystem.
1379 * Note that all multi-byte fields are written to disk little endian so they must be
1380 * converted to native endian-ness as needed.
1383 cp_getrootxattr(struct hfsmount
* hfsmp
, struct cp_root_xattr
*outxattr
)
1386 char uio_buf
[UIO_SIZEOF(1)];
1390 * We allow for an extra 64 bytes to cater for upgrades. This wouldn't
1391 * be necessary if the xattr routines just returned what we asked for.
1393 size_t attrsize
= roundup(sizeof(struct cp_root_xattr
) + 64, 64);
1396 struct vnop_getxattr_args args
;
1399 panic("Content Protection: cp_xattr called with xattr == NULL");
1402 MALLOC(buf
, void *, attrsize
, M_TEMP
, M_WAITOK
);
1404 auio
= uio_createwithbuffer(1, 0, UIO_SYSSPACE
, UIO_READ
, &uio_buf
[0], sizeof(uio_buf
));
1405 uio_addiov(auio
, CAST_USER_ADDR_T(buf
), attrsize
);
1407 args
.a_desc
= NULL
; // unused
1408 args
.a_vp
= NULL
; //unused since we're writing EA to root folder.
1409 args
.a_name
= CONTENT_PROTECTION_XATTR_NAME
;
1411 args
.a_size
= &attrsize
;
1412 args
.a_options
= XATTR_REPLACE
;
1413 args
.a_context
= NULL
; // unused
1415 error
= hfs_getxattr_internal(NULL
, &args
, hfsmp
, 1);
1421 if (attrsize
< CP_ROOT_XATTR_MIN_LEN
) {
1422 error
= HFS_EINCONSISTENT
;
1426 const struct cp_root_xattr
*xattr
= buf
;
1428 bzero(outxattr
, sizeof(*outxattr
));
1430 /* Now convert the multi-byte fields to native endianness */
1431 outxattr
->major_version
= OSSwapLittleToHostInt16(xattr
->major_version
);
1432 outxattr
->minor_version
= OSSwapLittleToHostInt16(xattr
->minor_version
);
1433 outxattr
->flags
= OSSwapLittleToHostInt64(xattr
->flags
);
1435 if (outxattr
->major_version
>= CP_VERS_5
) {
1436 if (attrsize
< sizeof(struct cp_root_xattr
)) {
1437 error
= HFS_EINCONSISTENT
;
1450 * Sets the EA we set on the root folder (fileid 1) to get information about the
1451 * version of Content Protection that was used to write to this filesystem.
1452 * Note that all multi-byte fields are written to disk little endian so they must be
1453 * converted to little endian as needed.
1455 * This will be written to the disk when it detects the EA is not there, or when we need
1456 * to make a modification to the on-disk version that can be done in-place.
1459 cp_setrootxattr(struct hfsmount
*hfsmp
, struct cp_root_xattr
*newxattr
)
1462 struct vnop_setxattr_args args
;
1466 args
.a_name
= CONTENT_PROTECTION_XATTR_NAME
;
1467 args
.a_uio
= NULL
; //pass data ptr instead
1469 args
.a_context
= NULL
; //no context needed, only done from mount.
1471 const uint32_t flags
= newxattr
->flags
;
1473 /* Now convert the multi-byte fields to little endian before writing to disk. */
1474 newxattr
->flags
= OSSwapHostToLittleInt64(newxattr
->flags
);
1476 int xattr_size
= sizeof(struct cp_root_xattr
);
1479 newxattr
->major_version
= OSSwapHostToLittleInt16(newxattr
->major_version
);
1480 newxattr
->minor_version
= OSSwapHostToLittleInt16(newxattr
->minor_version
);
1482 error
= hfs_setxattr_internal(NULL
, (caddr_t
)newxattr
,
1483 xattr_size
, &args
, hfsmp
, 1);
1486 hfsmp
->cproot_flags
= flags
;
1494 * Stores new xattr data on the cnode.
1495 * cnode lock held exclusive (if available).
1497 * This function is also invoked during file creation.
1499 int cp_setxattr(struct cnode
*cp
, struct cprotect
*entry
, struct hfsmount
*hfsmp
,
1500 uint32_t fileid
, int options
)
1503 cp_key_pair_t
*cpkp
= &entry
->cp_keys
;
1505 if (hfsmp
->hfs_flags
& HFS_READ_ONLY
) {
1509 if (hfsmp
->hfs_running_cp_major_vers
< CP_CURRENT_VERS
) {
1511 printf("hfs: upgrading to cp version %u\n", CP_CURRENT_VERS
);
1513 struct cp_root_xattr root_xattr
;
1515 error
= cp_getrootxattr(hfsmp
, &root_xattr
);
1519 root_xattr
.major_version
= CP_CURRENT_VERS
;
1520 root_xattr
.minor_version
= CP_MINOR_VERS
;
1522 error
= cp_setrootxattr(hfsmp
, &root_xattr
);
1526 hfsmp
->hfs_running_cp_major_vers
= CP_CURRENT_VERS
;
1529 struct cp_xattr_v5
*xattr
;
1530 MALLOC(xattr
, struct cp_xattr_v5
*, sizeof(*xattr
), M_TEMP
, M_WAITOK
);
1532 xattr
->xattr_major_version
= OSSwapHostToLittleConstInt16(CP_VERS_5
);
1533 xattr
->xattr_minor_version
= OSSwapHostToLittleConstInt16(CP_MINOR_VERS
);
1535 xattr
->persistent_class
= OSSwapHostToLittleInt32(entry
->cp_pclass
);
1536 xattr
->key_os_version
= OSSwapHostToLittleInt32(entry
->cp_key_os_version
);
1537 xattr
->key_revision
= OSSwapHostToLittleInt16(entry
->cp_key_revision
);
1539 uint16_t key_len
= cpkp_pers_key_len(cpkp
);
1540 xattr
->key_len
= OSSwapHostToLittleInt16(key_len
);
1541 memcpy(xattr
->persistent_key
, cpkp_pers_key(cpkp
), key_len
);
1543 size_t xattr_len
= offsetof(struct cp_xattr_v5
, persistent_key
) + key_len
;
1546 struct vnop_setxattr_args args
= {
1547 .a_vp
= cp
? cp
->c_vp
: NULL
,
1548 .a_name
= CONTENT_PROTECTION_XATTR_NAME
,
1549 .a_options
= options
,
1550 .a_context
= vfs_context_current(),
1553 error
= hfs_setxattr_internal(cp
, xattr
, xattr_len
, &args
, hfsmp
, fileid
);
1555 FREE(xattr
, M_TEMP
);
1558 entry
->cp_flags
&= ~CP_NO_XATTR
;
1565 * Used by an fcntl to query the underlying FS for its content protection version #
1569 cp_get_root_major_vers(vnode_t vp
, uint32_t *level
)
1572 struct hfsmount
*hfsmp
= NULL
;
1573 struct mount
*mp
= NULL
;
1577 /* check if it supports content protection */
1578 if (cp_fs_protected(mp
) == 0) {
1582 hfsmp
= VFSTOHFS(mp
);
1583 /* figure out the level */
1585 err
= cp_root_major_vers(mp
);
1588 *level
= hfsmp
->hfs_running_cp_major_vers
;
1590 /* in error case, cp_root_major_vers will just return EINVAL. Use that */
1595 /* Used by fcntl to query default protection level of FS */
1596 int cp_get_default_level (struct vnode
*vp
, uint32_t *level
) {
1598 struct hfsmount
*hfsmp
= NULL
;
1599 struct mount
*mp
= NULL
;
1603 /* check if it supports content protection */
1604 if (cp_fs_protected(mp
) == 0) {
1608 hfsmp
= VFSTOHFS(mp
);
1609 /* figure out the default */
1611 *level
= hfsmp
->default_cp_class
;
1615 /********************
1617 *******************/
1620 cp_root_major_vers(mount_t mp
)
1623 struct cp_root_xattr xattr
;
1624 struct hfsmount
*hfsmp
= NULL
;
1626 hfsmp
= vfs_fsprivate(mp
);
1627 err
= cp_getrootxattr (hfsmp
, &xattr
);
1630 hfsmp
->hfs_running_cp_major_vers
= xattr
.major_version
;
1640 cp_vnode_is_eligible(struct vnode
*vp
)
1642 return ((vp
->v_op
== hfs_vnodeop_p
) &&
1643 (!vnode_issystem(vp
)) &&
1644 (vnode_isreg(vp
) || vnode_isdir(vp
)));
1650 cp_is_valid_class(int isdir
, int32_t protectionclass
)
1653 * The valid protection classes are from 0 -> N
1654 * We use a signed argument to detect unassigned values from
1655 * directory entry creation time in HFS.
1658 /* Directories are not allowed to have F, but they can have "NONE" */
1659 return ((protectionclass
>= PROTECTION_CLASS_DIR_NONE
) &&
1660 (protectionclass
<= PROTECTION_CLASS_D
));
1663 return ((protectionclass
>= PROTECTION_CLASS_A
) &&
1664 (protectionclass
<= PROTECTION_CLASS_F
));
1669 static const uint32_t cp_magic1
= 0x7b727063; // cpr{
1670 static const uint32_t cp_magic2
= 0x7270637d; // }cpr
1674 cp_entry_alloc(cprotect_t old
, uint16_t pers_key_len
,
1675 uint16_t cached_key_len
, cp_key_pair_t
**pcpkp
)
1677 struct cprotect
*cp_entry
;
1679 if (pers_key_len
> CP_MAX_WRAPPEDKEYSIZE
)
1682 size_t size
= (sizeof(struct cprotect
) - sizeof(cp_key_pair_t
)
1683 + cpkp_size(pers_key_len
, cached_key_len
));
1686 size
+= 4; // Extra for magic2
1689 MALLOC(cp_entry
, struct cprotect
*, size
, M_TEMP
, M_WAITOK
);
1692 memcpy(cp_entry
, old
, offsetof(struct cprotect
, cp_keys
));
1695 bzero(cp_entry
, offsetof(struct cprotect
, cp_keys
));
1699 cp_entry
->cp_magic1
= cp_magic1
;
1700 *PTR_ADD(uint32_t *, cp_entry
, size
- 4) = cp_magic2
;
1703 cpkp_init(&cp_entry
->cp_keys
, pers_key_len
, cached_key_len
);
1706 * If we've been passed the old entry, then we are in the process of
1707 * rewrapping in which case we need to copy the cached key. This is
1708 * important for class B files when the device is locked because we
1709 * won't be able to unwrap whilst in this state, yet we still need the
1713 cpx_copy(cpkp_cpx(&old
->cp_keys
), cpkp_cpx(&cp_entry
->cp_keys
));
1716 *pcpkp
= &cp_entry
->cp_keys
;
1722 cp_entry_dealloc(__unused hfsmount_t
*hfsmp
, struct cprotect
*entry
)
1725 cpkp_flush(&entry
->cp_keys
);
1728 assert(entry
->cp_magic1
== cp_magic1
);
1729 assert(*PTR_ADD(uint32_t *, entry
, (sizeof(struct cprotect
) - sizeof(cp_key_pair_t
)
1730 + cpkp_sizex(&entry
->cp_keys
) == cp_magic2
)));
1733 FREE(entry
, M_TEMP
);
1736 static int cp_read_xattr_v4(__unused hfsmount_t
*hfsmp
, struct cp_xattr_v4
*xattr
,
1737 size_t xattr_len
, cprotect_t
*pcpr
, cp_getxattr_options_t options
)
1739 /* Endian swap the multi-byte fields into host endianness from L.E. */
1740 xattr
->xattr_major_version
= OSSwapLittleToHostInt16(xattr
->xattr_major_version
);
1741 xattr
->xattr_minor_version
= OSSwapLittleToHostInt16(xattr
->xattr_minor_version
);
1742 xattr
->key_size
= OSSwapLittleToHostInt32(xattr
->key_size
);
1743 xattr
->flags
= OSSwapLittleToHostInt32(xattr
->flags
);
1744 xattr
->persistent_class
= OSSwapLittleToHostInt32(xattr
->persistent_class
);
1745 xattr
->key_os_version
= OSSwapLittleToHostInt32(xattr
->key_os_version
);
1748 * Prevent a buffer overflow, and validate the key length obtained from the
1749 * EA. If it's too big, then bail out, because the EA can't be trusted at this
1752 if (xattr
->key_size
> CP_MAX_WRAPPEDKEYSIZE
)
1753 return HFS_EINCONSISTENT
;
1755 size_t min_len
= offsetof(struct cp_xattr_v4
, persistent_key
) + xattr
->key_size
;
1756 if (xattr_len
< min_len
)
1757 return HFS_EINCONSISTENT
;
1760 * Class F files have no backing key; their keylength should be 0,
1761 * though they should have the proper flags set.
1763 * A request to instantiate a CP for a class F file should result
1764 * in a bzero'd cp that just says class F, with key_flushed set.
1766 if (CP_CLASS(xattr
->persistent_class
) == PROTECTION_CLASS_F
1767 || ISSET(xattr
->flags
, CP_XAF_NEEDS_KEYS
)) {
1768 xattr
->key_size
= 0;
1771 /* set up entry with information from xattr */
1772 cp_key_pair_t
*cpkp
;
1775 if (ISSET(options
, CP_GET_XATTR_BASIC_INFO
)) {
1776 /* caller passed in a pre-allocated structure to get the basic info */
1778 bzero(entry
, offsetof(struct cprotect
, cp_keys
));
1781 entry
= cp_entry_alloc(NULL
, xattr
->key_size
, CP_MAX_CACHEBUFLEN
, &cpkp
);
1784 entry
->cp_pclass
= xattr
->persistent_class
;
1785 entry
->cp_key_os_version
= xattr
->key_os_version
;
1788 if (!ISSET(options
, CP_GET_XATTR_BASIC_INFO
)) {
1789 if (xattr
->key_size
) {
1790 cpkp_set_pers_key_len(cpkp
, xattr
->key_size
);
1791 memcpy(cpkp_pers_key(cpkp
), xattr
->persistent_key
, xattr
->key_size
);
1796 else if (xattr
->key_size
) {
1797 SET(entry
->cp_flags
, CP_HAS_A_KEY
);
1803 int cp_read_xattr_v5(hfsmount_t
*hfsmp
, struct cp_xattr_v5
*xattr
,
1804 size_t xattr_len
, cprotect_t
*pcpr
, cp_getxattr_options_t options
)
1806 if (xattr
->xattr_major_version
== OSSwapHostToLittleConstInt16(CP_VERS_4
)) {
1807 return cp_read_xattr_v4(hfsmp
, (struct cp_xattr_v4
*)xattr
, xattr_len
, pcpr
, options
);
1810 xattr
->xattr_major_version
= OSSwapLittleToHostInt16(xattr
->xattr_major_version
);
1812 if (xattr
->xattr_major_version
!= CP_VERS_5
) {
1813 printf("hfs: cp_getxattr: unsupported xattr version %d\n",
1814 xattr
->xattr_major_version
);
1818 size_t min_len
= offsetof(struct cp_xattr_v5
, persistent_key
);
1820 if (xattr_len
< min_len
)
1821 return HFS_EINCONSISTENT
;
1823 xattr
->xattr_minor_version
= OSSwapLittleToHostInt16(xattr
->xattr_minor_version
);
1824 xattr
->flags
= OSSwapLittleToHostInt32(xattr
->flags
);
1825 xattr
->persistent_class
= OSSwapLittleToHostInt32(xattr
->persistent_class
);
1826 xattr
->key_os_version
= OSSwapLittleToHostInt32(xattr
->key_os_version
);
1827 xattr
->key_revision
= OSSwapLittleToHostInt16(xattr
->key_revision
);
1828 xattr
->key_len
= OSSwapLittleToHostInt16(xattr
->key_len
);
1830 uint16_t pers_key_len
= xattr
->key_len
;
1832 min_len
+= pers_key_len
;
1833 if (xattr_len
< min_len
)
1834 return HFS_EINCONSISTENT
;
1837 cp_key_pair_t
*cpkp
;
1841 * If option CP_GET_XATTR_BASIC_INFO is set, we only return basic
1842 * information about the file's protection (and not the key) and
1843 * we store the result in the structure the caller passed to us.
1845 if (ISSET(options
, CP_GET_XATTR_BASIC_INFO
)) {
1847 bzero(entry
, offsetof(struct cprotect
, cp_keys
));
1849 entry
= cp_entry_alloc(NULL
, xattr
->key_len
, CP_MAX_CACHEBUFLEN
, &cpkp
);
1852 entry
->cp_pclass
= xattr
->persistent_class
;
1853 entry
->cp_key_os_version
= xattr
->key_os_version
;
1854 entry
->cp_key_revision
= xattr
->key_revision
;
1856 if (!ISSET(options
, CP_GET_XATTR_BASIC_INFO
)) {
1857 if (xattr
->key_len
) {
1858 cpkp_set_pers_key_len(cpkp
, xattr
->key_len
);
1859 memcpy(cpkp_pers_key(cpkp
), xattr
->persistent_key
, xattr
->key_len
);
1865 else if (xattr
->key_len
) {
1866 SET(entry
->cp_flags
, CP_HAS_A_KEY
);
1873 * Initializes a new cprotect entry with xattr data from the cnode.
1874 * cnode lock held shared
1877 cp_getxattr(struct cnode
*cp
, struct hfsmount
*hfsmp
, cprotect_t
*outentry
)
1879 size_t xattr_len
= sizeof(struct cp_xattr_v5
);
1880 struct cp_xattr_v5
*xattr
;
1882 MALLOC (xattr
, struct cp_xattr_v5
*, xattr_len
,
1885 int error
= hfs_xattr_read(cp
->c_vp
, CONTENT_PROTECTION_XATTR_NAME
,
1889 if (xattr_len
< CP_XATTR_MIN_LEN
)
1890 error
= HFS_EINCONSISTENT
;
1892 error
= cp_read_xattr_v5(hfsmp
, xattr
, xattr_len
, outentry
, 0);
1896 if (error
&& error
!= ENOATTR
) {
1897 printf("cp_getxattr: bad cp xattr (%d):\n", error
);
1898 for (size_t i
= 0; i
< xattr_len
; ++i
)
1899 printf("%02x ", ((uint8_t *)xattr
)[i
]);
1904 FREE(xattr
, M_TEMP
);
1910 * If permitted, restore entry's unwrapped key from the persistent key.
1911 * If not, clear key and set CP_KEY_FLUSHED.
1912 * cnode lock held exclusive
1915 cp_restore_keys(struct cprotect
*entry
, struct hfsmount
*hfsmp
, struct cnode
*cp
)
1919 error
= cp_unwrap(hfsmp
, entry
, cp
);
1921 cp_flush_cached_keys(entry
);
1928 cp_lock_vfs_callback(mount_t mp
, void *arg
)
1931 /* Use a pointer-width integer field for casting */
1932 unsigned long new_state
;
1933 struct hfsmount
*hfsmp
;
1936 * When iterating the various mount points that may
1937 * be present on a content-protected device, we need to skip
1938 * those that do not have it enabled.
1940 if (!cp_fs_protected(mp
)) {
1943 new_state
= (unsigned long) arg
;
1945 hfsmp
= VFSTOHFS(mp
);
1947 hfs_lock_mount(hfsmp
);
1948 /* this loses all of the upper bytes of precision; that's OK */
1949 hfsmp
->hfs_cp_lock_state
= (uint8_t) new_state
;
1950 hfs_unlock_mount(hfsmp
);
1952 if (new_state
== CP_LOCKED_STATE
) {
1954 * We respond only to lock events. Since cprotect structs
1955 * decrypt/restore keys lazily, the unlock events don't
1956 * actually cause anything to happen.
1958 return vnode_iterate(mp
, 0, cp_lock_vnode_callback
, arg
);
1960 /* Otherwise just return 0. */
1967 * Deny access to protected files if keys have been locked.
1970 cp_check_access(struct cnode
*cp
, struct hfsmount
*hfsmp
, int vnop __unused
)
1975 * For now it's OK to examine the state variable here without
1976 * holding the HFS lock. This is only a short-circuit; if the state
1977 * transitions (or is in transition) after we examine this field, we'd
1978 * have to handle that anyway.
1980 if (hfsmp
->hfs_cp_lock_state
== CP_UNLOCKED_STATE
) {
1984 if (!cp
->c_cpentry
) {
1985 /* unprotected node */
1989 if (!S_ISREG(cp
->c_mode
)) {
1993 /* Deny all access for class A files */
1994 switch (CP_CLASS(cp
->c_cpentry
->cp_pclass
)) {
1995 case PROTECTION_CLASS_A
: {
2008 * Respond to a lock or unlock event.
2009 * On lock: clear out keys from memory, then flush file contents.
2010 * On unlock: nothing (function not called).
2013 cp_lock_vnode_callback(struct vnode
*vp
, void *arg
)
2016 struct cprotect
*entry
= NULL
;
2019 unsigned long action
= 0;
2020 int took_truncate_lock
= 0;
2022 error
= vnode_getwithref (vp
);
2030 * When cleaning cnodes due to a lock event, we must
2031 * take the truncate lock AND the cnode lock. By taking
2032 * the truncate lock here, we force (nearly) all pending IOs
2033 * to drain before we can acquire the truncate lock. All HFS cluster
2034 * io calls except for swapfile IO need to acquire the truncate lock
2035 * prior to calling into the cluster layer.
2037 hfs_lock_truncate (cp
, HFS_EXCLUSIVE_LOCK
, HFS_LOCK_DEFAULT
);
2038 took_truncate_lock
= 1;
2040 hfs_lock(cp
, HFS_EXCLUSIVE_LOCK
, HFS_LOCK_ALLOW_NOEXISTS
);
2042 entry
= cp
->c_cpentry
;
2044 /* unprotected vnode: not a regular file */
2048 action
= (unsigned long) arg
;
2050 case CP_LOCKED_STATE
: {
2052 if (CP_CLASS(entry
->cp_pclass
) != PROTECTION_CLASS_A
||
2055 * There is no change at lock for other classes than A.
2056 * B is kept in memory for writing, and class F (for VM) does
2057 * not have a wrapped key, so there is no work needed for
2058 * wrapping/unwrapping.
2060 * Note that 'class F' is relevant here because if
2061 * hfs_vnop_strategy does not take the cnode lock
2062 * to protect the cp blob across IO operations, we rely
2063 * implicitly on the truncate lock to be held when doing IO.
2064 * The only case where the truncate lock is not held is during
2065 * swapfile IO because HFS just funnels the VNOP_PAGEOUT
2066 * directly to cluster_pageout.
2071 /* Before doing anything else, zero-fill sparse ranges as needed */
2072 ctx
= vfs_context_current();
2073 (void) hfs_filedone (vp
, ctx
, 0);
2075 /* first, sync back dirty pages */
2077 ubc_msync (vp
, 0, ubc_getsize(vp
), NULL
, UBC_PUSHALL
| UBC_INVALIDATE
| UBC_SYNC
);
2078 hfs_lock (cp
, HFS_EXCLUSIVE_LOCK
, HFS_LOCK_ALLOW_NOEXISTS
);
2081 * There was a concern here(9206856) about flushing keys before nand layer is done using them.
2082 * But since we are using ubc_msync with UBC_SYNC, it blocks until all IO is completed.
2083 * Once IOFS caches or is done with these keys, it calls the completion routine in IOSF.
2084 * Which in turn calls buf_biodone() and eventually unblocks ubc_msync()
2085 * Also verified that the cached data in IOFS is overwritten by other data, and there
2086 * is no key leakage in that layer.
2089 cp_flush_cached_keys(entry
);
2091 /* some write may have arrived in the mean time. dump those pages */
2095 ubc_msync (vp
, 0, ubc_getsize(vp
), NULL
, UBC_INVALIDATE
| UBC_SYNC
);
2098 case CP_UNLOCKED_STATE
: {
2103 panic("Content Protection: unknown lock action %lu\n", action
);
2111 if (took_truncate_lock
) {
2112 hfs_unlock_truncate (cp
, HFS_LOCK_DEFAULT
);
2123 * Generate a new wrapped key based on the existing cache key.
2127 cp_rewrap(struct cnode
*cp
, __unused hfsmount_t
*hfsmp
,
2128 cp_key_class_t
*newclass
, cp_key_pair_t
*cpkp
, const void *old_holder
,
2129 cp_new_alloc_fn alloc_fn
, void **pholder
)
2131 struct cprotect
*entry
= cp
->c_cpentry
;
2133 uint8_t new_persistent_key
[CP_MAX_WRAPPEDKEYSIZE
];
2134 size_t keylen
= CP_MAX_WRAPPEDKEYSIZE
;
2136 const cp_key_class_t key_class
= CP_CLASS(*newclass
);
2138 /* Structures passed between HFS and AKS */
2139 cp_cred_s access_in
;
2140 cp_wrapped_key_s wrapped_key_in
;
2141 cp_wrapped_key_s wrapped_key_out
;
2144 * PROTECTION_CLASS_F is in-use by VM swapfile; it represents a transient
2145 * key that is only good as long as the file is open. There is no
2146 * wrapped key, so there isn't anything to wrap.
2148 if (key_class
== PROTECTION_CLASS_F
) {
2152 cp_init_access(&access_in
, cp
);
2154 bzero(&wrapped_key_in
, sizeof(wrapped_key_in
));
2155 wrapped_key_in
.key
= cpkp_pers_key(cpkp
);
2156 wrapped_key_in
.key_len
= cpkp_pers_key_len(cpkp
);
2157 /* Use the persistent class when talking to AKS */
2158 wrapped_key_in
.dp_class
= entry
->cp_pclass
;
2160 bzero(&wrapped_key_out
, sizeof(wrapped_key_out
));
2161 wrapped_key_out
.key
= new_persistent_key
;
2162 wrapped_key_out
.key_len
= keylen
;
2165 * inode is passed here to find the backup bag wrapped blob
2166 * from userspace. This lookup will occur shortly after creation
2167 * and only if the file still exists. Beyond this lookup the
2168 * inode is not used. Technically there is a race, we practically
2171 error
= g_cp_wrap_func
.rewrapper(&access_in
,
2172 key_class
, /* new class */
2176 keylen
= wrapped_key_out
.key_len
;
2180 * Verify that AKS returned to us a wrapped key of the
2181 * target class requested.
2183 /* Get the effective class here */
2184 cp_key_class_t effective
= CP_CLASS(wrapped_key_out
.dp_class
);
2185 if (effective
!= key_class
) {
2187 * Fail the operation if defaults or some other enforcement
2188 * dictated that the class be wrapped differently.
2191 /* TODO: Invalidate the key when 12170074 unblocked */
2195 /* Allocate a new cpentry */
2196 cp_key_pair_t
*new_cpkp
;
2197 *pholder
= alloc_fn(old_holder
, keylen
, CP_MAX_CACHEBUFLEN
, &new_cpkp
);
2199 /* copy the new key into the entry */
2200 cpkp_set_pers_key_len(new_cpkp
, keylen
);
2201 memcpy(cpkp_pers_key(new_cpkp
), new_persistent_key
, keylen
);
2203 /* Actually record/store what AKS reported back, not the effective class stored in newclass */
2204 *newclass
= wrapped_key_out
.dp_class
;
2213 static int cpkp_unwrap(cnode_t
*cp
, cp_key_class_t key_class
, cp_key_pair_t
*cpkp
)
2216 uint8_t iv_key
[CP_IV_KEYSIZE
];
2217 cpx_t cpx
= cpkp_cpx(cpkp
);
2219 /* Structures passed between HFS and AKS */
2220 cp_cred_s access_in
;
2221 cp_wrapped_key_s wrapped_key_in
;
2222 cp_raw_key_s key_out
;
2224 cp_init_access(&access_in
, cp
);
2226 bzero(&wrapped_key_in
, sizeof(wrapped_key_in
));
2227 wrapped_key_in
.key
= cpkp_pers_key(cpkp
);
2228 wrapped_key_in
.key_len
= cpkp_max_pers_key_len(cpkp
);
2229 /* Use the persistent class when talking to AKS */
2230 wrapped_key_in
.dp_class
= key_class
;
2232 bzero(&key_out
, sizeof(key_out
));
2233 key_out
.iv_key
= iv_key
;
2234 key_out
.key
= cpx_key(cpx
);
2236 * The unwrapper should validate/set the key length for
2237 * the IV key length and the cache key length, however we need
2238 * to supply the correct buffer length so that AKS knows how
2239 * many bytes it has to work with.
2241 key_out
.iv_key_len
= CP_IV_KEYSIZE
;
2242 key_out
.key_len
= cpx_max_key_len(cpx
);
2244 error
= g_cp_wrap_func
.unwrapper(&access_in
, &wrapped_key_in
, &key_out
);
2246 if (key_out
.key_len
== 0 || key_out
.key_len
> CP_MAX_CACHEBUFLEN
) {
2247 panic ("cp_unwrap: invalid key length! (%ul)\n", key_out
.key_len
);
2250 if (key_out
.iv_key_len
!= CP_IV_KEYSIZE
)
2251 panic ("cp_unwrap: invalid iv key length! (%ul)\n", key_out
.iv_key_len
);
2253 cpx_set_key_len(cpx
, key_out
.key_len
);
2255 cpx_set_aes_iv_key(cpx
, iv_key
);
2256 cpx_set_is_sep_wrapped_key(cpx
, ISSET(key_out
.flags
, CP_RAW_KEY_WRAPPEDKEY
));
2265 cp_unwrap(__unused
struct hfsmount
*hfsmp
, struct cprotect
*entry
, struct cnode
*cp
)
2268 * PROTECTION_CLASS_F is in-use by VM swapfile; it represents a transient
2269 * key that is only good as long as the file is open. There is no
2270 * wrapped key, so there isn't anything to unwrap.
2272 if (CP_CLASS(entry
->cp_pclass
) == PROTECTION_CLASS_F
) {
2276 int error
= cpkp_unwrap(cp
, entry
->cp_pclass
, &entry
->cp_keys
);
2285 * Take a cnode that has already been initialized and establish persistent and
2286 * cache keys for it at this time. Note that at the time this is called, the
2287 * directory entry has already been created and we are holding the cnode lock
2291 int cp_generate_keys (struct hfsmount
*hfsmp
, struct cnode
*cp
, cp_key_class_t targetclass
,
2292 uint32_t keyflags
, struct cprotect
**newentry
)
2296 struct cprotect
*newcp
= NULL
;
2299 /* Target class must be an effective class only */
2300 targetclass
= CP_CLASS(targetclass
);
2302 /* Validate that it has a cprotect already */
2303 if (cp
->c_cpentry
== NULL
) {
2304 /* We can't do anything if it shouldn't be protected. */
2308 /* Asserts for the underlying cprotect */
2309 if (cp
->c_cpentry
->cp_flags
& CP_NO_XATTR
) {
2310 /* should already have an xattr by this point. */
2315 if (S_ISREG(cp
->c_mode
)) {
2316 if (!cp_needs_pers_key(cp
->c_cpentry
)) {
2322 cp_key_revision_t key_revision
= cp_initial_key_revision(hfsmp
);
2324 error
= cp_new (&targetclass
, hfsmp
, cp
, cp
->c_mode
, keyflags
, key_revision
,
2325 (cp_new_alloc_fn
)cp_entry_alloc
, (void **)&newcp
);
2328 * Key generation failed. This is not necessarily fatal
2329 * since the device could have transitioned into the lock
2330 * state before we called this.
2336 newcp
->cp_pclass
= targetclass
;
2337 newcp
->cp_key_os_version
= cp_os_version();
2338 newcp
->cp_key_revision
= key_revision
;
2341 * If we got here, then we have a new cprotect.
2342 * Attempt to write the new one out.
2344 error
= cp_setxattr (cp
, newcp
, hfsmp
, cp
->c_fileid
, XATTR_REPLACE
);
2347 /* Tear down the new cprotect; Tell MKB that it's invalid. Bail out */
2348 /* TODO: rdar://12170074 needs to be fixed before we can tell MKB */
2350 cp_entry_destroy(hfsmp
, newcp
);
2356 * If we get here then we can assert that:
2357 * 1) generated wrapped/unwrapped keys.
2358 * 2) wrote the new keys to disk.
2359 * 3) cprotect is ready to go.
2369 void cp_replace_entry (hfsmount_t
*hfsmp
, struct cnode
*cp
, struct cprotect
*newentry
)
2371 if (cp
->c_cpentry
) {
2373 cp_entry_destroy (hfsmp
, cp
->c_cpentry
);
2375 cp
->c_cpentry
= newentry
;
2376 newentry
->cp_backing_cnode
= cp
;
2385 * Given a double-pointer to a cprotect, generate keys (either in-kernel or from keystore),
2386 * allocate a cprotect, and vend it back to the caller.
2388 * Additionally, decide if keys are even needed -- directories get cprotect data structures
2389 * but they do not have keys.
2394 cp_new(cp_key_class_t
*newclass_eff
, __unused
struct hfsmount
*hfsmp
, struct cnode
*cp
,
2395 mode_t cmode
, int32_t keyflags
, cp_key_revision_t key_revision
,
2396 cp_new_alloc_fn alloc_fn
, void **pholder
)
2399 uint8_t new_key
[CP_MAX_CACHEBUFLEN
];
2400 size_t new_key_len
= CP_MAX_CACHEBUFLEN
; /* AKS tell us the proper key length, how much of this is used */
2401 uint8_t new_persistent_key
[CP_MAX_WRAPPEDKEYSIZE
];
2402 size_t new_persistent_len
= CP_MAX_WRAPPEDKEYSIZE
;
2403 uint8_t iv_key
[CP_IV_KEYSIZE
];
2404 size_t iv_key_len
= CP_IV_KEYSIZE
;
2406 cp_key_class_t key_class
= CP_CLASS(*newclass_eff
);
2408 /* Structures passed between HFS and AKS */
2409 cp_cred_s access_in
;
2410 cp_wrapped_key_s wrapped_key_out
;
2411 cp_raw_key_s key_out
;
2413 if (are_wraps_initialized
== false) {
2414 printf("hfs: cp_new: wrap/gen functions not yet set\n");
2418 /* Sanity check that it's a file or directory here */
2419 if (!(S_ISREG(cmode
)) && !(S_ISDIR(cmode
))) {
2424 * Step 1: Generate Keys if needed.
2426 * For class F files, the kernel provides the key.
2427 * PROTECTION_CLASS_F is in-use by VM swapfile; it represents a transient
2428 * key that is only good as long as the file is open. There is no
2429 * wrapped key, so there isn't anything to wrap.
2431 * For class A->D files, the key store provides the key
2433 * For Directories, we only give them a class ; no keys.
2435 if (S_ISDIR (cmode
)) {
2437 new_persistent_len
= 0;
2443 /* Must be a file */
2444 if (key_class
== PROTECTION_CLASS_F
) {
2445 /* class F files are not wrapped; they can still use the max key size */
2446 new_key_len
= CP_MAX_KEYSIZE
;
2447 read_random (&new_key
[0], new_key_len
);
2448 new_persistent_len
= 0;
2454 * The keystore is provided the file ID so that it can associate
2455 * the wrapped backup blob with this key from userspace. This
2456 * lookup occurs after successful file creation. Beyond this, the
2457 * file ID is not used. Note that there is a potential race here if
2458 * the file ID is re-used.
2460 cp_init_access(&access_in
, cp
);
2462 bzero(&key_out
, sizeof(key_out
));
2463 key_out
.key
= new_key
;
2464 key_out
.iv_key
= iv_key
;
2466 * AKS will override our key length fields, but we need to supply
2467 * the length of the buffer in those length fields so that
2468 * AKS knows hoa many bytes it has to work with.
2470 key_out
.key_len
= new_key_len
;
2471 key_out
.iv_key_len
= iv_key_len
;
2473 bzero(&wrapped_key_out
, sizeof(wrapped_key_out
));
2474 wrapped_key_out
.key
= new_persistent_key
;
2475 wrapped_key_out
.key_len
= new_persistent_len
;
2477 access_in
.key_revision
= key_revision
;
2479 error
= g_cp_wrap_func
.new_key(&access_in
,
2485 /* keybag returned failure */
2490 /* Now sanity-check the output from new_key */
2491 if (key_out
.key_len
== 0 || key_out
.key_len
> CP_MAX_CACHEBUFLEN
) {
2492 panic ("cp_new: invalid key length! (%ul) \n", key_out
.key_len
);
2495 if (key_out
.iv_key_len
!= CP_IV_KEYSIZE
) {
2496 panic ("cp_new: invalid iv key length! (%ul) \n", key_out
.iv_key_len
);
2500 * AKS is allowed to override our preferences and wrap with a
2501 * different class key for policy reasons. If we were told that
2502 * any class other than the one specified is unacceptable then error out
2503 * if that occurred. Check that the effective class returned by
2504 * AKS is the same as our effective new class
2506 if (CP_CLASS(wrapped_key_out
.dp_class
) != key_class
) {
2507 if (!ISSET(keyflags
, CP_KEYWRAP_DIFFCLASS
)) {
2509 /* TODO: When 12170074 fixed, release/invalidate the key! */
2514 *newclass_eff
= wrapped_key_out
.dp_class
;
2515 new_key_len
= key_out
.key_len
;
2516 iv_key_len
= key_out
.iv_key_len
;
2517 new_persistent_len
= wrapped_key_out
.key_len
;
2519 /* Is the key a SEP wrapped key? */
2520 if (key_out
.flags
& CP_RAW_KEY_WRAPPEDKEY
) {
2527 * Step 2: allocate cprotect and initialize it.
2530 cp_key_pair_t
*cpkp
;
2531 *pholder
= alloc_fn(NULL
, new_persistent_len
, new_key_len
, &cpkp
);
2532 if (*pholder
== NULL
) {
2536 /* Copy the cache key & IV keys into place if needed. */
2537 if (new_key_len
> 0) {
2538 cpx_t cpx
= cpkp_cpx(cpkp
);
2540 cpx_set_key_len(cpx
, new_key_len
);
2541 memcpy(cpx_key(cpx
), new_key
, new_key_len
);
2543 /* Initialize the IV key */
2544 if (key_class
!= PROTECTION_CLASS_F
)
2545 cpx_set_aes_iv_key(cpx
, iv_key
);
2547 cpx_set_is_sep_wrapped_key(cpx
, iswrapped
);
2549 if (new_persistent_len
> 0) {
2550 cpkp_set_pers_key_len(cpkp
, new_persistent_len
);
2551 memcpy(cpkp_pers_key(cpkp
), new_persistent_key
, new_persistent_len
);
2558 if ((hfsmp
->hfs_cp_verbose
) && (error
== EPERM
)) {
2559 /* Only introspect the data fork */
2560 cp_log_eperm (cp
->c_vp
, *newclass_eff
, true);
2568 /* Initialize the cp_cred_t structure passed to AKS */
2569 static void cp_init_access(cp_cred_t access
, struct cnode
*cp
)
2571 vfs_context_t context
= vfs_context_current();
2572 kauth_cred_t cred
= vfs_context_ucred(context
);
2573 proc_t proc
= vfs_context_proc(context
);
2575 bzero(access
, sizeof(*access
));
2577 /* Note: HFS uses 32-bit fileID, even though inode is a 64-bit value */
2578 access
->inode
= cp
->c_fileid
;
2579 access
->pid
= proc_pid(proc
);
2580 access
->uid
= kauth_cred_getuid(cred
);
2583 access
->key_revision
= cp
->c_cpentry
->cp_key_revision
;
2589 * Parses versions of the form 12A316, i.e. <major><minor><revision> and
2590 * returns a uint32_t in the form 0xaabbcccc where aa = <major>,
2591 * bb = <ASCII char>, cccc = <revision>.
2593 static cp_key_os_version_t
parse_os_version(void)
2595 const char *p
= osversion
;
2598 while (*p
>= '0' && *p
<= '9') {
2599 a
= a
* 10 + *p
- '0';
2611 while (*p
>= '0' && *p
<= '9') {
2612 c
= c
* 10 + *p
- '0';
2619 return (a
& 0xff) << 24 | b
<< 16 | (c
& 0xffff);
2622 cp_key_os_version_t
cp_os_version(void)
2624 static cp_key_os_version_t cp_os_version
;
2627 return cp_os_version
;
2632 cp_os_version
= parse_os_version();
2633 if (!cp_os_version
) {
2634 printf("cp_os_version: unable to parse osversion `%s'\n", osversion
);
2638 return cp_os_version
;
2642 errno_t
cp_handle_strategy(buf_t bp
)
2644 vnode_t vp
= buf_vnode(bp
);
2647 if (bufattr_rawencrypted(buf_attr(bp
))
2648 || !(cp
= cp_get_protected_cnode(vp
))
2649 || !cp
->c_cpentry
) {
2655 * For filesystem resize, we may not have access to the underlying
2656 * file's cache key for whatever reason (device may be locked).
2657 * However, we do not need it since we are going to use the
2658 * temporary HFS-wide resize key which is generated once we start
2659 * relocating file content. If this file's I/O should be done
2660 * using the resize key, it will have been supplied already, so do
2661 * not attach the file's cp blob to the buffer.
2663 if (ISSET(cp
->c_cpentry
->cp_flags
, CP_RELOCATION_INFLIGHT
))
2668 cpx_t cpx
= cpkp_cpx(&cp
->c_cpentry
->cp_keys
);
2670 if (cpx_has_key(cpx
)) {
2671 bufattr_setcpx(buf_attr(bp
), cpx
);
2677 * We rely mostly (see note below) upon the truncate lock to
2678 * protect the CP cache key from getting tossed prior to our IO
2679 * finishing here. Nearly all cluster io calls to manipulate file
2680 * payload from HFS take the truncate lock before calling into the
2681 * cluster layer to ensure the file size does not change, or that
2682 * they have exclusive right to change the EOF of the file. That
2683 * same guarantee protects us here since the code that deals with
2684 * CP lock events must now take the truncate lock before doing
2687 * If you want to change content protection structures, then the
2688 * truncate lock is not sufficient; you must take the truncate
2689 * lock and then wait for outstanding writes to complete. This is
2690 * necessary because asynchronous I/O only holds the truncate lock
2691 * whilst I/O is being queued.
2693 * One exception should be the VM swapfile IO, because HFS will
2694 * funnel the VNOP_PAGEOUT directly into a cluster_pageout call
2695 * for the swapfile code only without holding the truncate lock.
2696 * This is because individual swapfiles are maintained at
2697 * fixed-length sizes by the VM code. In non-swapfile IO we use
2698 * PAGEOUT_V2 semantics which allow us to create our own UPL and
2699 * thus take the truncate lock before calling into the cluster
2700 * layer. In that case, however, we are not concerned with the CP
2701 * blob being wiped out in the middle of the IO because there
2702 * isn't anything to toss; the VM swapfile key stays in-core as
2703 * long as the file is open.
2706 off_rsrc_t off_rsrc
= off_rsrc_make(buf_lblkno(bp
) * GetLogicalBlockSize(vp
),
2708 cp_io_params_t io_params
;
2712 * We want to take the cnode lock here and because the vnode write
2713 * count is a pseudo-lock, we need to do something to preserve
2714 * lock ordering; the cnode lock comes before the write count.
2715 * Ideally, the write count would be incremented after the
2716 * strategy routine returns, but that becomes complicated if the
2717 * strategy routine where to call buf_iodone before returning.
2718 * For now, we drop the write count here and then pick it up again
2721 if (!ISSET(buf_flags(bp
), B_READ
) && !ISSET(buf_flags(bp
), B_RAW
))
2722 vnode_writedone(vp
);
2724 hfs_lock_always(cp
, HFS_SHARED_LOCK
);
2725 cp_io_params(VTOHFS(vp
), cp
->c_cpentry
, off_rsrc
,
2726 ISSET(buf_flags(bp
), B_READ
) ? VNODE_READ
: VNODE_WRITE
,
2731 * Last chance: If this data protected I/O does not have unwrapped
2732 * keys present, then try to get them. We already know that it
2733 * should, by this point.
2735 if (!cpx_has_key(io_params
.cpx
)) {
2736 int io_op
= ( (buf_flags(bp
) & B_READ
) ? CP_READ_ACCESS
: CP_WRITE_ACCESS
);
2737 errno_t error
= cp_handle_vnop(vp
, io_op
, 0);
2740 * We have to be careful here. By this point in the I/O
2741 * path, VM or the cluster engine has prepared a buf_t
2742 * with the proper file offsets and all the rest, so
2743 * simply erroring out will result in us leaking this
2744 * particular buf_t. We need to properly decorate the
2745 * buf_t just as buf_strategy would so as to make it
2746 * appear that the I/O errored out with the particular
2749 if (!ISSET(buf_flags(bp
), B_READ
) && !ISSET(buf_flags(bp
), B_RAW
))
2750 vnode_startwrite(vp
);
2751 buf_seterror (bp
, error
);
2756 hfs_lock_always(cp
, HFS_SHARED_LOCK
);
2757 cp_io_params(VTOHFS(vp
), cp
->c_cpentry
, off_rsrc
,
2758 ISSET(buf_flags(bp
), B_READ
) ? VNODE_READ
: VNODE_WRITE
,
2763 assert(buf_count(bp
) <= io_params
.max_len
);
2764 bufattr_setcpx(buf_attr(bp
), io_params
.cpx
);
2766 if (!ISSET(buf_flags(bp
), B_READ
) && !ISSET(buf_flags(bp
), B_RAW
))
2767 vnode_startwrite(vp
);
2772 #else // !CONFIG_PROTECT
2774 #include <sys/cdefs.h>
2775 #include <sys/cprotect.h>
2776 #include <sys/errno.h>
2778 int cp_key_store_action(int action __unused
)
2783 int cp_register_wraps(cp_wrap_func_t key_store_func __unused
)
2788 size_t cpx_size(__unused
size_t key_size
)
2793 cpx_t
cpx_alloc(__unused
size_t key_size
)
2798 void cpx_free(__unused cpx_t cpx
)
2802 bool cpx_is_sep_wrapped_key(__unused
const struct cpx
*cpx
)
2807 void cpx_set_is_sep_wrapped_key(__unused
struct cpx
*cpx
, __unused
bool v
)
2811 bool cpx_use_offset_for_iv(__unused
const struct cpx
*cpx
)
2816 void cpx_set_use_offset_for_iv(__unused
struct cpx
*cpx
, __unused
bool v
)
2820 uint16_t cpx_key_len(__unused
const struct cpx
*cpx
)
2825 void cpx_set_key_len(__unused
struct cpx
*cpx
, __unused
uint16_t key_len
)
2829 void *cpx_key(__unused
const struct cpx
*cpx
)
2834 aes_encrypt_ctx
*cpx_iv_aes_ctx(__unused cpx_t cpx
)
2839 #endif /* CONFIG_PROTECT */